User01
User01

Reputation: 41

implementing step over, dwarf

Im working on a source level debugger. The debug info available in elf format. How could be 'step over' implemented? The problem is at 'Point1', anyway I can wait for the next source line (reading it from the .debug_line table).

Thanks

if (a == 1)
 x = 1; //Point1
else if (a == 2)
 x = 1;

z = 1;

Upvotes: 4

Views: 923

Answers (1)

Jim Blandy
Jim Blandy

Reputation: 1546

I'm not sure I understand the question entirely, but I can tell you how GDB implements its step command.

Once control has entered a particular compilation unit, GDB reads that CU's debugging information; in particular, it reads the CU's portion of the .debug_line section and builds a table that maps instruction addresses to source code positions.

When the step begins, GDB looks up the source location for the current PC. Then it steps by machine instruction, looking up the source location of the new PC each time, until the source location changes. When the source location changes, the step is complete.

It also computes the frame ID—the base address of the stack frame, and the start address of the function—after each step, and checks if that has changed. If it has, that means that we've stepped into or returned from a recursive call, and the step is complete.

To see why it's necessary to check the frame ID as well as the source location, consider stepping through a call to the following function:

int fact(n) { if (n > 0) { return n * fact(n-1); } else return 1; }

Since this function is defined entirely on the same source line, stepping by instruction until the source line changes would step you through all the recursive calls without stopping. However, when we enter a new call to fact, the stack frame base address will have changed, indicating that we should stop. This gives us the following behavior:

fact (n=10) at recurse.c:4
(gdb) step
fact (n=9) at recurse.c:4
(gdb) step
fact (n=8) at recurse.c:4

GDB's next command combines this general behavior with appropriate logic for recognizing function calls and letting them return to completion. As before, one must use frame IDs in deciding when calls have truly returned to the original frame; and there are other complications.

It's worth thinking a bit about how to treat inlined instances of functions (which DWARF does describe). But that's a bit much for this question.

Not to discourage experimentation, but if I were beginning a debugger project, I would want to look at Apple's work-in-progress debugger, lldb, which is open source.

Upvotes: 6

Related Questions