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
Last revision Both sides next revision
soc:2008:stefanha:journal:week3 [2008/06/11 11:19]
stefanha
soc:2008:stefanha:journal:week3 [2008/06/13 09:11]
stefanha
Line 57: Line 57:
  
 I am going to write tests and polish the code tonight with a commit coming tomorrow. I am going to write tests and polish the code tonight with a commit coming tomorrow.
 +
 +==== Thu Jun 12 ====
 +Git commits:
 +  * [[http://​git.etherboot.org/?​p=people/​stefanha/​gpxe.git;​a=commit;​h=5a1db5bd3c8310f9797add6e75383b00dc9d2d15|[Drivers-via-rhine] read/write instead of in/out]]
 +  * [[http://​git.etherboot.org/?​p=people/​stefanha/​gpxe.git;​a=commit;​h=bbcd45d10048c95e009c5b5c69c5d93cd74f3cc6|[GDB] Add watch and rwatch hardware watchpoints]]
 +
 +Michael Decker formats commits nicely in [[:​soc:​2008:​mdeck:​journal:​week3|his journal]] so I'm copying him :-).
 +
 +**Watchpoints now work in GDB**. ​ The ''​watch <​memory-location>''​ command sets a write watchpoint. ​ The watchpoint fires when the given memory location is written. ​ Similarly, the ''​awatch <​memory-location>''​ command sets a read/write watchpoint and fires when the memory location is read or written.
 +
 +Watchpoints are orthogonal to breakpoints,​ they give you another dimension of trapping events during debugging. ​ They are an excellent tool for tracking down variable accesses or memory corruption. ​ Without watchpoints,​ you'd have to add ''​printf()''​ calls or periodically break into the debugger to check if memory has changed. ​ And that's no fun.
 +
 +Why are ''​watch''​ and ''​awatch''​ supported but not ''​rwatch''? ​ The answer has to do with how watchpoints are implemented,​ so let's take a look...
 +
 +The x86 has hardware debugging support that you can access via the debug registers, ''​dr0''​ through ''​dr7''​. ​ The control register, ''​dr7'',​ lets you enable up to four hardware breakpoints. ​ Hardware breakpoints can be normal execution breakpoints,​ write watchpoints,​ read/write watchpoints,​ or port I/O watchpoints. ​ The x86 does not support pure read watchpoints.
 +
 +The GDB stub watchpoint code is almost capable of doing normal execution breakpoints. ​ However, there is some extra behavior necessary involving setting the Resume Flag (RF) to avoid repeatedly breaking on the same instruction without advancing EIP.  I don't see a need for normal execution breakpoints versus GDB's software breakpoints.
 +
 +Implementing the debug register code required me to rewire the way the GDB stub receives control on interrupt. ​ Previously the interrupt handler would call the portable GDB stub directly. ​ Now it calls an architecture-specific handler, which calls the portable GDB stub code after it has configured the debug registers.
 +
 +**Used watchpoints to find and fix a bug in the Via Rhine driver**. ​ Last week I tracked down a memory corruption where 0x00000000 and 0x00000004 were being written to.  At the time I wished I had watchpoints so I added them to the TODO list.
 +
 +The first thing I did once watchpoints were implemented is ''​awatch _entry'',​ where ''​_entry''​ is the symbol at 0x00000000. ​ This will detect NULL pointer reads/​writes. ​ To my surprise the watchpoint immediately fired!
 +
 +The backtrace showed that ''​rhine_poll()''​ was trying to read from 0x00000000. ​ It turned out that the driver was using ''​readb()''/''​writeb()''​ in a few places whereas it should be using ''​inb()''/''​outb()''​. ​ The ''​readb()''/''​writeb()''​ functions do memory I/O while the ''​inb()''/''​outb()''​ functions do port I/O.
 +
 +Implementing watchpoints has paid off ;-)!
 +
 +==== Fri Jun 13 ====
 +Git commits:
 +  * [[http://​git.etherboot.org/?​p=people/​stefanha/​gpxe.git;​a=commit;​h=8ec13694a44779156d679af99a104aeb3bbfdb53|[GDB] Zero-extend 16-bit segment registers]]
 +  * [[http://​git.etherboot.org/?​p=people/​stefanha/​gpxe.git;​a=commit;​h=03d22bf5e31348e3f3ede48500c981761f367651|[GDB] UDP clean up and add netdev refcnt]]
 +
 +**Segment registers sometimes contained junk values**. ​ The test suite reported that the ''​DS''​ segment register had the wrong value when running on real hardware. ​ Most of my past development and testing has been in QEMU.
 +
 +Upon closer inspection the lower 16 bits of ''​DS''​ were correct. ​ On older processors, the upper 16 bits are undefined whereas they are guaranteed to be zero on newer processors. ​ gPXE runs correctly since only the lower 16 bits of segment selectors are used by the CPU.
 +
 +Although it is technically okay for the upper 16 bits to be undefined, I think it is nicer if we zero-extend segment registers when reporting their values to GDB.  This makes it easier to write test cases and is less confusing for users.
 +
 +**Weekly meeting with mdc and mcb30**. ​ Things are looking good for cleaning up and merging the second round of GDB stub work:
 +  * Remote debugging over UDP
 +  * Watchpoints
 +  * Atomic read/write for device memory
 +  * Continue on detach/kill from GDB
 +
 +Making the merge happen is my immediate goal.  An interesting opportunity for another iteration of development is 16-bit real mode debugging. ​ If GDB can hold up to the pressures of real mode, then I will implement stub support.
  
 Next steps: Next steps:
-  * Implement hardware watchpoint support using debug registers+  * Choose and document a simple way to manually call into the debugger
-  * NULL pointer bug guard using watchpoint support. +  * Improve flow control so that GDB does not print warnings
-  * Polish UDP code+  * Update [[:​dev:​gdbstub|GDB stub page]] and screencast when UDP code is merged into mainline.  See [[http://​grub.enbug.org/​DebuggingWithGDB|GRUB GDB wiki page]] for inspiration. 
-  * Update [[:​dev:​gdbstub|GDB stub page]] and screencast when UDP code is merged into mainline.+  * See if GDB supports 16-bit code, and try out real-mode debugging.

QR Code
QR Code soc:2008:stefanha:journal:week3 (generated for current page)