在 gdb 中使用核心转储时,我如何确切知道哪个线程导致了 SIGSEGV?
When using a coredump in gdb how do I know exactly which thread caused SIGSEGV?
我的应用程序使用了 8 个以上的线程。当我在 gdb 中运行 info threads
时,我看到线程和它们正在执行的最后一个函数。对我来说,究竟是哪个线程导致了 SIGSEGV 似乎并不明显。有可能告诉它吗?是线程1吗?线程是如何编号的?
当您使用gdb
分析核心转储文件时,gdb
会停在导致程序核心转储的函数处。当前线程将是谋杀。以下面的程序为例:
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *p_arg)
{
while (1)
{
printf("%s\n", (char*)p_arg);
sleep(10);
}
}
int main(void)
{
pthread_t t1, t2;
pthread_create(&t1, NULL, thread_func, "Thread 1");
pthread_create(&t2, NULL, thread_func, NULL);
sleep(1000);
return;
}
t2
线程将导致程序停止,因为它引用了一个 NULL
指针。程序down后,使用gdb
分析core dump文件:
[root@localhost nan]# gdb -q a core.32794
Reading symbols from a...done.
[New LWP 32796]
[New LWP 32795]
[New LWP 32794]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./a'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
(gdb)
gdb
停在 __strlen_sse2
函数,这意味着这个函数导致程序停止。然后用bt
命令查看是哪个线程调用的:
(gdb) bt
#0 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
#1 0x00000034e4268cdb in puts () from /lib64/libc.so.6
#2 0x00000000004005cc in thread_func (p_arg=0x0) at a.c:7
#3 0x00000034e4a079d1 in start_thread () from /lib64/libpthread.so.0
#4 0x00000034e42e8b6d in clone () from /lib64/libc.so.6
(gdb) i threads
Id Target Id Frame
3 Thread 0x7ff6104c1700 (LWP 32794) 0x00000034e42accdd in nanosleep () from /lib64/libc.so.6
2 Thread 0x7ff6104bf700 (LWP 32795) 0x00000034e42accdd in nanosleep () from /lib64/libc.so.6
* 1 Thread 0x7ff60fabe700 (LWP 32796) 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
bt
命令显示当前线程的堆栈帧(这是谋杀)。 “i threads
”命令显示所有线程,以*
开头的线程号为当前线程。
至于“How are the threads numbered?
”,则取决于OS。您可以参考 gdb manual 了解更多信息。
我的应用程序使用了 8 个以上的线程。当我在 gdb 中运行 info threads
时,我看到线程和它们正在执行的最后一个函数。对我来说,究竟是哪个线程导致了 SIGSEGV 似乎并不明显。有可能告诉它吗?是线程1吗?线程是如何编号的?
当您使用gdb
分析核心转储文件时,gdb
会停在导致程序核心转储的函数处。当前线程将是谋杀。以下面的程序为例:
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *p_arg)
{
while (1)
{
printf("%s\n", (char*)p_arg);
sleep(10);
}
}
int main(void)
{
pthread_t t1, t2;
pthread_create(&t1, NULL, thread_func, "Thread 1");
pthread_create(&t2, NULL, thread_func, NULL);
sleep(1000);
return;
}
t2
线程将导致程序停止,因为它引用了一个 NULL
指针。程序down后,使用gdb
分析core dump文件:
[root@localhost nan]# gdb -q a core.32794
Reading symbols from a...done.
[New LWP 32796]
[New LWP 32795]
[New LWP 32794]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./a'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
(gdb)
gdb
停在 __strlen_sse2
函数,这意味着这个函数导致程序停止。然后用bt
命令查看是哪个线程调用的:
(gdb) bt
#0 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
#1 0x00000034e4268cdb in puts () from /lib64/libc.so.6
#2 0x00000000004005cc in thread_func (p_arg=0x0) at a.c:7
#3 0x00000034e4a079d1 in start_thread () from /lib64/libpthread.so.0
#4 0x00000034e42e8b6d in clone () from /lib64/libc.so.6
(gdb) i threads
Id Target Id Frame
3 Thread 0x7ff6104c1700 (LWP 32794) 0x00000034e42accdd in nanosleep () from /lib64/libc.so.6
2 Thread 0x7ff6104bf700 (LWP 32795) 0x00000034e42accdd in nanosleep () from /lib64/libc.so.6
* 1 Thread 0x7ff60fabe700 (LWP 32796) 0x00000034e4281451 in __strlen_sse2 () from /lib64/libc.so.6
bt
命令显示当前线程的堆栈帧(这是谋杀)。 “i threads
”命令显示所有线程,以*
开头的线程号为当前线程。
至于“How are the threads numbered?
”,则取决于OS。您可以参考 gdb manual 了解更多信息。