I am using GDB to understand a C++ program. I put a break in the middle of the running which turns to be something like:
break main.cpp:500
and I would like to see which functions have been called before. I tried "backtrace" but it shows only info about main, as previous calls to previous functions have already finished.
My question is how can I get (with GDB or another method) the info about which functions have been called before this point, even if the call has been returned.
Thanks
A gdb script might be a solution for your problem.
Create a script that puts break point to each possibly called function.
At break prints the stack with 'bt' and continue the execution.
You should put an other break point to main.cpp:500 to quit from debugging.
b 'main.cpp::500'
commands 1
detach
quit
end
break 'A::f1()'
break 'A::f2()'
while true
continue
bt
end
You can start the script like this:
gdb --command ./gdbscript.gdb fpmanager
If you have too much possibly called function you can grep the code to find all.
Related
I know how to create/modify a breakpoint to stop only on a specific thread using breakpoint modify <breakpoint-id> -T <thread-name>, but can I do it the other way around, preventing the breakpoint to stop on a specific thread?
I have a log thread that use the same function I'm trying to debug on other threads and it's annoying to have to let it continue every time it hits.
You can do this sort of thing using the lldb Python API and Python breakpoint callbacks. The callback returns a "should stop" value, i.e. if it returns True, you stop at the breakpoint, and False you continue.
So for instance:
(lldb) breakpoint command add -s python -o 'return frame.thread.name != "MyThread"'
is what you wanted. Note, in this example, I didn't provide a breakpoint ID. In lldb that means "act on the last set breakpoint". But you can also supply the breakpoint ID if the one you want to add the command to doesn't happen to be the last breakpoint you set. And if you want to add it to multiple breakpoints, you can specify a breakpoint ID list.
There's more on the API's and the callback format here:
https://lldb.llvm.org/python_api.html
https://lldb.llvm.org/use/python-reference.html#running-a-python-script-when-a-breakpoint-gets-hit
Note, however, that breakpoints with should-stop callbacks will force a stop every time the breakpoint is hit. lldb auto-continues pretty quickly, so for many applications this isn't a problem. But just getting from the stop over to the debugger and back is not cheap, so if your breakpoint is in a work loop and getting hit hundreds of thousands of times a second, this is going to slow down the run. If that ends up being a problem and you control your source code, tricks like the one Eljay suggested in the comments can be really handy.
Is there a way to attach a print statement to the call of a function? I would like to debug a x64 program with nested loops and logic and it would be faster to see the sequence of function calls by printing them as they occur, rather than setting breakpoints.
Can this be done with a post hook in gdb or a different technique?
Is there a way to attach a print statement to the call of a function?
Yes: attach a breakpoint to every function you want to trace, and attach commands to each of these breakpoints:
(gdb) break foo
(gdb) commands $bpnum
continue
end
Now every time foo is called, GDB will print the usual "Breakpoint N ..." message, and then continue.
Obviously you could print additional info (argument values, call stack, thread-id, etc.).
You will probably want to set height 0 to disable pagination. You will also probably want to log this to a file (see set logging file, set logging on, etc.)
I'm using gdb to solve a binary bomb as part of a class. Every time we set the bomb off we lose points. I already have a break point on the function that explodes the bomb, but have accidentally stepped past it a couple times already and exploded the bomb. Is there a way to make gdb exit at a specific point rather than just break?
You can attach commands to breakpoints. After you set breakpoint, e.g. #1, do this:
commands 1
quit
end
I'm trying to debug proftpd in order to understand better this exploit http://www.phrack.org/issues.html?issue=67&id=7. The vulnerable section is in mod_sql.c, I have tried to breakpoint the sql_prepare_where function (that is where the heap overflow is done) and then call the USER ... and PASS ... command but it is never triggered.
To find out why I have breakpoints all the hundreds line of mod_sql.c and then launch the program (with full debugging option), some breakpoints are triggered (sql_setuserinfo, set_sqlauthenticate, get_auth_entry...) but only at the very beginning of the launching process, then when the program goes in it main loop nothing else breakpoint related happens (while the log of proftpd mentions that the USER and PASS commands are dispatched to mod_sql.c)..
Would anyone know what I'm missing?
[ It's possible I am missing something essential of GDB, I am learning on the roll :) ]
Server programs often use a "separate program for each connection" method, where after successful accept, the parent forks a child to handle current connection, and goes back to accepting more connections.
I don't know for sure, but if proftpd used that model, it would explain exactly the symptoms you've described.
You can ask GDB to debug the child instead of the parent, by using (gdb) set follow-fork-mode child.
When debugging an unfamiliar program with gdb, the program often unexpectedly exits after executing next. When that happens I'll typically set a break point, re-run the program and execute step instead of next to trace what's happening. However, sometimes it is difficult to know where to set the break point. Is there a technique set the break automatically? Something like:
define hook-next
break
end
define hookpost-next
# delete the previous break if the program is still running
end
I think you could do it with a combination of hook-next, convenience variables, and a breakpoint on exit. Something like:
define hook-next
set $saved_pc = $pc
end
break exit
commands
break *$saved_pc
end
You may prefer "tbreak" there.