问题
I searched online but in vain. info thread
provides all the threads the are currently alive in the process attached with gdb. I want to know if it is possible for gdb to show a thread tree i.e. parent child relationship between the listed threads.
Why do I want to know that?: Amongst a dozen threads, one of the thread is waiting on join_all() of its child threads. If I can understand on which threads is the main thread waiting on, I can debug better.
Metadata: gdb version 7.7
回答1:
I don't think the information you want is available, so gdb doesn't have a built-in way to display it.
If it is very important I guess you have a couple of choices.
One, in your follow-up comment you mention that a thread is trying to join its children. So, as a quick-and-dirty thing you could switch to that thread, go "up", and look at the threads it is waiting on.
Or, you could use Python to write some gdb code to automate this in a way, either app-specific or by setting breakpoints at the appropriate spots (pthread_create, etc) to record the parentage information. This is somewhat harder.
回答2:
Try running this to get a good view of all the threads to see what they're doing. It may be easier than figuring out from a tree of threads:
thread apply all bt
This will generate you a backtrace of all threads and then you can visually see who is waiting on what.
回答3:
I recently wanted this info and worked out the following scheme. It's not pretty, but it prints parent/child relationships between all the threads.
After starting gdb but before running your program, paste in these gdb commands:
set pagination off
break pthread_create
commands
set $a = newthread
continue
end
break pthread_create.c:611
commands
p "parent thread"
p/x pthread_self()
p "child thread"
p/x *$a
p "created from this stack"
where
continue
end
Then run your program.
When you get a crash or you otherwise want to look at the threads, you can use "info threads" to list all the current threads, or "thread" to print info about the current thread. Then you can scroll up through all the output from the breakpoints to see parent/child relationships between threads. This also includes a stack trace of each thread creation, which is more useful than a simple tree of thread IDs.
Instead of scrolling back and looking for IDs manually, I copy the whole gdb session text into emacs and search for the matching thread ID.
The first breakpoint is the call to pthread_create. That happens in the parent thread. pthread_create()'s first argument ("newthread") is a pointer to a location where the child thread ID will be placed. When the first breakpoint is hit, we save that pointer in $a. Then we need to continue executing until the second breakpoint, at which point the target of the pointer will have been filled with the child's thread ID.
This was on ubuntu 14.04 linux. The second breakpoint (at pthread_create.c:611) might need to change if your version of that library is sufficiently different. I found that line number experimentally by doing the first breakpoint without the "commands" part, then typing "until" and "print *$a" until it got filled with the child's thread ID.
来源:https://stackoverflow.com/questions/24811802/how-do-i-find-thread-tree-using-gdb