0

I'm exploring the difference in gdb behaviour on a executable compiled with and without -g option.

So,I have observed the following things which I don't understand:

1.I can't place breakpoint on a line in my code. Every time I try,it places in the file ../sysdeps/x86_64/start.S, line 63 Here's the image of what I see when I try to place breakpoint on line number 34 in my program

2.I can however place breakpoints using function names. So I placed breakpoint at the beginning of my main. But after that I can't go to the next line in my program. After typing 'next' the execution reaches the end of the program. Why does this happen? Is this expected behaviour?Is it because line number information is not available? Image for this case

Note: Posting links to the images since it's my first question here and I can't post images.Sorry about that.

I understand why line numbers are not visible or program name is not visible when I place the breakpoints and why 'info locals' does not display the symbols. Also,I understand that debugging information is not stored in DWARF format when I don't use -g , but shouldn't I still be able to debug my code? I don't understand why I can't traverse my code line by line or place line breakpoints.

I have checked similar questions but they don't mention the behaviors I observed. this this

My main function looks like this:

main(){
 printf("Starting to build the linked list\n");
 .
 .
 .
 printf("Printing values of the list");
}

Are these expected behaviors or am I missing something? Are there documentations about gdb behavior without -g?

mosa
  • 15
  • 7

2 Answers2

2

One of the things that -g does is to save a record of which lines and statements in your source file correspond to which (sets of) machine language instructions in the compiled program. Without that information, the debugger has no way to place a breakpoint based on source line statements, and it can't single-step by lines, either, again because it has no idea where the line/statement boundaries are.

You can still set breakpoints at the beginning of functions because these days, the symbol table (which among other things tells where in the machine code each function begins) is considered so basic that it's typically included even without -g.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • If the symbol table is included without -g ,why does do I see 'no symbol table' message when i try the command 'info locals'? – mosa Aug 24 '19 at 21:02
  • @mosa I'm not sure, and I probably shouldn't have bade the blanket statement that "the symbol table is typically included even without `-g`". Perhaps there's a basic symbol table you get no matter what, and a more detailed one (including local variables) when you use `-g`. Or perhaps I'm completely mistaken. (I'm basically speculating.) But I've noticed I typically get a basic symbol table (enough to give me backtraces) even without `-g`, and you said you could set breakpoints on functions even without `-g`, which seemed consistent with my experience. But I dunno. – Steve Summit Aug 25 '19 at 00:23
  • Thanks for clarifying. Yes,I could place breakpoints on functions and also print global variables. Probably the way local variables are dealt with will help explain this behavior. – mosa Aug 25 '19 at 09:41
2

Without -g, the debugger has no line number information, so it does not know which instructions correspond to which line of your source files. So using the next and step are equivalent to continue -- they'll just run.

What you can do is use the nexti and stepi commands (abbreviated as ni and si). These commands execute a single machine instruction and stop at the next one. Unfortunately, gdb does not print useful machine instruction info as it steps in these cases, but you can put the following in your .gdbinit file:

define sx
  si
  x /1i $pc
end
document sx
    Step one instruction and print next instruction
end
define nx
  ni
  x /1i $pc
end
document nx
    Step one instruction running through calls and print next instruction
end

These commands (nx and sx) are slightly more useful versions of ni and si -- stepping a single instruction and then disassembling the next instruction to be run.

For the breakpoint issue, you can put breakpoints at specific machine instructions with eg.
break *0x4000fed, but you need to know the specific raw addresses. You can use eg.
disassemble start to disassemble the code at a specific symbol to see the raw addresses of instructions with that function.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • thank you. How do I go about learning all the internal workings of gdb? – mosa Aug 25 '19 at 09:51
  • 1
    the `help` command is pretty good for showing how indiviual commands work, as well as listing all the commands (though there are a lot, so its hard to know where to start if you don't know any of them). The gdb texinfo manual is a pretty good place to start -- generally installed as a separate gdb-doc package and accessed via `info gdb` from the command line. – Chris Dodd Aug 25 '19 at 17:32