gdb debugging tips

Posted 2021-01-11

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

gdb debugging tips

I wrote this in reply to someone on the forum, but gonna copy paste it here so I can link more easily in the future.

dmd -debug

dmd's -debug switch enables the debug keyword inside the D code itself. This lets you bypass other rules temporarily. For example

void foo() pure {
   writeln("called foo");
}

Normally, that wouldn't compile, since writeln is not pure. But if you do

void foo() pure {
   debug writeln("called foo");
}

It is allowed. Without the -debug switch, that line is just ignored, it is not compiled. With the -debug switch, that line is allowed - and it bypasses the pure restriction.

It does NOT do anything related to running D in debuggers like gdb, it just enables code guarded by that debug keyword.

dmd -g

-g is what compiles in the information gdb uses. This info is used to print function names in stack traces, make breakpoints by file and line number, etc.

You can use -g and -debug together or independently or whatever depending on what exactly you want to do.

gdb tips

Now, some general tips on using D with gdb:

  • Segfaults should be run inside the debugger to get the stack trace. If your program did "Segmentation fault (core dumped)", you can fire up gdb after the fact on it. Check that directory for a .core file and then run gdb program that.core to inspect it.
  • Running a program in gdb may sometimes say "program received SIGUSR1" and pause.

    The commands

    handle SIGUSR1 noprint
    handle SIGUSR2 noprint

    will skip this. SIGUSR1/2 are used by the GC when doing collections so you probably don't care about it. You can put those commands i your ~/.gdbinit to run every time.

  • Running gdb --args ./yourprogram --DRT-trapExceptions=0 will break on any uncaught exception so you can inspect that stuff. Super useful if you get one of those.