When we use gdb attach to debug a running process, we could use gdb attach pid ,if the process have two or more threads, the pid is the main thread tid.
Now I want to implement a simple debugger to debug multi-thread process, but when I use my debugger to attach a multi-thread process, only the main thread suspended.
I want to know why only use the main thread tid, the gdb can attach all thread of this process, how does gdb suspend all the threads? we assume that when we use gdb attach, all the thread have been created.
I want to know why only use the main thread tid, the gdb can attach all thread of this process, how does gdb suspend all the threads?
When you do attach PROCESS_PID gdb internally calls ptrace (PTRACE_ATTACH) for each thread. on Linux you can check it yourself with:
$ strace -e ptrace -p GDB_PROCESS_PID
Just run a program with s few threads, run gdb and before running attach PROCESS_PID run strace in another console. You must see ptrace (PTRACE_ATTACH) for each thread.
ptrace PTRACE_ATTACH sends SIGSTOP to the process which suspends the whole process i.e. all threads.
The main thread TID having the same numerical value as the process PID is a historical accident of Linux systems; it isn't the case on other Unix systems.
When gdb (or any debugger) attaches to a process using ptrace, all the threads of that process are suspended.
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 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?
If I have some multithreaded process and want to trace it with gdb using attach command, to which thread it will connect (e.g. current running or main)? I know that I can discover it with info threads but I want to know which thread it will choose by default.
For Linux, all of the threads are stopped by the ptrace command when gdb attaches.
It has been my experience that gdb defaults to the main thread for C/C++ applications. If you attach to a process and do a 'bt' it will list the stack for 'main'.
Information is available for all threads however. gdb can look at the thread(s) information in the /proc filesystem. The proc contains information about each thread in the tasks area. Details about the stack address is located in the stat file as well as the maps file. Details are also available regarding the register values for each thread.
Along the lines of your question, I've often wondered why stepping through a multithreaded application will cause gdb to jump from thread to thread. I think that gdb is still at the mercy of the kernel scheduler so that a step on a thread may lead to a different thread getting the CPU resource and a breakpoint being triggered.
On Linux, where thread ids exist in the same space as process ids, it appears you can run gdb -p tid to attach to the thread with given tid and its owning process, without knowing the pid. Because the main thread of a process has tid == pid, it makes sense that running gdb -p pid connects to the main thread.
Example code that connects gdb to the currently executing thread, e.g. for generating a pretty stack trace: https://github.com/facebook/rocksdb/pull/11150
I attached to my multithread application with gdb and after that type cont to continue execution.
Is there any way to stop execution at any time on cont gdb state and check what every thread do?
How to check state of every thread and get execution line number of each? (commands)
Here's what I do, (taken from here )
Create a little gdb script stackdumper.gdb that dumps the stack trace of all threads:
thread apply all backtrace
Then repeatedly attach gdb and run the dumper:
for i in $(seq 1 10) ; do
gdb -batch -x stackdumper.gdb ./a.out 123456 > stack.$i
sleep 10
done
where ./a.out is the binary you are interested and 123456 is the PID.
Adjust the sleep to match your sampling needs.
thread apply all bt
Or
info threads
t <threadid from above trace >
Followed by
where or bt
To get the backtrace for all of the stopped threads type the
thread apply all bt
command (the output is exactly the same that one might see in the MacOSX crash report box).
Usually the threads are stopped simultaneously in gdb.
Reference: http://www.delorie.com/gnu/docs/gdb/gdb_40.html
And here's about "all-stop" mode, which is default: http://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html
Is this any way to stop execution at any time on cont gdb state and check what every thread do
If you ask about ways to check what threads do without gdb the you can just run pstask <pid-of-your application>
Is it "pstack" because i don't think "pstask" is any command in linux, If it is please provide some more info
Is there a way to stop the inferior without using Ctrl+C (or an equivalent signal sent from another process?) I'm using a windows platform and am managing GDB from another process, so with no notion of signals, it seems that there isn't a good way to break execution of my program when it's free running without any breakpoints.
EDIT FOR CLARITY:
There are 2 processes involved here. There's process A, which is the parent of GDB. GDB is managing a process, but it's on a remote host, and we'll call that process C.
When I tell GDB to "run" it kicks off process C on the remote host and blocks either until a breakpoint is hit, process C encounters an error or a fatal signal, or GDB itself receives an interrupt signal. If working interactively, you would simply press CTRL+C at the GDB command console, which GDB interprets as a SIGINT (somehow), triggering GDB to halt process C. Since I'm actually managing GDB with process A (and not dealing with it interactively at the shell) I can't very well press Ctrl+C, and since windows has no native notion of "Signals" like you have in UNIX, I can't figure out how to interrupt GDB when it's blocking waiting for process C to interrupt or hit a breakpoint.
Did you try to take a look at the remote control protocols? for instance, EMACS uses MI to control GDB, you should check how/if they offer such a ctrl-C mechanism, and how they implement it.
EDIT: it seems to be -exec-interrupt which interrupts the execution.