I have a problem with GDB. When I use "s" to step into a function called from the main function, GDB jumps to another function without showing me the function that I need.
To be clear, I use step here:
In file main.c:
short c = get(a, b);
Now get has a 36 lines code and at line 27 it calls an other function "swap" here:
In file get.s:
call _swap;
When I use step (s) with GDB on "get", it jumps all of the get function and it shows me the _swap function.
These are three different files: main.c, get.s, and *swap.c compiled in this way:
gcc -g -m32 main.c swap.c get.s -o IA-main
-m32 because get.s is IA-32 assembly. Why does it jump the "get" function and show me only "_swap"?
I work on Mac OS X v10.12.6 (Sierra), so GDB is a little annoying.
From Continuing and Stepping (emphasis mine)
step
Continue running your program until control reaches a different source line, then stop it and return control to GDB. This command is abbreviated s.
Warning: If you use the step command while control is within a function that was compiled without debugging information, execution proceeds until control reaches a function that does have debugging information. Likewise, it will not step into a function which is compiled without debugging information. To step through functions without debugging information, use the stepi command, described below.
You can use the stepi command instead:
stepi
stepi arg
si
Execute one machine instruction, then stop and return to the debugger.
It is often useful to do ‘display/i $pc’ when stepping by machine instructions. This makes GDB automatically display the next instruction to be executed, each time your program stops. See Automatic Display.
An argument is a repeat count, as in step.
Related
I am using gdb to debug boot loader code in xv6. In bootasm.S, I can use gdb to debug assembly code as expected. Then at the end of bootasm.S, we will call bootmain (line 9168, call bootmain) and the execution will go into the bootmain function of the C code bootmain.c. Since it is a C code, I wish to step over the C statements instead of assembly. I know that the step command of gdb is for this purpose, but after I input 's', I received an error message: Cannot find bounds of current function. The same error shows up no matter I input 's' before or after the call bootmain instruction. So, is it possible to step C statements in gdb when the execution switches from an assembly source to a C source like the situation described above? If it is, how to do that? Thank you.
PS1: The list command only list the main() source of the kernel.
PS2: The remote terminal ran make qemu-gdb to start the QEMU, and the local terminal ran gdb kernel to start the debug session, following steps here. I think the C source code symbols like bootmain function should be included so I should be able to step the C code in it.
Thank you again for your help!
I have built the Clang program from sources with full debugging information (the default build type for Clang IIUC). I check that debug information is available in the executable by noting that there are compile units in the module:
$ lldb /opt/bin/clang++
(lldb) script lldb.target.module['/opt/bin/clang++'].GetNumCompileUnits()
1341
I have instrumented a file in the Clang source tree, lib/Sema/SemaExpr.cpp with a printf statement in the Sema::DiagnoseAssignmentResult method (which is at line 10853 in my copy). I know this method gets called on my test file test.cc, but I can't get the debugger to stop on breakpoints for this method! I have tried setting the breakpoints two ways,
$ lldb /opt/bin/clang++
(lldb) breakpoint set -m DiagnoseAssignmentResult
Breakpoint 2: where = clang++`clang::Sema::DiagnoseAssignmentResult(clang::Sema::AssignConvertType, clang::SourceLocation, clang::QualType, clang::QualType, clang::Expr*, clang::Sema::AssignmentAction, bool*) + 87 at SemaExpr.cpp:10858, address = 0x0000000100ab9947
(lldb) process launch -- ./test.cc
<< message from my printf statement >>
... then clang++ runs to completion and exits, no breakpoint hit ...
(lldb)
I note that lldb did find the correct place in the source code, but didn't stop when it passed through the method. I also tried setting the breakpoint by specifiying the file and line number,
(lldb) breakpoint set -f SemaExpr.cpp -l 10853
Breakpoint 3: where = clang++`clang::Sema::DiagnoseAssignmentResult(clang::Sema::AssignConvertType, clang::SourceLocation, clang::QualType, clang::QualType, clang::Expr*, clang::Sema::AssignmentAction, bool*) + 87 at SemaExpr.cpp:10858, address = 0x0000000100ab9947
Again it "worked", but does not stop. Am I doing something fundamentally wrong here? How can I get the breakpoint to trigger?
You are debugging the clang driver, which is not what actually does the parsing. Instead, clang spawns off another process to do the compilation, then ld if linking is needed, etc. lldb wasn't stopping at your breakpoints because that code was actually getting run by a child process. The confusing bit here is that clang actually uses the same binary for the driver and the parser, so the breakpoints took, just not in the version of clang that was going to invoke that code.
The way to debug the compilation part of clang is first to run it like this:
$ clang++ -### <all your other arguments>
Note the weird -### argument. That tells clang not to do the compilation but to emit the command line that it will run to do the compilation. It will look something like:
/usr/bin/clang" "-cc1" ...
So that is the command line that you want to use in lldb to debug clang as a compiler rather than clang as a compiler driver...
I've never used a debugger and the time has come to give them a try. MinGW appears to come with GDB which I've been trying to use. Supposdly running gdb from the command line and typing run myprog.exe starts the debugger but when I do this I get
Starting program: C:\MinGW\bin\myprog.exe MyProg.exe
[New Thread 1828.0xd8c]
Error opening file.
[Inferior 1 (process 1828) exited with code 02]
How to proceed or what's an easier way?
In particular I'm trying to flush out undefined behavior.
Since your program terminates, you'll need to set a breakpoint to see anything. Try break main before the run line. Then you can do commands line next (next line), step (step into/outof function calls), print expression (where expression can be a variable name or a function-call or a calculation), display expression (same as print, but prints just before each prompt). At any given point you can type backtrace to get a call stack. You can even type up and down to move up the callstack, so you can print higher local variables.
Well, the easiest way would be to use an IDE, actually. You might want to give code::blocks a try - very easy to use, configures everything for you on installation (just make sure to pick a compiler - don't worry, it'll prompt you) and there, you're all set and ready to go. As it's multi-platform, it doesn't really lock you into windows either, and gives you very powerful (and, I guess more importantly, convenient) possibilities of graphical debugging.
pass the binary with gdb
gdb <binary>
then set breakpoint to main
gdb) break main
Then run your program in gdb
gdb) run
then break point hits use 'n' or 'next' to step to different lines
gdb) n
Use 's' for stepping into function and 'p' printing var value
Example :
gdb) s <fun_name>
gdb) p x
I would suggest , as a beginner start off with Visual Studio. It has a very good and easy to use debugger. Just create a break point in the line from which you want to start debugging (click on the left bar beside the line or right click and create a break point). Once your break points are set you can just simply run the program in debug mode and the execution of the program will halt in the point where the break was created.
At this point you should be able to view all valuable information about the execution of the program. You can use F10 to continue the execution step or F11 to step inside the execution tree.
The debugger as many other advanced features like break on condition , hit count etc but you can start off with it's basic functionality.
If I compiled a program like this:
gcc -o my-prog -g myprog.c
I could then debug the executable my-prog it like this:
gdb my-prog
The -g option tells gcc to generate full debugging info. Other compilers will have their own versions of this option (e.g. the MSVC cl command has the /Zi option).
Since you're having issues running the gdb on your program, it might be worth checking if it was compiled with debugging info in the first place. The debugging info is usually generated in the same location as where you compiled your program.
As the title suggests, is there any way to read the machine code instructions as/after they have been executed? For example, if I had an arbitrary block of C code and I wanted to know what instructions were compiled and executed when that block was entered then would there be a way to do that? Thank you in advance for any pointers on the subject.
Edit: Some motivation as to what I'm trying to do: I want to have a program that roughly figures out how it has been compiled or what instructions it is currently running without actually needing to know how the machine code is made. I.e. I want to use the hard work that some compiler previously did in compiling a program so that I can copy and later use the machine code being executed.
Little-known fact: GDB has a curses interface built in.
Use gdbtui or gdb,Ctrl+X,Ctrl+A to enter, then Ctrl+X,2 to start showing assembly and source together. The current instruction is highlighted, and you can navigate using the arrow keys.
Almost every debugger can do this.
For gdb, a useful trick to remember is: display/i $pc
Do that once, and then set a breakpoint on a function, the step through the function with stepi and nexti.
The instruction at the PC will be automatically displayed each time.
Ross-Harveys-MacBook-Pro:so ross$ cat > deb.c
int main(void) { return (long)main + 0x123; }
Ross-Harveys-MacBook-Pro:so ross$ cc -O deb.c
Ross-Harveys-MacBook-Pro:so ross$ gdb -q a.out
Reading symbols for shared libraries .. done
(gdb) break main
Breakpoint 1 at 0x100000f30
(gdb) display/i $pc
(gdb) r
Starting program: /Users/ross/so/a.out
Reading symbols for shared libraries +. done
Breakpoint 1, 0x0000000100000f30 in main ()
1: x/i $pc 0x100000f30 <main+4>: lea -0xb(%rip),%rax # 0x100000f2c <main>
(gdb) stepi
0x0000000100000f37 in main ()
1: x/i $pc 0x100000f37 <main+11>: add $0x123,%eax
(gdb) stepi
0x0000000100000f3c in main ()
1: x/i $pc 0x100000f3c <main+16>: leaveq
I can't tell if you're asking about doing this at runtime, or if you want to see a textfile containing the assembly code of your compiled C code.
If the former, just use a debugger (use disassemble in gdb with gcc, or the integrated debugger in Microsoft Visual Studio).
If the latter, you'll have to look up the specific commands for your compiler. With Visual Studio, for example, just use the flag /FAs; this will output the assembly code with your source code. For gcc:
gcc -c -g -Wa,-a,-ad foo.c > foo.lst
Most debuggers have options to view the disassembly of the code you are executing.
Ex: in gdb use the disassemble command.
If you want to know what the execution path was for a particular function, perhaps some processors have such a feature, but generally no. Now what you can do is run in an emulator and modify the emulator to print out the addresses of the fetches or reads or whatever.
If this is just a disassembly question using the gcc/binutils tools objdump -D filename > out.list and not bother executing or using a debugger
How do I make gdb print functions of interest as they are called, indented according to how deep in the stack they are?
I want to be able to say something like (made up):
(gdb) trace Foo* Bar* printf
And have gdb print all functions which begin with Foo or Bar, as they are called. Kind of like gnu cflow, except using the debugging symbols and only printing functions which actually get called, not all possible call flows.
Tools which won't help include cachegrind, callgrind and oprofile, which order the results by which functions were called most often. I need the order of calling preserved.
The wildcarding (or equivalent) is essential, as there are a lot of Foo and Bar funcs. Although I would settle for recording absolutely every function. Or, perhaps telling gdb to record all functions in a particular library.
Some GDB wizard must have a script for this common job!
In your case I would turn to the define command in gdb, which allows you to define a function, which can take up to 10 arguments.
You can pass in the names of functions to "trace" as arguments to the function you define, or record them all in the function itself. I'd do something like the following
define functiontrace
if $arg0
break $arg0
commands
where
continue
end
end
if $arg1
...
Arguments to a user-defined function in gdb are referenced as $arg0-$arg9. Alternatively, you could just record every function you wanted to trace in the function, instead of using $arg0-9.
Note: this will not indent as to depth in the stack trace, but will print the stack trace every time the function is called. I find this approach more useful than strace etc... because it will log any function you want, system, library, local, or otherwise.
There's rbreak cmd accepting regular expression for setting breakpoints. You can use:
(gdb) rbreak Foo.*
(gdb) rbreak Bar.*
(gdb) break printf
See this for details on breakpoints.
Then use commands to print every function as it's called. E.g. let α = the number of the last breakpoint (you can check it with i br if you missed), then do:
(gdb) commands 1-α
Type commands for breakpoint(s) 1-α, one per line.
End with a line saying just "end".
>silent
>bt 1
>c
>end
(gdb)
Some elaboration: silent suppresses unnecessary informational messages, bt 1 prints the last frame of backtrace (i.e. it's the current function), c is a shortcut for continue, to continue execution, and end is just the delimiter of command list.
NB: if you trace library functions, you may want to wait for lib to get loaded. E.g. set a break to main or whatever function, run app until that point, and only then set breakpoints you wanted.
Use the right tool for the job ;)
How to print the next N executed lines automatically in GDB?
Did you see litb's excellent anwser to a similar post here ?
He uses readelf to get interesting symbols, gdb commands to get the trace, and awk to glue all that.
Basically what you have to change is to modify his gdb command script to remove the 1 depth from backtrace to see the stack and filter specific functions, and reformat the output with an awk/python/(...) script to present it as a tree. (I admit I'm too lazy to do it now...)
You may call gdb in batch mode (using -x option), break where you need and ask for backtrace (bt), then you filter the result using grep or egrep.
Indents are more difficult, however bt output is ordered so you have current function at the top of the trace and main at very bottom.
So you create file with commands:
br <function name where to break>
run
bt
kill
quit
then run gdb <program> -x<command file>
Filter strings that starts with #<digit> - you get stack trace.