views:

1095

answers:

2

Hi,

I am trying to debug a small operating system I have written in an university course in C++. At runtime somewhere one of my objects is getting corrupted. It seems like this happens due to accidentally writing to the wrong memory address. As I am unable to find the place where this happens from pure looking at the code, I need another way.

As this is an operating system, I cannot attach tools like valgrind to it, but I can run it in emulators (bochs/qemu) with gdb attached.

Is there a way in gdb to trace write access to a class instance or more general a specific memory range? I would like to break as soon as write access happens, so I can verify if this is valid or not.

+8  A: 

You can put a watchpoint:

watch x

This will break when x is modified. x can be any type of variable. If you have:

class A;
A x;

Then gdb will break whenever x is modified.

You can actually put a watchpoint on any expression, and gdb will break when the expression changes. Be careful with this, though, because if the expression isn't something that the underlying hardware supports, gdb will have to evaluate this after every instruction, which leads to awful performance. For example, if A above is a class with many members then gdb can watch the entire instance x, but the way it'll work is:

  • execute an instruction
  • jump to the debug breakpoint
  • check if x has changed
  • return to the program

Naturally, this is very slow. If x is an int then gdb can use a hardware breakpoint.

If you have a specific memory address you can watch it too:

watch *0x1234

This will break when the contents of [0x1234] changes.

You can also set a read breakpoint using rwatch, or awatch to set a read/write breakpoint.

Nathan Fellman
Can you watch a range of addresses? I'm in a similar situation, except I would like to watch my entire kernel stack (I think at some point I'm writing to it accidentally, causing all hell to break loose)
Mala
@Mala: You can't do this in x86 using hardware watchpoints. In fact, other than specifying the addresses explicitly, I don't know how to watch a range of addresses at all. Maybe you should ask this as a separate question.
Nathan Fellman
+3  A: 

If you know at least approximately where it happens you can also just use "display" instead of watch and manually step line by line until you see when the change happens. Watching an address using "watch" is just too painfully slow.

Zitrax
Actually, watching only an address is very fast, cause it's done by hardware. Watching anything else _can_ get very painful
Nathan Fellman