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