Consider:
(gdb) q
A debugging session is active.
Inferior 1 [process 9018] will be killed.
Quit anyway? (y or n) y
What is a .gdbinit option to make GDB always kill the running process at a quit request?
I know that GDB can attach to already-running processes, so it would be bad to kill them at quit. But for a processes started from it, a need to confirm your actions starts to annoy at a second quit.
Turning confirmation prompts off globally disabled many other useful checks, such as the one to ask you if you really want to delete all breakpoints when you type "delete".
It would be better to disable the prompt only for the quit command. You can do that by adding this hook to your ~/.gdbinit (for current user) or /etc/gdb/gdbinit (for all users):
define hook-quit
set confirm off
end
set confirm off
See gdb doc for details
Another option is to define a new command that quits without asking for confirmation:
define qquit
set confirm off
quit
end
document qquit
Quit without asking for confirmation.
end
Now you can use qquit or just qq to exit quickly, without changing the default behaviour of quit
In conclusion this will run the program directly and don't ask for quit confirmation:
gdb -ex="set confirm off" -ex=r --args ...
Type:Ctrl + D
Before
xx#yy: ~>
(gdb)
After
(gdb) quit
Then
xx#yy: ~>
Related
I'm trying to achieve the "Semihosting" like feature by registering a set of commands associated with a specific break point, like:
print buffer[0]
cont
So the plan is having analog values dumped into the GDB client console in realtime, thus making the development process easier.
Is it possible for GDB to execute above example commands when the breakpoint on line 38 (eg.) is hit? (I will need to run different set of commands on another break point)
Each breakpoint you add in gdb has a number. You can see the numbers with i b (short for info breakpoints). Suppose you want to add commands to breakpoint number 2, just type commands 2 and press ENTER. Now, type the commands you want gdb to run when breakpoint 2 is hit (one per line). When you want to finish entering the commands, type end.
Tip: You can add the continue command before end if you want gdb to continue execution instead of stopping. That is, if you only added to breakpoint to add commands to it but you don't want execution to stop there. For instance, if you just want to print the value of some variable, or even if you want to create another breakpoint but only if some specific code path is reached first. The possibilities are endless.
If I run a program under gdb, how do I break at an arbitrary point? Pressing Ctrl+C kills the program. Ctrl+Break does nothing.
I can't enter gdb commands because my program is itself sitting in a REPL loop so anything I enter goes to my program, not to gdb.
My program uses linenoise to implement the REPL; I assume that this is hiding Ctrl+C, etc., from gdb.
Ctrl+\ results in a 001C square blob thingy in my program, rather than SIGUSR1.
Pressing Ctrl+C kills the program.
That is not the default GDB behavior.
Did you set handle SIGINT nostop pass?
You can examine current signal disposition with:
(gdb) handle SIGINT
Signal Stop Print Pass to program Description
SIGINT Yes Yes No Interrupt
Update:
My program is using linenoise for console input. I assume that it has done something to Ctrl+C
If your program is modifying terminal settings, you are going to have a very bad time debugging it from the same terminal.
For example, suppose the program sets no echo, and then hits a breakpoint. I think you would get a (gdb) prompt, but would not see any commands you are typing into GDB.
It seems that you would be much better off debugging this program from a different terminal. Use gdb -p $PID to attach to it from "outside".
I'm trying to debug a custom thread pool implementation that has rarely deadlocks. So I cannot use a debugger like gdb because I have click like 100 times "launch" debugger before having a deadlock.
Currently, I'm running the threadpool test in an infinite loop in a shell script, but that means I cannot see variables and so on. I'm trying to std::cout data, but that slow down the thread and reduce the risk of deadlocks meaning that I can wait like 1hour with my infinite before getting messages. Then I don't get the error, and I need more messages, which means waiting one more hour...
How to efficiently debug the program so that its restart over and over until it deadlocks ? (Or maybe should I open another question with all the code for some help ?)
Thank you in advance !
Bonus question : how to check everything goes fine with a std::condition_variable ? You cannot really tell which thread are asleep or if a race condition occurs on the wait condition.
There are 2 basic ways:
Automate the running of program under debugger. Using gdb program -ex 'run <args>' -ex 'quit' should run the program under debugger and then quit. If the program is still alive in one form or another (segfault, or you broke it manually) you will be asked for confirmation.
Attach the debugger after reproducing the deadlock. For example gdb can be run as gdb <program> <pid> to attach to running program - just wait for deadlock and attach then. This is especially useful when attached debugger causes timing to be changed and you can no longer repro the bug.
In this way you can just run it in loop and wait for result while you drink coffee. BTW - I find the second option easier.
If this is some kind of homework - restarting again and again with more debug will be a reasonable approach.
If somebody pays money for every hour you wait, they might prefer to invest in a software that supports replay-based debugging, that is, a software that records everything a program does, every instruction, and allows you to replay it again and again, debugging back and forth. Thus instead of adding more debug, you record a session during which a deadlock happens, and then start debugging just before the deadlock happened. You can step back and forth as often as you want, until you finally found the culprit.
The software mentioned in the link actually supports Linux and multithreading.
Mozilla rr open source replay based debugging
https://github.com/mozilla/rr
Hans mentioned replay based debugging, but there is a specific open source implementation that is worth mentioning: Mozilla rr.
First you do a record run, and then you can replay the exact same run as many times as you want, and observe it in GDB, and it preserves everything, including input / output and thread ordering.
The official website mentions:
rr's original motivation was to make debugging of intermittent failures easie
Furthermore, rr enables GDB reverse debugging commands such as reverse-next to go to the previous line, which makes it much easier to find the root cause of the problem.
Here is a minimal example of rr in action: How to go to the previous line in GDB?
You can run your test case under GDB in a loop using the command shown in https://stackoverflow.com/a/8657833/341065: gdb --eval-command=run --eval-command=quit --args ./a.out.
I have used this myself: (while gdb --eval-command=run --eval-command=quit --args ./thread_testU ; do echo . ; done).
Once it deadlocks and does not exit, you can just interrupt it by CTRL+C to enter into the debugger.
An easy quick debug to find deadlocks is to have some global variables that you modify where you want to debug, and then print it in a signal handler. You can use SIGINT (sent when you interrupt with ctrl+c) or SIGTERM (sent when you kill the program):
int dbg;
int multithreaded_function()
{
signal(SIGINT, dbg_sighandler);
...
dbg = someVar;
...
}
void dbg_sighandler(int)
{
std::cout << dbg1 << std::endl;
std::exit(EXIT_FAILURE);
}
Like that you just see the state of all your debug variables when you interrupt the program with ctrl+c.
In addition you can run it in a shell while loop:
$> while [ $? -eq 0 ]
do
./my_program
done
which will run your program forever until it fails ($? is the exit status of your program and you exit with EXIT_FAILURE in your signal handler).
It worked well for me, especially for finding out how many thread passed before and after what locks.
It is quite rustic, but you do not need any extra tool and it is fast to implement.
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.
Consider:
(gdb) q
A debugging session is active.
Inferior 1 [process 9018] will be killed.
Quit anyway? (y or n) y
What is a .gdbinit option to make GDB always kill the running process at a quit request?
I know that GDB can attach to already-running processes, so it would be bad to kill them at quit. But for a processes started from it, a need to confirm your actions starts to annoy at a second quit.
Turning confirmation prompts off globally disabled many other useful checks, such as the one to ask you if you really want to delete all breakpoints when you type "delete".
It would be better to disable the prompt only for the quit command. You can do that by adding this hook to your ~/.gdbinit (for current user) or /etc/gdb/gdbinit (for all users):
define hook-quit
set confirm off
end
set confirm off
See gdb doc for details
Another option is to define a new command that quits without asking for confirmation:
define qquit
set confirm off
quit
end
document qquit
Quit without asking for confirmation.
end
Now you can use qquit or just qq to exit quickly, without changing the default behaviour of quit
In conclusion this will run the program directly and don't ask for quit confirmation:
gdb -ex="set confirm off" -ex=r --args ...
Type:Ctrl + D
Before
xx#yy: ~>
(gdb)
After
(gdb) quit
Then
xx#yy: ~>