Difficulties using valgrind/vgdb and gdb in nix-shells

Maybe this helps someone like me who sometimes runs valgrind from nix-shell and wants to debug as well.

Problem: debugging via vgdb does not work

Start valgrind with vgdb in one terminal (“valgrind terminal”):

> nix-shell -p valgrind
$ valgrind --quiet --vgdb-error=0 --vgdb=full sleep 1
==2799760== (action at startup) vgdb me ...
==2799760==
==2799760== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==2799760==   /path/to/gdb sleep
==2799760== and then give GDB the following command
==2799760==   target remote | /nix/store/z3k1ih7g5njqnbhns0anx8mw6zqjs1z3-valgrind-3.26.0/libexec/valgrind/../../bin/vgdb --pid=2799760
==2799760== --pid is optional if only one valgrind process is running
==2799760==

Start gdb in another terminal (“gdb terminal”) and follow valgrind’s hint:

$ gdb -q sleep
Reading symbols from sleep...
(gdb) target remote | /nix/store/z3k1ih7g5njqnbhns0anx8mw6zqjs1z3-valgrind-3.26.0/libexec/valgrind/../../bin/vgdb --pid=2799760
Remote debugging using | /nix/store/z3k1ih7g5njqnbhns0anx8mw6zqjs1z3-valgrind-3.26.0/libexec/valgrind/../../bin/vgdb --pid=2799760
❌️ Remote communication error.  Target disconnected: error while reading: Connection reset by peer.
(gdb)

Solution

vgdb started from the gdb terminal doesn’t find the communication FIFOs to valgrind. It puts them in TMPDIR (or one of those env vars) and it differs in the nix-shell(s):

$ valgrind --help | grep prefix=
    --vgdb-prefix=<prefix>    prefix for vgdb FIFOs [/tmp/nix-shell-2602004-3207382787/vgdb-pipe]

Pass the option to vgdb in the gdb terminal:

(gdb) target remote | /nix/store/z3k1ih7g5njqnbhns0anx8mw6zqjs1z3-valgrind-3.26.0/libexec/valgrind/../../bin/vgdb --pid=2799760 --vgdb-prefix=/tmp/nix-shell-2602004-3207382787/vgdb-pipe
Remote debugging using | /nix/store/z3k1ih7g5njqnbhns0anx8mw6zqjs1z3-valgrind-3.26.0/libexec/valgrind/../../bin/vgdb --pid=2799760 --vgdb-prefix=/tmp/nix-shell-2602004-3207382787/vgdb-pipe
relaying data between gdb and process 2799760
⚠️ warning: remote target does not support file transfer, attempting to access files from local filesystem.
...
0x00000000043c5d40 in _start ()
   from /nix/store/57iz36553175g3178pvxjij8z5rcsd4n-glibc-2.42-61/lib/ld-linux-x86-64.so.2
(gdb) c
Continuing.
Loaded /nix/store/z3k1ih7g5njqnbhns0anx8mw6zqjs1z3-valgrind-3.26.0/libexec/valgrind/valgrind-monitor.py
Type "help valgrind" for more info.
[Inferior 1 (Remote target) exited normally]