My OS is RHEL 7, and I run a simple Go program:
package main
import (
"time"
)
func main() {
time.Sleep(1000 * time.Second)
}
During its running, I check the thread count of process:
# cat /proc/13858/status | grep Thread
Threads: 5
While using the pstack command shipped on RHEL, it only prints one thread's stack:
# pstack 13858
Thread 1 (process 13858):
#0 runtime.futex () at /usr/local/go/src/runtime/sys_linux_amd64.s:307
#1 0x0000000000422580 in runtime.futexsleep (addr=0x4c7af8 <runtime.timers+24>, val=0, ns=999999997446) at /usr/local/go/src/runtime/os1_linux.go:57
#2 0x000000000040b07b in runtime.notetsleep_internal (n=0x4c7af8 <runtime.timers+24>, ns=999999997446, ~r2=255) at /usr/local/go/src/runtime/lock_futex.go:174
#3 0x000000000040b1e6 in runtime.notetsleepg (n=0x4c7af8 <runtime.timers+24>, ns=999999997446, ~r2=false) at /usr/local/go/src/runtime/lock_futex.go:206
#4 0x000000000043e5de in runtime.timerproc () at /usr/local/go/src/runtime/time.go:209
#5 0x0000000000451001 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1998
#6 0x0000000000000000 in ?? ()
Why does pstack only print one thread's content?
P.S.: The pstack script is here:
#!/bin/sh
if test $# -ne 1; then
echo "Usage: `basename $0 .sh` <process-id>" 1>&2
exit 1
fi
if test ! -r /proc/$1; then
echo "Process $1 not found." 1>&2
exit 1
fi
# GDB doesn't allow "thread apply all bt" when the process isn't
# threaded; need to peek at the process to determine if that or the
# simpler "bt" should be used.
backtrace="bt"
if test -d /proc/$1/task ; then
# Newer kernel; has a task/ directory.
if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then
backtrace="thread apply all bt"
fi
elif test -f /proc/$1/maps ; then
# Older kernel; go by it loading libpthread.
if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then
backtrace="thread apply all bt"
fi
fi
GDB=${GDB:-/usr/bin/gdb}
# Run GDB, strip out unwanted noise.
# --readnever is no longer used since .gdb_index is now in use.
$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <<EOF 2>&1 |
set width 0
set height 0
set pagination no
$backtrace
EOF
/bin/sed -n \
-e 's/^\((gdb) \)*//' \
-e '/^#/p' \
-e '/^Thread/p'
pstack uses gdb. This is a quote from golang doc (https://golang.org/doc/gdb):
GDB does not understand Go programs well. The stack management,
threading, and runtime contain aspects that differ enough from the
execution model GDB expects that they can confuse the debugger, even
when the program is compiled with gccgo. As a consequence, although
GDB can be useful in some situations, it is not a reliable debugger
for Go programs, particularly heavily concurrent ones.
4 out of 5 threads that you see in /proc are created even before you program enters main. I assume that golang runtime creates them.
Why does pstack only print one thread's content?
Judging from output of strace for gdb I see that gdb actually tries to attach to them but after something goes wrong and gdb does not try to inspect these threads. These are syscalls that gdb issued for these runtime threads but due to unknown reason decided stopped investigating them immediately:
5072 ptrace(PTRACE_ATTACH, 5023, 0, 0) = 0
5072 --- SIGCHLD (Child exited) # 0 (0) ---
5072 rt_sigreturn(0x11) = 0
5072 ptrace(PTRACE_ATTACH, 5024, 0, 0) = 0
5072 --- SIGCHLD (Child exited) # 0 (0) ---
5072 rt_sigreturn(0x11) = 0
5072 ptrace(PTRACE_ATTACH, 5025, 0, 0) = 0
5072 --- SIGCHLD (Child exited) # 0 (0) ---
5072 rt_sigreturn(0x11) = 0
However you can inspect them yourself. It seems that these threads belong to golang runtime
$ pstack 5094
Thread 1 (process 5094):
#0 0x0000000000459243 in runtime.futex ()
#1 0x00000000004271e0 in runtime.futexsleep ()
#2 0x000000000040d55b in runtime.notetsleep_internal ()
#3 0x000000000040d64b in runtime.notetsleep ()
#4 0x0000000000435677 in runtime.sysmon ()
#5 0x000000000042e6cc in runtime.mstart1 ()
#6 0x000000000042e5d2 in runtime.mstart ()
#7 0x00000000004592b7 in runtime.clone ()
#8 0x0000000000000000 in ?? ()
$ pstack 5095
Thread 1 (process 5095):
#0 0x0000000000459243 in runtime.futex ()
#1 0x0000000000427143 in runtime.futexsleep ()
#2 0x000000000040d3f4 in runtime.notesleep ()
#3 0x000000000042f6eb in runtime.stopm ()
#4 0x0000000000430a79 in runtime.findrunnable ()
#5 0x00000000004310ff in runtime.schedule ()
#6 0x000000000043139b in runtime.park_m ()
#7 0x0000000000455acb in runtime.mcall ()
#8 0x000000c820021500 in ?? ()
#9 0x0000000000000000 in ?? ()
$ pstack 5096
Thread 1 (process 5096):
#0 0x0000000000459243 in runtime.futex ()
#1 0x0000000000427143 in runtime.futexsleep ()
#2 0x000000000040d3f4 in runtime.notesleep ()
#3 0x000000000042f6eb in runtime.stopm ()
#4 0x000000000042fff7 in runtime.startlockedm ()
#5 0x0000000000431147 in runtime.schedule ()
#6 0x000000000043139b in runtime.park_m ()
#7 0x0000000000455acb in runtime.mcall ()
#8 0x000000c820020000 in ?? ()
Update for gdb 8.0
pstack that uses gdb 8.0 correctly prints backtraces for all threas. The command looks like:
$ GDB=$HOME/bin/gdb pstack $(pidof main)
And here is its output (shortened):
$ GDB=$HOME/bin/gdb pstack $(pidof main) | egrep "^Thread"
Thread 4 (LWP 18335):
Thread 3 (LWP 18334):
Thread 2 (LWP 18333):
Thread 1 (LWP 18332):
When you're passing LWP/thread id to pstack you get a stack of that thread only. Try to pass a PID of the process to pstack and you'll get stacks of all its threads. You may get a PID or Tgid (thread group id) of the process: cat /proc/13858/status | grep Tgid. To get all LWPs created by your process you may run ps -L <PID>
Related
I have some complicated problem (by complicated I mean that I couldn't find a solution within a few hours of researching) and the problem is:
I submitted large amount of scripts to run (on an SGE cluster), some of those scripts generated core.# files (core dump files). I figured I could open those files with gdb, now when I simply open the core.# file I see this:
(the last few lines of the gdb output)
Core was generated by `/tools/graphmap/bin/Linux-x64/graphmap align --overlappe'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004a554b in ?? ()
"/4thExp/core.82912" is a core file.
Please specify an executable to debug.
Now to my question - I need to find what was the arguments to the program that caused the crash.
The output mentioned above shows only the beginning of the command that caused the crash: "Core was generated by `/groups/nshomron/artemd/tools/graphmap/bin/Linux-x64/graphmap align --overlappe'."
If I could see the rest of the command I would solve my problem, but after hours of searching online and checking gdb manual I couldn't find anything useful. I tried loading gdb with the program that caused the crash "gdb ..../graphmap core.#" but still I got only the beginning of the faulty command and couldn't get anything else.
Any help suggestion would be very appreciated.
Update: As the user #ks1322 suggested - I looked closely at the threads.
First I executed "info threads" and got the output:
(gdb) info threads
24 Thread 0x2b29409bd700 (LWP 82927) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
23 Thread 0x2b29401b9700 (LWP 82923) 0x00000031d00f820e in __lll_lock_wait_private () from /lib64/libc.so.6
* 22 Thread 0x2b29403ba700 (LWP 82924) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
21 Thread 0x2b29413c2700 (LWP 82932) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
20 Thread 0x2b293fbb6700 (LWP 82920) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
19 Thread 0x2b293fdb7700 (LWP 82921) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
18 Thread 0x2b2940bbe700 (LWP 82928) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
17 Thread 0x2b293f3b2700 (LWP 82916) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
16 Thread 0x2b29411c1700 (LWP 82931) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
15 Thread 0x2b2940dbf700 (LWP 82929) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
14 Thread 0x2b29419c5700 (LWP 82935) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
13 Thread 0x2b293efb0700 (LWP 82914) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
12 Thread 0x2b293f7b4700 (LWP 82918) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
11 Thread 0x2b29407bc700 (LWP 82926) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
10 Thread 0x2b293f9b5700 (LWP 82919) 0x00000031d00f820e in __lll_lock_wait_private () from /lib64/libc.so.6
9 Thread 0x2b29415c3700 (LWP 82933) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
8 Thread 0x2b29405bb700 (LWP 82925) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
7 Thread 0x2b292ea08be0 (LWP 82912) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
6 Thread 0x2b293ffb8700 (LWP 82922) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
5 Thread 0x2b293edaf700 (LWP 82913) 0x00000031d0045063 in vfprintf () from /lib64/libc.so.6
4 Thread 0x2b2940fc0700 (LWP 82930) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
3 Thread 0x2b293f1b1700 (LWP 82915) 0x00000031d00ac6aa in times () from /lib64/libc.so.6
2 Thread 0x2b29417c4700 (LWP 82934) 0x0000000000412bd6 in obtainAlignment(unsigned char const*, unsigned char const*, int, unsigned char const*, unsigned char const*, int, int, int, unsigned char**, int*) ()
1 Thread 0x2b293f5b3700 (LWP 82917) 0x00000000004a554b in GraphMap::ProcessKmerCacheFriendly_(signed char*, long, ScoreRegistry*, MappingData*, Index*, SingleSequence const*, ProgramParameters const*) ()
It didn't tell me very much so I continued to look for a "main thread". I switched to each thread, one by one, and executed "info stack". The only thread containing something relevant was thread 7. the info stack output:
(gdb) thread 7
[Switching to thread 7 (Thread 0x2b292ea08be0 (LWP 82912))]#0 0x00000031d00ac6aa in times () from /lib64/libc.so.6
(gdb) info stack
#0 0x00000031d00ac6aa in times () from /lib64/libc.so.6
#1 0x00000031d009bcba in clock () from /lib64/libc.so.6
#2 0x00000000004ccaed in GraphMap::RegionSelectionNoCopy_(long, MappingData*, std::vector<Index*, std::allocator<Index*> >, SingleSequence const*, ProgramParameters const*) ()
#3 0x00000000004c3544 in GraphMap::ProcessRead(MappingData*, std::vector<Index*, std::allocator<Index*> >, SingleSequence const*, ProgramParameters const*, EValueParams const*) ()
#4 0x00000000004adf43 in GraphMap::ProcessSequenceFileInParallel ()
#5 0x00002b292e7f096f in GOMP_parallel () from /share/apps/gcc/gcc530/lib64/libgomp.so.1
#6 0x00000000004b0b08 in GraphMap::ProcessSequenceFileInParallel(ProgramParameters*, SequenceFile*, long*, _IO_FILE*, long*, long*) ()
#7 0x00000000004b1796 in GraphMap::ProcessReadsFromSingleFile(ProgramParameters&, _IO_FILE*) ()
#8 0x00000000004b281e in GraphMap::Run(ProgramParameters&) ()
#9 0x00000000005087fe in main ()
But I got stuck again from here (short reminder: my goal is to find the full command that crushed the execution, the beginning of which is displayed on the first page of gdb like this:
Core was generated by `/tools/graphmap/bin/Linux-x64/graphmap align
--overlappe'.
Any help from here would be very appreciated.
Final Update, problem solved: I followed #ks1322 advice and went to this stack overflow thread and then I repeated what was described in the first answer and was able to get the arguments.
(short overview of what I understood with my limited knowledge of working with gdb: First you should check what threads were running the task, you can do it with "info threads" then you need to check which thread has "main" in it's stack, I did it by switching threads one by one with "thread #" and printing the stack with "info stack" until I found the thread that had main in it. in my case it was shown like this in the "info stack" #9 0x00000000005087fe in main ()". Then according to the instructions in the linked thread, I executed "set backtrace past-main" then "bt" and then changed frame to the frame containing "in _start ()" with the command "frame #". Almost done, now I ran the command "x/8gx $rsp+8" with showed few four lines with 2 addressees in each line. In my case the second line looked like this "0x7ffe38f872d8: 0x00007ffe38f88c35 0x00007ffe38f88c73" and now if everything was right this address can contain one of the arguments of the command that caused the crush, you can check it with "x/s" command like so: "x/s 0x00007ffe38f88c35" and it prints the argument. Important note: I had a lot of arguments so I needed to go to later addressees that did not show in the "x/8gx $rsp+8" command, I noticed that the addresses are incremented by constant value (3 in hex) so I kept manually in a calculator adding "3" to the address and checking the address with x/s until I got to my wanted argument)
Very messy solution and I hope someone could find an easier solution but that is all I could find.
Big thanks to #ks1322 who cleared up things for me and guided me to the solution.
You can load core dump with matching binary (the one for which core dump was generated) and print argv values in the frame where main function resides.
Something like this:
gdb /tools/graphmap/bin/Linux-x64/graphmap /4thExp/core.82912
Then go up in stack trace to initial frame where int main(int argc, char *argv[]) resides. Now you can print the number of arguments and their values from gdb prompt.
Update:
It appears that your binary is multithreaded and crash happened in some auxiliary thread. You should therefore find main thread and switch to it. Here is an example of how to do it for Firefox with many threads:
(gdb) t a a bt -1
Thread 59 (Thread 0x7f691deff700 (LWP 25924)):
#12 0x00007f69dce93f6f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:105
..........
..........
many threads are listed here
..........
..........
Thread 1 (Thread 0x7f69de01a740 (LWP 4143)):
#17 0x000056374cb38817 in main ()
(gdb) t 1
[Switching to thread 1 (Thread 0x7f69de01a740 (LWP 4143))]
#0 0x00007f69dce8800d in poll () at ../sysdeps/unix/syscall-template.S:84
84 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
Now gdb is switched to main thread (Thread 1).
I'm using gdb.
I run a command like the below to set up the program by sending it input to stdin:
r < <(python -c "print '1\n2\n3'")
I want that command to allow me to start typing input after it finishes (so I can interact with the debugee normally) instead of stdin being closed.
This would work in bash but you can't pipe to the gdb r command this way:
cat <(python -c "print '1\n2\n3'") - | r
The below doesn't work, I assume it waits for EOF before it sends it to the program.
r < <(cat <(python -c "print '1\n2\n3'") -)
Is there a third option that will work?
This sounds like a job for expect.
Given
#include <stdio.h>
int main()
{
char *cp = NULL;
size_t n = 0;
while(getline(&cp, &n, stdin) >= 0) {
fprintf(stderr, "got: %s", cp);
}
return 0;
}
gcc -g -Wall t.c
And this expect script:
#!/usr/bin/expect
spawn gdb -q ./a.out
send run\n
send 1\n2\n3\n
interact
Here is the session:
$ ./t.exp
spawn gdb -q ./a.out
run
1
2
3
Reading symbols from ./a.out...done.
(gdb) run
Starting program: /tmp/a.out
got: 1
got: 2
got: 3
Now the script is waiting for my input. I provide some:
foo bar baz
got: foo bar baz
I can also interact with GDB:
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7b006b0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) bt
#0 0x00007ffff7b006b0 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
#1 0x00007ffff7a8f5a0 in _IO_new_file_underflow (fp=0x7ffff7dd4640 <_IO_2_1_stdin_>) at fileops.c:613
#2 0x00007ffff7a840d5 in _IO_getdelim (lineptr=0x7fffffffdda0, n=0x7fffffffdda8, delimiter=10, fp=0x7ffff7dd4640 <_IO_2_1_stdin_>) at iogetdelim.c:77
#3 0x000000000040064e in main () at t.c:9
I would like to catch a system call (more specifically access) and set a condition on it based on string comparison (obviously for arguments that are strings).
Specific example: when debugging ls I would like to catch access syscalls for specific pathnames (the 1st argument)
int access(const char *pathname, int mode);
So far, I have succeeded in manually inspecting the pathname argument of access (see [1]).
I tried to use this blog post:
catch syscall access
condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
but failed (see [2]), as gdb informed me of a segfault and that Evaluation of the expression containing the function (strcmp#plt) will be abandoned.. However gdb suggested set unwindonsignal on.
Which I tried:
set unwindonsignal on
catch syscall access
condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
but failed again (see [3]) with a similar error and the suggestion set unwindonsignal off...
I searched for the The program being debugged was signaled while in a function called from GDB. error message, but (I think) I didn't find something relevant.
Any help or ideas?
[1]
$ gdb ls
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ls...(no debugging symbols found)...done.
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) r
Starting program: /bin/ls
Catchpoint 1 (call to syscall access), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) x /s $rdi
0x7ffff7df6911: "/etc/ld.so.nohwcap"
(gdb) c
Continuing.
Catchpoint 1 (returned from syscall access), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81 in ../sysdeps/unix/syscall-template.S
(gdb) x /s $rdi
0x7ffff7df6911: "/etc/ld.so.nohwcap"
(gdb) c
Continuing.
Catchpoint 1 (call to syscall access), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81 in ../sysdeps/unix/syscall-template.S
(gdb) x /s $rdi
0x7ffff7df9420 <preload_file.9747>: "/etc/ld.so.preload"
[2]
$ gdb ls
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ls...(no debugging symbols found)...done.
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
(gdb) info breakpoints
Num Type Disp Enb Address What
1 catchpoint keep y syscall "access"
stop only if strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
(gdb) r
Starting program: /bin/ls
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(strcmp#plt) will be abandoned.
When the function is done executing, GDB will silently stop.
Catchpoint 1 (returned from syscall munmap), 0x0000000000000000 in ?? ()
[3]
$ gdb ls
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ls...(no debugging symbols found)...done.
(gdb) set unwindonsignal on
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) condition 1 strcmp((char*)($rdi), "/etc/ld.so.preload") == 0
(gdb) r
Starting program: /bin/ls
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off".
Evaluation of the expression containing the function
(strcmp#plt) will be abandoned.
Catchpoint 1 (returned from syscall munmap), 0x00007ffff7df3537 in access () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) x /s $rdi
0x7ffff7df6911: "/etc/ld.so.nohwcap"
You can use the gdb internal function $_streq like this:
(gdb) catch syscall access
Catchpoint 1 (syscall 'access' [21])
(gdb) condition 1 $_streq((char *)$rdi, "/etc/ld.so.preload")
(gdb) ru
Starting program: /bin/ls
Catchpoint 1 (call to syscall access), 0x00007ffff7df3537 in access ()
at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) p (char *)$rdi
$1 = 0x7ffff7df9420 <preload_file> "/etc/ld.so.preload"
Although Linux doesn't provide pstack as Solaris does, RedHat provides a script can do the same thing:
#!/bin/bash
if test $# -ne 1; then
echo "Usage: `basename $0 .sh` <process-id>" 1>&2
exit 1
fi
if test ! -r /proc/$1; then
echo "Process $1 not found." 1>&2
exit 1
fi
# GDB doesn't allow "thread apply all bt" when the process isn't
# threaded; need to peek at the process to determine if that or the
# simpler "bt" should be used.
backtrace="bt"
if test -d /proc/$1/task ; then
# Newer kernel; has a task/ directory.
if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then
backtrace="thread apply all bt"
fi
elif test -f /proc/$1/maps ; then
# Older kernel; go by it loading libpthread.
if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then
backtrace="thread apply all bt"
fi
fi
GDB=${GDB:-/usr/bin/gdb}
if $GDB -nx --quiet --batch --readnever > /dev/null 2>&1; then
readnever=--readnever
else
readnever=
fi
# Run GDB, strip out unwanted noise.
$GDB --quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 |
$backtrace
EOF
/bin/sed -n \
-e 's/^(gdb) //' \
-e '/^#/p' \
-e '/^Thread/p'
Executing the script in Suse:
linux:~ # pstack 7286
Thread 3 (Thread 0x7f7c074b5700 (LWP 7287)):
#0 0x00007f7c055f7a9d in read () from /lib64/libpthread.so.0
#1 0x00007f7c050a3b76 in ?? () from /usr/lib64/libxenstore.so.3.0
#2 0x00007f7c050a3c2f in ?? () from /usr/lib64/libxenstore.so.3.0
#3 0x00007f7c050a3f72 in ?? () from /usr/lib64/libxenstore.so.3.0
#4 0x00007f7c055f10a4 in start_thread () from /lib64/libpthread.so.0
#5 0x00007f7c03c9104d in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7f7bfe4b0700 (LWP 7288)):
#0 0x00007f7c055f505f in pthread_cond_wait##GLIBC_2.3.2 ()
#1 0x00007f7c07199d99 in ?? ()
#2 0x00007f7c0709a213 in ?? ()
#3 0x00007f7c0709a610 in ?? ()
#4 0x00007f7c055f10a4 in start_thread () from /lib64/libpthread.so.0
#5 0x00007f7c03c9104d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f7c07483980 (LWP 7286)):
#0 0x00007f7c03c88cdf in ppoll () from /lib64/libc.so.6
#1 0x00007f7c07060ec9 in ?? ()
#2 0x00007f7c07026654 in ?? ()
#3 0x00007f7c06edcb36 in ?? ()
#4 0x00007f7c03bcdb05 in __libc_start_main () from /lib64/libc.so.6
#5 0x00007f7c06ee0eec in ?? ()
My question is how to resolve the function name from the address? such as 0x00007fe4ab73eb36. I know maybe through installing debug-info packages, but how to know install which packages?
Update:
According to Mark Plotnick's comments, I use the following command to get which debuginfo packages are lacked:
linux:~ # gdb --quiet -nx --readnever /proc/7286/exe 7286
......
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.19-31.5.x86_64 ......
After installing all need debuginfo packages, the symbols can be resolved:
linux:~ # pstack 7286
Thread 3 (Thread 0x7f7c074b5700 (LWP 7287)):
#0 0x00007f7c055f7a9d in read () from /lib64/libpthread.so.0
#1 0x00007f7c050a3b76 in read_all.part.1.constprop ()
#2 0x00007f7c050a3c2f in read_message.constprop ()
#3 0x00007f7c050a3f72 in read_thread () from /usr/lib64/libxenstore.so.3.0
#4 0x00007f7c055f10a4 in start_thread () from /lib64/libpthread.so.0
#5 0x00007f7c03c9104d in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7f7bfe4b0700 (LWP 7288)):
#0 0x00007f7c055f505f in pthread_cond_wait##GLIBC_2.3.2 ()
#1 0x00007f7c07199d99 in qemu_cond_wait ()
#2 0x00007f7c0709a213 in vnc_worker_thread_loop ()
#3 0x00007f7c0709a610 in vnc_worker_thread ()
#4 0x00007f7c055f10a4 in start_thread () from /lib64/libpthread.so.0
#5 0x00007f7c03c9104d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f7c07483980 (LWP 7286)):
#0 0x00007f7c03c88cdf in ppoll () from /lib64/libc.so.6
#1 0x00007f7c07060ec9 in qemu_poll_ns ()
#2 0x00007f7c07026654 in main_loop_wait ()
#3 0x00007f7c06edcb36 in main ()
But "objdump -t /proc/7286/exe | grep main" outputs nothing:
linux:~ # objdump -t /proc/7286/exe | grep main
linux:~ #
Is it possible for me to track what function/code a thread is executing when debugging with gdb.I do the following
$gdb
$gdb attach pid
$info threads
27 Thread 0x7f0d3a0fe700 (LWP 3418) "BgHangManager" 0x00007f0d4fd9b0af in pthread_cond_wait##GLIBC_2.3.2 () from /lib64/libpthread.so.0
26 Thread 0x7f0d389ff700 (LWP 3419) "gdbus" 0x00007f0d4f098b3d in poll () from /lib64/libc.so.6
25 Thread 0x7f0d381fe700 (LWP 3420) "gmain" 0x00007f0d4f098b3d in poll () from /lib64/libc.so.6
24 Thread 0x7f0d36fff700 (LWP 3422) "Timer" 0x00007f0d4fd9b458 in pthread_cond_timedwait##GLIBC_2.3.2 () from /lib64/libpthread.so.0
23 Thread 0x7f0d3ee52700 (LWP 3423) "Cache2 I/O" 0x00007f0d4fd9b0af in pthread_cond_wait##GLIBC_2.3.2 () from /lib64/libpthread.so.0
$bt
Only gives me the stack-trace of the currently executing code while I would like to
for know what code is exuting in another thread for instance thread 26.
Worked around it by switching to the "wanted" thread and printing the stack-trace