Which debugger setup do you guys use?

Hey. I’ve tried using debuggers with Zig with no luck. First I tried using gdb, which completely doesn’t work. Then I tried using lldb with the llvm backend. It works partially, but you miss out useful features like being able to print out slices. Then I tried using the lldb-zig fork of lldb. It definitely works better, but it still has weird drawbacks like not being able to print out const variables (I don’t know if it used to work properly, but at least debugging my 0.16.0 program it doesn’t work).

What debugger do you guys use that works properly with the latest Zig release?

None (windows user). Frustration.
std.debug.print()

2 Likes
std.debug.print

This is a habit that I will never break, it is just too ingrained into my being. I have dap plugin installed into my neovim, and went through all the trouble getting it too work with Zig a year or so ago, and then never use it. Good 'ol print statements rule the day.

5 Likes

I just use VSCode with the CodeLLDB extension (plus the Zig Language extension). It has the downsides you describe, e.g. slices are only shown as ‘type-erased’ pointer/size structs but it allows to set breakpoints and step through the code (and most importantly for me: step from Zig into C code and back).

I wonder if the type being erased from slices is a bug in the debug information generation though, I would think it should be trivial to give the pointer in the slice the proper type in the debug info.

but it still has weird drawbacks like not being able to print out const variables

This sort of makes sense since consts are ‘disolved’ at build time in Zig. I think making them inspectible with a debugger would require to assign a memory location to consts.

1 Like

When I worked with C I also used to be a print debugger, until I finally sat down and learnt how to use gdb. So much faster and easier!

lldb-zig manages to properly print out slices, so it’s def. possible!

This sort of makes sense since consts are ‘disolved’ at build time in Zig

What do you mean by this?

1 Like

I am not unfamiliar with debuggers, have even used them extensively in other languages, but not so much with Zig, C, etc.
I rarely even output an artifact for my Zig projects, and haven’t even explored how to hook into the test runner with a debugger.

Zig’s consts are fundamentally different than C consts. In C, const is only a hint to the compiler that this ‘item’ should not be modified, but the const item is still a regular variable which exists at runtime and has a location in memory (either on the heap or on the stack).

Zig’s consts are more like a typed #define x 123, the compiler directly replaces the const with its value in all the places it is used, and the const itself doesn’t exist as as a single ‘named item’ at runtime anymore (that’s what I mean that the ‘const is dissolved’).

PS: in C a const can also be ‘dissolved’, but only with optimization enabled and when the compiler can be sure that the const isn’t used outside its compilation unit (e.g. it would need to be a static const .... This is one reason why source-level-debugging optimized code in C and C++ can be very confusing.

3 Likes

I see, thanks for the insight

I use nnd (Linux) for my debugging purposes, it has some quirks with zig specifically (one being that you have to specify the type to print string slices in the debugger) but generally it works much better for me than lldb. That and printf debugging as others have mentioned.

4 Likes

I use gdb and it works for me. obviously some issues around printing structs, but i can set breakpoints and step through. Still have to use the LLVM backend to get it to work, but that’s because the llvm backend generates dwarf version 4 not dwarf version 5.

2 Likes

On Windows I’ve had pretty good experiences with RAD Debugger, but on Mac/Linux I’ve only used VSCode + CodeLLDB.

I came here expecting to be the only one using std.debug.print but it feels good not being the only one

2 Likes

Have you tried using the LLDB fork? I think that one shows slices correctly

Kind of did it at comp time:

But it’s kind of a manual job to put it in a global variable on the side. Not great, but better then nothing.

edit: I think floooh meant something else the compiler would do. My solution is memory location based, but you have to list the types you want the const from.

I used Raddebugger on windows in the past with zig.

1 Like

Agree that it’s a tough habit to break. There’s a place for gdb, etc., but I find it powerful that incremental compilation can enable a quick debug.print insert and, without explicitly re-compiling or restarting the run, you can re-trigger and see the trace… for some debug needs, the combo of incremental compilation and debug.print is hard to deny.

1 Like

I am using lldb with llvm backend through Zed editor. I am not using forked lldb but I do get nice printout for slices and even MultiArrayList. I just set it up with the pretty printers zig makes available here.

I am on zig 0.15.2 and all of this works great but it seems something changed in the newer zig versions and it stopped working. I opened a ticket about it since it seems that script needs some changes to make it work again.

1 Like