I have read how gdb attaches to another running process from this link:
How does a debugger peek into another process' memory?
But what about starting a program directly with it as such:
gdb ./my_program
Does gdb fork and run my_program using it and attach to it like it's explained int he above link (i.e with ptrace on linux), or the process is entirely different?
or the process is entirely different?
No: the process is the same -- fork, parent calls PTRACE_ATTACH, child calls PTRACE_TRACEME. That last point guarantees that GDB can debug the child process from its first instruction.
There is one additional complication: GDB uses $SHELL in order to handle input / output redirection, so there is fork -> exec shell (in the child) -> exec program.
Related
I have web daemon and request that makes it fail with SIGSEGV. So i start daemon, attach with gdb, continuing, send request and getting this:
$ gdb attach -p 630066
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
How to make gdb print stacktrace before killing application? Application do not have subprocesses, just threads.
Thanks.
Your GDB session indicates that you have not attached all threads of the multithreaded process, and some other thread (one you didn't attach) ran into SIGSEGV and terminated the entire process.
Another (somewhat unlikely) possibility is that you are using a very old version of GDB, one which still has this bug in it (the bug was fixed in 2009).
When using gdb -p NNNN you need to be careful and specify correct process id. pgrep daemon-name or ps aux | grep daemon-name should give you a good idea which process to attach.
Just enter backtrace or bt right in the gdb shell after getting SIGSEGV.
To explore stack trace for each separate thread, start with info thread, then choose the thread you need, for example thread 3 and then type bt to see the stack trace for that thread.
I'm having a tough time figuring this one out; I have a program, iverilog that executes a system() call to invoke another program, ivl. I want to debug the second program, ivl in gdb, but I can't get gdb to set any breakpoints in the child process when I invoke gdb with the parent process. Here's what the programs look like:
//iverilog-main.cpp (Parent process)
int main(){
//...
system("ivl arg1 arg2");
//...
return 0;
}
.
//ivl-main.cpp (child process)
int main(){
//...
//stuff I want to debug
//...
return 0;
}
.
The gdb commands I'm running are: gdb iverilog -x cmds.gdb
# cmds.gdb
set args hello.v
set follow-fork-mode child
set breakpoint pending on
break ivl-main.cpp:main
run
Unfortunately, gdb doesn't break at ivl-main.cpp:main,it just completes without ever breaking; the output I get is:
Starting program: /usr/local/bin/iverilog hello.v
[New process 18117]
process 18117 is executing new program: /bin/dash
[Inferior 2 (process 18117) exited normally]
I'm certain ivl-main.cpp:main is being called because when I run the ivl program in gdb it successfully breaks there.
My thinking is that gdb doesn't recognize ivl-main.cpp as a source file when its running gdb iverilog, and it's not setting that breakpoint when it enters the child process which does contain ivl-main.cpp as a source file. So I think if I set the breakpoint for ivl-main.cpp when gdb enters the child process, it should work. The only way I can think of doing this is to manually break at the system() call and step into the child process, then set the breakpoint. Is there a more elegant approach that would force gdb to break whenever entering a child process?
Normally GDB only debugs one process at a time- if your program forks then you will debug the parent or the child, but not both simultaneously. By default, GDB continues debugging the parent after a fork, but you can change this behavior if you so desire with the following command:
set follow-fork-mode child
Alternately, you can tell GDB to keep both the parent and the child under its control. By default GDB only follows one process, but you can tell it to follow all child processes with this command:
set detach-on-fork off
GDB refers to each debugged process as an "inferior". When debugging multiple processes you can examine and interact each process with the "inferiors" command similar to how you would use "threads" to examine or interact with multiple threads.
See more documentation here:
https://sourceware.org/gdb/onlinedocs/gdb/Forks.html
This answer provides one way to achieve what you want.
In theory, set follow-fork-mode child should work.
In practice, the iverilog is likely itself a shell script that runs (forks) multiple commands, so at every fork you will need to decide whether you want to continue debugging the parent or the child. One wrong decision and you've lost control of the process that will eventually execute your program. This very likely explains why it didn't work for you.
I'm debugging a C++ application which creates trees of forks. Using GDB defaults, the child processes will be detached on the fork and as a result I see only one inferior shown afterwards.
I tried to attach to one of the child processes and despite it not being listed as an inferior for the other GDB process, in the new GDB session I get an error that the process is already being traced (by the first GDB session).
Is this expected behavior? What steps can I take to debug the forked process in a separate GDB session? What steps can I take to debug the problem further?
I have a program which create many threads. I can check it using following command: ps -L pid. I also know that a process loads some shared libs. I wonder if is possible to check which threads belong to a selected shared lib.
That process contains debug symbols and I can attach to them using follwoing command: sudo gdb -p pid What's next ?
Let we already attached to a process.
(gdb) info threads
Will display currently known threads. The last column in the output shows function and library for the last stack frame for each thread.
If you want to see threads start routines and the libraries they belong to, you may use:
(gdb) thread apply all bt -3
This command will show you 3 stack frames (from bottom) for each thread. If you are using pthread library then function that goes right after start_thread() is your start routine.
Without getting into to to much detail, I'm working on a program that consists of several separate processes all running on embedded QNX RTOS. They don't have a parent-child relationship, they are all spawned using spawnlp(P_NOWAIT, ...) and they all communicate with each other using the IPC mechanism provided by the OS.
When I'm debugging with GDB and I hit a breakpoint in the process I'm working in, all of my threads are paused, which is great. But is there a way to also have it pause execution of my other processes? Right now what's happening is all the other processes keep on truckin' while my process is paused and so all the IPC queues get full etc. etc.
Thanks in advance,
HF
You can associate a list of GDB commands with each breakpoint. So when you hit a breakpoint in process A, you can for example send a SIGTRAP to process B, which should drop it into the debugger:
(gdb) b main
Breakpoint 1 at 0x804834a: file testA.c, line 40.
(gdb) command
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>shell kill -s TRAP `pidof testB`
>end
(gdb)
More info at Breakpoint Command Lists