Debugging with valgrind and gdb

· nat's blog

And this is pretty much exactly, why I wrote mulle-prose.sh. There are some tasks that aren't complicated, but just don't happen often enough, so that I don't have to look them up. I actually wrote the following text a few weeks ago, but could't easily find it...

With valgrind you can watch large memory ranges in gdb kinda invaluable! Also maybe read up on Debug memory errors with Valgrind and GDB.

Run tests to produce executables: mulle-sde test run --keep-exe

# Shell 1

1EXE='./test/30-multithreaded/multi-producer-multi-consumer.exe'
2valgrind --tool=memcheck --vgdb=yes --vgdb-error=0 "${EXE}"

# Shell 2

Remove old log, which otherwise gets appended to. Now start gdb not vgdb!

1rm gdb.txt
2EXE='./test/30-multithreaded/multi-producer-multi-consumer.exe'
3gdb "${EXE}"

In gdb now say:

target remote | vgdb

# Step past data structure creation

b main
c
n
n

Examine data structure and figure out addresses. In the case of multi-producer-multi-consumer.exe its:

(gdb) p fifo
$1 = { read = 0x0, write = 0x0, size = 4, allocator = 0x0, storage = 0x4aba4f0}

We want to watch "write","read" all 64 bits and "storage" which is 4 * 64 bits.

Don't use expressions to watch something as they will "go away". Figure out the address and the size and then set watchpoints:

watch (int64_t [2]) *&fifo
watch (int64_t [4]) *&*fifo->storage

# Automate watchpoints

Turn on logging, so that the watchpoint information is sent to a logfile gdb.txt. Automate the watchpoints, so we don't have to continue all the time.

set logging enabled on

commands 2
  continue
end

commands 3
  continue
end

Now run it with

c

# Automating it more

commands.txt

target remote | vgdb
b main
c
n
n
p fifo
watch -l (int64_t [2]) *&fifo
watch -l (int64_t [4]) *&*fifo->storage
set logging enabled on

I haven't figured out how to automate this :(

commands 2
  continue
end
commands 3
  continue
end
c

# Kill kill and quit

monitor v.kill
quit