Debug¶
When an application is build, it often has to be debugged. This section describes the peculiarities of debugging.
Debugger¶
The debugger architecture is depicted below:
The debugger class is the main piece of the debugger. This is created for a specific architecture and is given a driver to communicate with the target hardware.
-
class
ppci.binutils.dbg.
Debugger
(arch, driver)¶ Main interface to the debugger. Give it a target architecture for which it must debug and driver plugin to connect to hardware.
-
clear_breakpoint
(filename, row)¶ Remove a breakpoint
-
read_mem
(address, size)¶ Read binary data from memory location
-
run
()¶ Run the program
-
set_breakpoint
(filename, row)¶ Set a breakpoint
-
step
()¶ Single step the debugged program
-
stop
()¶ Interrupt the currently running program
-
write_mem
(address, data)¶ Write binary data to memory location
-
One of the classes that uses the debugger is the debug command line interface.
-
class
ppci.binutils.dbg.cli.
DebugCli
(debugger, showsource=False)¶ Implement a console-based debugger interface.
-
do_clrbrk
(arg)¶ Clear a breakpoint. Specify the location by “filename, row” for example: main.c, 5
-
do_disasm
(_)¶ Print disassembly around current location
-
do_info
(_)¶ Show some info about the debugger
-
do_nstep
(count)¶ Single instruction step the debugger
-
do_p
(arg)¶ Print a variable
-
do_print
(arg)¶ Print a variable
-
do_q
(_)¶ Quit the debugger
-
do_quit
(_)¶ Quit the debugger
-
do_read
(arg)¶ Read data from memory: read address,length
-
do_readregs
(_)¶ Read registers
-
do_restart
(_)¶ Restart the running program
-
do_run
(_)¶ Continue the debugger
-
do_s
(_)¶ Single step the debugger
-
do_setbrk
(arg)¶ Set a breakpoint: setbrk filename, row
-
do_setreg
(arg)¶ Set registervalue
-
do_sl
(line)¶ step one line
-
do_step
(_)¶ Single step the debugger
-
do_stepi
(_)¶ Single instruction step the debugger
-
do_stepl
(line)¶ step one line
-
do_stop
(_)¶ Stop the running program
-
do_write
(arg)¶ Write data to memory: write address,hexdata
-
do_writeregs
(_)¶ Write registers
-
postcmd
(stop, line)¶ Hook method executed just after a command dispatch is finished.
-
precmd
(line)¶ Hook method executed just before the command line is interpreted, but after the input prompt is generated and issued.
-
To connect to your favorite hardware, subclass the DebugDriver class.
-
class
ppci.binutils.dbg.
DebugDriver
¶ Degug driver interface.
Inherit this class to expose a target interface. This class implements primitives for a given hardware target.
-
get_registers
(registers)¶ Get the values for a range of registers
-
The following class can be used to connect to a gdb server:
-
class
ppci.binutils.dbg.gdb.client.
GdbDebugDriver
(arch, transport, pcresval=0, swbrkpt=False)¶ Implement debugging via the GDB remote interface.
GDB servers can communicate via the RSP protocol.
Helpfull resources:
- http://www.embecosm.com/appnotes/ean4/
- embecosm-howto-rsp-server-ean4-issue-2.html
Tried to make this class about the protocol itself, not about the sending and receiving of bytes. The protocol must be able to work using sockets and threads, serial port and threads and asyncio sockets.
-
clear_breakpoint
(address: int)¶ Clear a breakpoint
-
connect
()¶ Connect to the target
-
disconnect
()¶ Disconnect the client
-
get_fp
()¶ read the frame pointer
-
get_pc
()¶ read the PC of the device
-
get_registers
(registers)¶ Get the values for a range of registers
-
nstep
(count)¶ Single step count times
-
read_mem
(address: int, size: int)¶ Read memory from address
-
restart
()¶ restart the device
-
run
()¶ start the device
-
set_breakpoint
(address: int)¶ Set a breakpoint
-
set_pc
(value)¶ set the PC of the device
-
step
()¶ Single step the device
-
write_mem
(address: int, data)¶ Write memory
Debug info file formats¶
Debug information is of a complex nature. Various file formats exist to store this information. This section gives a short overview of the different formats.
Dwarf format¶
How a linked list is stored in dwarf format.
struct ll {
int a;
struct ll *next;
};
<1><57>: Abbrev Number: 3 (DW_TAG_base_type)
<58> DW_AT_byte_size : 4
<59> DW_AT_encoding : 5 (signed)
<5a> DW_AT_name : int
<1><5e>: Abbrev Number: 2 (DW_TAG_base_type)
<5f> DW_AT_byte_size : 8
<60> DW_AT_encoding : 5 (signed)
<61> DW_AT_name : (indirect string, offset: 0x65): long int
<1><65>: Abbrev Number: 2 (DW_TAG_base_type)
<66> DW_AT_byte_size : 8
<67> DW_AT_encoding : 7 (unsigned)
<68> DW_AT_name : (indirect string, offset: 0xf6): sizetype
<1><6c>: Abbrev Number: 2 (DW_TAG_base_type)
<6d> DW_AT_byte_size : 1
<6e> DW_AT_encoding : 6 (signed char)
<6f> DW_AT_name : (indirect string, offset: 0x109): char
<1><73>: Abbrev Number: 4 (DW_TAG_structure_type)
<74> DW_AT_name : ll
<77> DW_AT_byte_size : 16
<78> DW_AT_decl_file : 1
<79> DW_AT_decl_line : 4
<7a> DW_AT_sibling : <0x95>
<2><7e>: Abbrev Number: 5 (DW_TAG_member)
<7f> DW_AT_name : a
<81> DW_AT_decl_file : 1
<82> DW_AT_decl_line : 5
<83> DW_AT_type : <0x57>
<87> DW_AT_data_member_location: 0
<2><88>: Abbrev Number: 6 (DW_TAG_member)
<89> DW_AT_name : (indirect string, offset: 0xf1): next
<8d> DW_AT_decl_file : 1
<8e> DW_AT_decl_line : 6
<8f> DW_AT_type : <0x95>
<93> DW_AT_data_member_location: 8
<2><94>: Abbrev Number: 0
<1><95>: Abbrev Number: 7 (DW_TAG_pointer_type)
<96> DW_AT_byte_size : 8
<97> DW_AT_type : <0x73>