Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
dev:gdbstub [2008/07/03 03:13]
stefanha
dev:gdbstub [2010/03/28 21:27] (current)
stefanha
Line 2: Line 2:
  
 ===== Overview ===== ===== Overview =====
-You can use the [[http://​www.gnu.org/​software/​gdb/​|GNU Project Debugger (GDB)]] to debug gPXE.  You either need two computers or virtualization software (e.g. [[http://bellard.org/qemu/​|QEMU]]). ​ One host runs gPXE while the other runs GDB.+You can use the [[http://​www.gnu.org/​software/​gdb/​|GNU Project Debugger (GDB)]] to debug gPXE.  You either need two computers or virtualization software (e.g. [[http://qemu.org/​|QEMU]]). ​ One host runs gPXE while the other runs GDB.
  
 gPXE supports debugging via serial port or over the network. ​ For serial, you need a null modem serial cable. ​ For network, you need the machine to be connected to a network with UDP port 43770 traffic allowed. gPXE supports debugging via serial port or over the network. ​ For serial, you need a null modem serial cable. ​ For network, you need the machine to be connected to a network with UDP port 43770 traffic allowed.
- 
-===== Limitations ===== 
-Debugging works for 32-bit protected mode.  There is no support for 16-bit real-mode. 
- 
-Debugging can safely be used after ''​initialise()''​ and ''​startup()''​ have been called in ''​main()''​. ​ If you need to use it during ''​initialise()''​ or ''​startup()'',​ take special care and modify the code if necessary (e.g. by hardcoding calls to initialize it beforehand). 
- 
-When debugging over the network, gPXE will drop network packets while you are in the debugger. ​ This means you should use serial debugging if you need to minimize side-effects on gPXE.  You may also try using a dedicated NIC for debugging so that traffic to the primary NIC is not dropped while you are in the debugger. ​ Note that traffic may still be dropped if you stay in the debugger so long that the receive buffers fill up (i.e. gPXE is not running while you are in the debugger). 
  
 ===== Building with GDB enabled ===== ===== Building with GDB enabled =====
Line 30: Line 23:
  
 This file overrides ''​src/​config.h''​ but is not under version control. ​ Therefore you will never accidentally commit a patch that enables GDB debugging. This file overrides ''​src/​config.h''​ but is not under version control. ​ Therefore you will never accidentally commit a patch that enables GDB debugging.
 +Sometimes you also need to remove/​define ''​GDBSERIAL''​ in ''​config/​general.h''​ to get serial debugging to work.
 +<​code>#​define GDBSERIAL ​              /* Remote GDB debugging over serial */
 +</​code>​
  
 Now build gPXE: Now build gPXE:
Line 67: Line 63:
 </​code>​ </​code>​
  
-Next you should set up the serial port in GDB if you are debugging via serial. ​ The ''​set remotebaud N''​ command is used to set the serial port baud rate to ''​N''​. ​ See [[http://​sourceware.org/​gdb/​current/​onlinedocs/​gdb_18.html#SEC173|Remote Configuration]] in the GDB Manual.+The ''​.tmp''​ file must correspond to your gPXE image. ​ For example, ''​gpxe.dsk''​ -> ''​gpxe.dsk.tmp'',​ ''​gpxe.pxe''​ -> ''​gpxe.pxe.tmp'',​ and ''​gpxe.usb''​ -> ''​gpxe.hd.tmp''​. 
 + 
 +Next you should set up the serial port in GDB if you are debugging via serial. ​ The ''​set remotebaud N''​ command is used to set the serial port baud rate to ''​N''​. ​ See [[http://​sourceware.org/​gdb/​current/​onlinedocs/​gdb/​Remote-Configuration.html#Remote-Configuration|Remote Configuration]] in the GDB Manual.
  
 Now connect to gPXE, which is already waiting since we entered the ''​gdbstub''​ command in the gPXE shell: Now connect to gPXE, which is already waiting since we entered the ''​gdbstub''​ command in the gPXE shell:
Line 75: Line 73:
                                     # host 192.168.1.2                                     # host 192.168.1.2
 target remote 192.168.1.2:​43770 ​    # if you are forwarding over TCP target remote 192.168.1.2:​43770 ​    # if you are forwarding over TCP
-                                    # port 1234 using QEMU -serial+                                    # using QEMU -serial
 </​code>​ </​code>​
  
Line 84: Line 82:
 <​code>​ <​code>​
 $ qemu -serial tcp::​43770,​server bin/​gpxe.usb $ qemu -serial tcp::​43770,​server bin/​gpxe.usb
 +</​code>​
 +
 +==== Breaking into the debugger programmatically ====
 +You can break into the debugger without using the gPXE shell. ​ The following breaks into the debugger for serial debugging:
 +<​code>​
 +#include <​gpxe/​gdbserial.h>​
 +#include <​gpxe/​gdbstub.h>​
 +[...]
 +gdbstub_start ( gdbserial_configure() );
 +</​code>​
 +
 +Here is the same thing for network debugging:
 +<​code>​
 +#include <​gpxe/​gdbudp.h>​
 +#include <​gpxe/​gdbstub.h>​
 +[...]
 +struct sockaddr_in sa = {
 +    /* FILL IN LISTEN ADDR/PORT OR ZERO FOR DEFAULTS */
 +};
 +gdbstub_start ( gdbudp_configure ( "​net0",​ &sa ) );
 +</​code>​
 +
 +===== Limitations =====
 +Interrupt (''​CTRL + C''​) in GDB does not work.  Implementing this is not possible since gPXE does not use interrupts. ​ This means that you cannot hit ''​CTRL + C''​ if gPXE is in an infinite loop.
 +
 +Debugging works for 32-bit protected mode.  There is no support for 16-bit real-mode.
 +
 +Debugging can safely be used after ''​initialise()''​ and ''​startup()''​ have been called in ''​main()''​. ​ If you need to use it during ''​initialise()''​ or ''​startup()'',​ take special care and modify the code if necessary (e.g. by hardcoding calls to initialize the GDB stub before the thing you are debugging).
 +
 +Backtraces are sometimes wrong. ​ I believe this is because the optimization settings gPXE is built with confuse GDB.
 +
 +When debugging over the network, gPXE will drop network packets while you are in the debugger. ​ This means you should use serial debugging if you need to minimize side-effects on gPXE.  You may also try using a dedicated NIC for debugging so that traffic to the primary NIC is not dropped while you are in the debugger. ​ Note that traffic may still be dropped if you stay in the debugger so long that the receive buffers fill up (i.e. gPXE is not running while you are in the debugger).
 +
 +===== GDB usage ====
 +  * **Breakpoint** (''​b''​) marks code where execution should stop and break into the debugger. ​ To break on an instruction'​s virtual memory address, use ''​b *ADDR''​.
 +<​code>​
 +(gdb) b http_rx_response
 +Breakpoint 1 at 0x25de: file net/​tcp/​http.c,​ line 157.
 +</​code>​
 +
 +  * **Continue** (''​c''​) resumes execution until the next breakpoint.
 +<​code>​
 +(gdb) c
 +Continuing.
 +
 +Breakpoint 1, http_rx_response (http=0x595e4,​ response=0x594b4 "​HTTP/​1.0 200 OK") at net/​tcp/​http.c:​157
 +157     ​static int http_rx_response ( struct http_request *http, char *response ) {
 +(gdb)
 +</​code>​
 +
 +  * **Step** (''​s''​),​ **next** (''​n''​),​ **finish** (''​fin''​),​ and **step instruction** (''​si''​) resume execution over a limited region of code.  Step executes until the next line of source code, it steps inside function calls. ​ Next executes until the next line of source code in the function, thereby stepping over function calls. ​ Finish executes the remainder of the current function. ​ Step instruction executes the current machine instruction.
 +
 +  * **Backtrace** (''​bt''​) shows the call stack. ​ Some stack frames may not be detected correctly by GDB due to the compiler optimisations used when building gPXE.
 +<​code>​
 +(gdb) bt
 +#0  http_rx_response (http=0x595e4,​ response=0x594b4 "​HTTP/​1.0 200 OK") at net/​tcp/​http.c:​157
 +#1  0x0000282a in http_socket_deliver_iob (socket=<​value optimized out>, iobuf=0x5a3ac,​ meta=<​value optimized out>)
 +    at net/​tcp/​http.c:​363
 +#2  0x00034118 in xfer_deliver_iob_meta (xfer=<​value optimized out>, iobuf=0x5a3ac,​ meta=0xa4aa0) at core/​xfer.c:​143
 +#3  0x00035247 in tcp_rx (iobuf=0x5a3ac,​ st_src=0xbe470,​ st_dest=<​value optimized out>, pshdr_csum=<​value optimized out>)
 +    at net/​tcp.c:​768
 +#4  0x00002510 in tcpip_rx (iobuf=0x5a3ac,​ tcpip_proto=<​value optimized out>, st_src=0xbe470,​ st_dest=0xbe450,​
 +    pshdr_csum=<​value optimized out>) at net/​tcpip.c:​54
 +#5  0x000be470 in ?? ()
 +</​code>​
 +
 +  * **Local variables** (''​info locals''​) can be displayed though their values may be unavailable due to compiler optimizations.
 +<​code>​
 +(gdb) info locals
 +spc = <value optimized out>
 +rc = <value optimized out>
 +</​code>​
 +
 +  * **CPU registers** (''​i r''​) shows many but not all of the registers.
 +
 +  * **Print** (''​p''​) shows the value of program variables and arbitrary expressions in C-like syntax (see [[http://​sourceware.org/​gdb/​current/​onlinedocs/​gdb/​Data.html|GDB Manual]]).
 +<​code>​
 +(gdb) p response ​                   ​
 +$1 = 0x594b4 "​HTTP/​1.0 200 OK" ​     ​
 +(gdb) p *http                       
 +$2 = {refcnt = {refcnt = 2, free = 0x28e8 <​http_free>​},​ xfer = {intf = {dest = 0x595c8, refcnt = 0x595e4}, op = 0x42e20},
 +  uri = 0x59554, socket = {intf = {dest = 0x59434, refcnt = 0x595e4}, op = 0x42e38}, process = {list = {next = 0x59608,
 +      prev = 0x59608}, step = 0x286b <​http_step>,​ refcnt = 0x595e4}, response = 0, content_length = 0, rx_len = 0,
 +  rx_state = HTTP_RX_RESPONSE,​ linebuf = {data = 0x594b4 "​HTTP/​1.0 200 OK", len = 15, ready = 1}}
 </​code>​ </​code>​
  
 ===== GDB documentation ===== ===== GDB documentation =====
-  * [[http://​sourceware.org/​gdb/​current/​onlinedocs/​gdb_toc.html|Debugging with GDB (official manual)]]+  * [[http://​sourceware.org/​gdb/​current/​onlinedocs/​gdb/index.html|Debugging with GDB (official manual)]]
   * [[http://​darkdust.net/​files/​GDB%20Cheat%20Sheet.pdf|A cheatsheet]],​ note that there are several others [[http://​google.com/​search?​q=gdb+cheat+sheet|available]].   * [[http://​darkdust.net/​files/​GDB%20Cheat%20Sheet.pdf|A cheatsheet]],​ note that there are several others [[http://​google.com/​search?​q=gdb+cheat+sheet|available]].
  
-===== Getting help ===== +
-You can email the [[https://​lists.sourceforge.net/​lists/​listinfo/​etherboot-developers|Etherboot-Developers]] list or ask on the [[http://​www.etherboot.org/​wiki/​contact|IRC channel]].+

QR Code
QR Code dev:gdbstub (generated for current page)