debugging - z88dk/z88dk GitHub Wiki

Debugging tools

Debugging information can be generated by the toolchain by adding the -debug option, with these options:

  • sdcc .cdb files are generated
  • sccz80 generates .cdb information encoded into the .map file

z88dk-ticks supports parsing the encoded cdb information and provides limited debugging information (PC to address file translation). The generated information contains information on variable types, offsets etc

z88dk-ticks supports C (and assembler) line by line debugging, local variable inspection, stacktrace generation and comprehensive break and watchpoint implementation for assembler code.

The +test target supports the z88dk-ticks "hardware", to compile with debugging information:

zcc +test -debug [files]

The debugger can then be invoked with:

z88dk-ticks -x a.map -debug a.bin

Once the debugger has launched, the "help" command can be used to discover commands.

The core debugging functionality of z88dk-ticks is also available with z88dk-gdb which permits connection of the debugger to emulators or physical hardware that has implemented the gdbserver interface.

To enable source level debugging in an emulator that does not support the gdbserver interface, an emulator needs to:

  1. Parse plain .cdb files (as generated by zsdcc) to obtain variable information
  2. Parse the .cdb information contained with the .map file (generated by sccz80) to obtain variable information
  3. Parse the .map file to obtain symbol address, section information (generated by z80asm)
  4. Parse the .map file to extract source code line information (__C_LINE, __ASM_LINE symbols) (generated by z80asm, sccz80)

Debug With Visual Studio Code or CLion

See z88dk-gdb-ide-test example

Profiling

When built with -debug option, z88-ticks/z88dk-gdb can do instrumental profiling to measure time it takes for each individual function. Execute profiler start, then resume session, break it after some time, do profiler stop to inspect the performancse.

    $0038    (ASMDISP_SENDTO_CALLEE+41)> profiler start
Profiler enabled.

    $0038    (ASMDISP_SENDTO_CALLEE+41)> c
^CRequesting a break...
l_debug_push_frame:
                    pop     bc                              ;[cc52] c1

    $cc52    (l_debug_push_frame+0)> profiler stop
Profiling results:
----------------------------------
    Time     Share    Function
----------------------------------
 4134142       27%    update_game_state
 1617394       10%    client_map_render
 1053286        7%    update_object
 1047621        7%    client_map_update
  926913        6%    update_game_input
  855393        5%    update_object_boundaries
  754259        5%    check_is_block_blocking
  707894        4%    update_move_controls
  568581        3%    client_map_get_block
  562230        3%    client_map_redraw_chunks
  539196        3%    client_map_redraw_objects
  408572        2%    client_map_get
  305714        2%    proto_client_process
  241743        1%    recv_process
  229390        1%    process
  177202        1%    find_cached_chunk
  139233        0%    proto_req_object_callback
  128713        0%    client_message_object
  105020        0%    client_map_render_chunk
   89943        0%    client_message_sync
   79010        0%    memory_switch_cached_chunk
   78701        0%    zxgui_scene_iteration
   37521        0%    allocate_cached_chunk
   20181        0%    client_message_unsync
   15171        0%    proto_req_new_request
   13561        0%    proto_req_recv
    8853        0%    my_player_send_updated_coords
    8598        0%    get_uint8_property
    6510        0%    proto_object_read
    6481        0%    find_property
    4987        0%    free_cached_chunk
    4582        0%    client_new_message
    4123        0%    client_message_complete
----------------------------------

    $cc52    (l_debug_push_frame+0)>