Technical Skills & Knowledge Base
Zig Patterns
Error Handling
Always propagate errors or handle them explicitly.
zig
// GOOD
fn doSomething() !void {
try someFunction();
}
// BAD
fn doSomething() void {
someFunction() catch {};
}
Memory Management
Use GeneralPurposeAllocator for debug builds to catch leaks.
zig
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
GDB MI3 Interactions
The Parse Loop
The parser must handle asynchronous out-of-band records.
zig
// Conceptual loop
while (reader.streamUntilDelimiter(&buf, '\n', null)) |line| {
if (line[0] == '*') {
handleAsyncRecord(line);
} else if (line[0] == '^') {
handleResultRecord(line);
}
}
Essential MI Commands
- •
-exec-run: Start execution. - •
-exec-continue: Resume. - •
-exec-next: Next line (step over). - •
-exec-step: Step into. - •
-stack-list-locals --simple-values: Get locals. - •
-data-evaluate-expression "var_name": Inspect variable.
Common Pitfalls
- •PTY Buffering: GDB buffers output differently on PTYs. Use pipes for MI communication to ensure immediate flushing.
- •Signal Handling: GDB traps SIGINT. Sending SIGINT to the GDB process might kill it if not handled correctly. Use
-exec-interrupt. - •Version Mismatch: GDB MI syntax changes slightly between versions. We target GDB 12+.
Verification
To verify zdebug logic without a full UI:
- •Compile a simple C program with
-g. - •Run
zdebugpointing to that binary. - •Issue
launchcommand. - •Check that
zdebugreports the correct stopped state.