Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracing write access to class instance/memory range in gdb

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.

like image 798
raimue Avatar asked Feb 17 '09 19:02

raimue


2 Answers

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.

like image 86
Nathan Fellman Avatar answered Sep 17 '22 22:09

Nathan Fellman


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.

like image 21
Zitrax Avatar answered Sep 19 '22 22:09

Zitrax