Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do debuggers keep track of the mapping between C code and assembly instructions?

I was wondering how debuggers are able to step line by line through the source code.

Once the source code is compiled and I run the program, how does a debugger know the correspondence between the machine-level instructions and the higher-level statements?

For example, if I set a break-point on one line in my source file, how does it know which machine-level instruction to stop at?

like image 990
sudoer123 Avatar asked May 14 '19 18:05

sudoer123


People also ask

What is debugger in assembly language?

The debugger automatically displays the contents of memory locations and registers as they are accessed and displays the address of the program counter. This display makes assembly debugging a valuable tool that you can use together with source debugging.

What do debuggers do?

A debugger is a software tool that can help the software development process by identifying coding errors at various stages of the operating system or application development. Some debuggers will analyze a test run to see what lines of code were not executed.

How do debuggers attach?

The user tells the debugger which process to attach to, either by name or by process ID. If it is a name then the debugger will look up the process ID, and initiate the debug session via a system call; under Windows this would be DebugActiveProcess.

How do you step through code in Visual Studio?

Begin code stepping by selecting F10 or F11. Doing so allows you to quickly find the entry point of your app. You can then continue to press step commands to navigate through the code. Run to a specific location or function, for example, by setting a breakpoint and starting your app.


2 Answers

Look at asm output from gcc -g -S and you'll see .line debug-info directives and so on for the block of asm corresponding to the C source line.

(With optimization enabled the same line can map to multiple non-contiguous instructions, so it gets much trickier, but compilers still try to be useful and map most instructions to some source line even if they're really the result of optimization and doing an operation that doesn't appear in the source...).

https://godbolt.org/ uses the same debug info as debuggers do, but uses it for color highlighting to match source lines with asm.


When an assembler assembles these .line directives, it creates debug info in the .o object file, which is eventually linked into an executable or library. Or split into a separate debug-symbols file. Or stripped.

It's this debug-info that debuggers read.

(Debug info also includes info about which named C variables are stored where, and what their types are. For locals, the locations are relative to the stack frame for the function that contains them.)

like image 93
Peter Cordes Avatar answered Oct 13 '22 02:10

Peter Cordes


The compiler & linker can produce so called debug symbols that contains this information. The debug information contains the source file/line to address mapping, the addresses of global variables and beginning addresses of all the functions and their local variable offsets on the stack. In the case of gcc, the -g compiler option does this. The debug symbol information can be embedded in the executable program as typically is the case with gcc or in separate symbol files (.pdb files with msvc).

like image 3
Sami Sallinen Avatar answered Oct 13 '22 02:10

Sami Sallinen