To debug a C program using gdb effectively it is required to compile it first using the command:
gcc -g programName.c
otherwise on using simply
gcc programName.c
and running we are unable to provide gdb the Source Code i.e.programName.c
resulting in an error message –
dl-debug.c: No such file or directory.
on demand for command like list in gdb.
Please Explain the Cause, Why it is like this.
3
A debugger needs:
- to refer to variable and function names, not their addresses (e.g.
i
not0xdeadbeef
andmain()
not0x4B1D
). - to associate the address of machine code with a line in the source code.
To this purpose the compiler builds (-g
) a (augmented) symbol table (it may be embedded into the program or stored as a separate file). Sometimes other ancillary information are generated.
There are different formats to store these information (stabs, coff, dwarf…).
Contrarily to popular beliefs, many compilers (GCC for sure) write some symbols to an object file even in release mode (with the -O3 switch).
That’s why even with a release binary, you can do:
$ gcc -O3 programName.c
$ gdb a.out
[...]
Reading symbols from a.out...(no debugging symbols found)...done.
Of course this isn’t enough for a good debugging experience.
Symbols can be removed from the binary using the strip command:
$ strip -s a.out
$ nm a.out
nm: a.out: no symbols
and now:
$ gdb a.out
[...]
(gdb) b main
Function "main" not defined.
Also consider that there is an interaction between code optimization and debugging:
- some variables you declared may not exist at all;
- the flow of control may briefly move where you did not expect it;
- some statements may not be executed because they compute constant results or their values were already at hand
- some statements may execute in different places because they were moved out of loops
- …
So, with many compilers, you cannot turn on both optimization and debugging (GCC has the -Og switch for debugging optimized code).
Further details:
- Preparing An Executable For Debugging
- Options for Debugging Your Program