This question already has answers here:
Getting a backtrace of other thread
(3 answers)
Closed 6 years ago.
I am looking to understand what is the state of a specific thread in my software, doing it from another thread.
Specifically I'd like to know if it's I/O stuck.
I was thinking of doing it by getting the backtrace(unless someone has another idea?), since I know what function it's supposed to be stuck on..
but I can't figure out how to get the backtrace of that specific thread, without calling the SEGFAULT handler... but gdb is able to do it(I doubt he creates SEGFAULTS..)
Can anyone help? any idea?
[Edit] all 3 answers refer to gdb, I KNOW I can do it from gdb, I wanted to know how to do it from a software(even linking to gdb libs somehow would be an answer, but how ? )
I know what function it's supposed to be stuck on.. but I can't figure
out how to get the backtrace of that specific thread
You can get backtraces of all threads and try to find function which is supposed to be stuck on in backtraces output. Here is how to get all backtraces in gdb:
(gdb) thread apply all bt
(gdb) info threads [will list all the threads and also indicate the thread you are currently backtracing on]
(gdb) thread apply all bt [will show backtrace of all threads so that you can see which thread is stuck on the function you are interested in before switching to that thread]
(gdb) thread #threadno [will switch the backtrace to the specific thread you are interested in and a bt will show its backtrace.]
Ref http://www.delorie.com/gnu/docs/gdb/gdb_25.html
Since you know which function you think you are getting stuck on, you could set a break point at the begining of that function. GDB allows you to attach a series of commands to a break point that are automatically executed when the breakpoint is hit, allowing you to print the backtrace for the thread that was executing when the breakpoint was hit.
(gdb) break filename:line
(gdb) commands
Type commands for breakpoint(s) 1, one per line
End with a line saying just "end"
>info threads
>bt
>continue
>end
The above will give you the list of threads, with the * by the active thread for the breakpoint, followed by the backtrace.
Related
By control transfer, I mean, after the tracee executing a function and return, which signal is generated so that GDB can wait*() on it and seize control again? It is not SIGTRAP though many people claim that ...
after the tracee executing a function and return, which signal is generated so that GDB can wait*() on it and seize control again?
The tracee is stopped, and control is transferred back to GDB, only when one of "interesting" events happens.
The interesting events are:
A breakpoint fires,
The tracee encounters a signal (e.g. SIGSEGV or SIGFPE as a result of performing invalid memory access or invalid floating-point operation),
The tracee disappears altogether (such as getting SIGKILLed by an outside program),
[There might be other "interesting" events, but I can't think of anything else right now.]
Now, a technically correct answer to "what signal does GDB use ..." is: none at all. The control isn't transferred, unless one of above events happen.
Perhaps your question is: how does control get back to GDB after executing something like finish command (which steps out of the current function)?
The answer to that is: GDB sets a temporary breakpoint on the instruction immediately after the CALL instruction that got us into the current function.
Finally, what causes the kernel to stop tracee and make waitpid in GDB to return upon execution of the breakpoint instruction?
On x86, GDB uses the INT3 (opcode 0xCC) instruction to set breakpoints (there is an alternate mechanism using debug registers, but it is limited to 4 simultaneous breakpoints, and usually reserved for hardware watchpoints instead). When the tracee executes INT3 instruction, SIGTRAP is indeed the signal that the kernel generates (i.e. other answers you've found are correct).
Without knowing what led you to believe it isn't SIGTRAP, it's hard to guess how you convinced yourself that it isn't.
Update:
I try to manually send a SIGTRAP signal to the tracee, trying to causing a spuriously wake-up of GDB, but fail.
Fail in what way?
What I expect you observe is that GDB stops with Program received signal SIGTRAP .... That's because GDB knows where it has placed breakpoints.
When GDB receives SIGTRAP and the tracee instruction pointer matches one of its breakpoints, then GDB "knows" that is's the breakpoint that has fired, and acts accordingly.
But when GDB receives SIGTRAP and the tracee IP doesn't match any of the breakpoints, then GDB treats it as any other signal: prints a message and waits for you to tell it what to do next.
"GDB sets a temporary breakpoint ... that means GDB has to modify tracee's code area, which may be read-only. So, how does GDB cope with that?
You are correct: GDB needs to modify (typically non-writable) .text section to insert any breakpoint using INT3 method. Fortunately, that is one of the "superpowers" granted to it by the kernel via ptrace(POKE_TEXT, ...).
P.S. It's a fun exercise to white a program that checksums code bytes of one of its own functions. You can then perform the checksum before and after placing a breakpoint on the "to be checksummed" function, and observe that the checksum differs when a breakpoint is present.
P.P.S. If you are curious about what GDB is doing, setting maintenance debug inferior will provide a lot of clues.
What I want is to get stacktrace of all threads for running process using c/c++.
The different ways which I know to get stacktrace :
we have backtrace() api but problem with this is that it only gives stacktrace of current thread. Does any one know how to associate it with each running thread?
Second way I tried is using pstack command. pstack takes input as pid of running process shows all stack of all threads. But problem with this is that it is not a C/C++ api so we can't use it in our code. (When I study) pstack is a shell file which in turn used gdb's bt command.
Does anyone know different ways which will help me to get stacktrace of all threads for running process?
Maybe you can use ptrace. Attach to all your threads (except for the thread that prints the stacktrace), and you can get register values with PTRACE_GETREGS. Then you can do stack unwinding (maybe you will need information stored in the .elf file to do this reliably). Note, that you have to take special care, if a thread is just creating/destroying its stack frame. And you may need debug information from the elf to do this reliably (you'd surely need that if your code compiled with omitted frame pointers).
Not an easy task to do this by hand, but surely can be done.
When debugging a C++ program emit a SIGSEGV with gdb,it is possible to handle the signal and asked to nostop.
How gdb handles this kind of scenario ??
Have searched gdb source code and couldn't find a starting point.
You cannot automatically ignore SIGSEGV. I also wouldn't recommend doing that anyway. Although you can make gdb ignore the signal and not pass it to the program, the kernel will attempt to re-run the offending instruction once the signal handler returns and results in an infinite loop. See this answer for more information.
One way to work around it is to the skip the instruction or change register values so that it does not segfault. The link shows an example of setting a register. You can also use the jump command to skip over an instruction.
is possible to handle the signal and asked to nostop.
It's unclear whether you want GDB to handle the signal, or the program itself.
If the latter, gdb handle SIGSEGV nostop noprint pass will do exactly that.
This is actually something the OS does. On Windows, if a program has a debugger attached and an exception is thrown, Windows will ask the debugger if it wants to handle it. If/when it declines, it passes it to the program. If the program doesn't handle it, Windows passes it to the debugger again.
Is there an equivalent command in GDB to that of WinDbg's !process 0 7?
I want to extract all the threads in a dump file along with their backtraces in GDB. info threads doesn't output the stack traces. So, is there a command that does?
Generally, the backtrace is used to get the stack of the current thread, but if there is a necessity to get the stack trace of all the threads, use the following command.
thread apply all bt
Is there a command that does?
thread apply all where
When debugging with several threads, it is also useful to switch to a particular thread number and get the backtrace for that thread only.
From the GNU GDB threads documentation
For debugging purposes, GDB associates its own thread number--a small integer assigned in thread-creation order--with each thread in your program.
Usage:
info threads
Then identify the thread that you want to look at.
thread <thread_id>
Finally, use backtrace for just that thread:
bt
If your process is running:
pstack $pid
While using GDB to debug a program I have been having issues with the program stopping while in debug mode. When I do a backtrace, I find that it's deep within a proprietary third party library call stack and I am looking to find out why exactly the program has stopped. I am still just a GDB beginner so I still unsure of how to do this. Looking at the backtrace I noticed that "__cxa_throw () from /usr/lib64/libstdc++.so.6" so I am presuming that an exception of some sort was thrown but I would like to know how to get more information about it, if possible.
Try using the backtrace command which will show how your program got in the state it is. Here you can find more details.
How do I find out why gdb has stopped
GDB usually tells you right away, e.g.
Program received signal SIGABRT, Aborted.
0x00007ffff7750425 in __GI_raise (sig=<optimized out>)
The program stopped because it received a signal.
I find that it's deep within a proprietary third party library call stack and I am looking to find out why exactly the program has stopped.
It has stopped exactly for the reason GDB told you about.
Looking at the backtrace I noticed that __cxa_throw() from /usr/lib64/libstdc++.so.6 so I am presuming that an exception of some sort was thrown but I would like to know how to get more information about it.
Presence of __cxa_throw does indicate that an exception has been thrown (and presence of std::terminate() indicates that it was an uncaught exception).
Without debug info for the third-party library, your choices of finding the cause are limited:
You can read the documentation for this library and double-check that you have not violated any preconditions that it requires
You can disassemble the routine that called __cxa_throw and figure out exactly why that routine was called.