在GDB中获取线程的堆栈区域

时间:2020-05-12 08:52:12

标签: linux gdb

是否有一种方法可以打印出GDB中某个线程的最小/最大堆栈指针或至少堆栈的底部?线程是在Linux环境中通过pthread创建的。

致谢。

1 个答案:

答案 0 :(得分:0)

有办法吗

好的。它需要为GLIBC(libc6-dbg或类似名称)安装调试符号。

示例:

#include <stdlib.h>
#include <pthread.h>

void *fn(void *p) {
  abort();
}

int main() {
  pthread_t tid;
  pthread_create(&tid, NULL, fn, NULL);
  pthread_join(tid, NULL);
  return 0;
}

使用gcc -g -pthread t.c进行编译。

gdb -q a.out
Reading symbols from a.out...
(gdb) run
Starting program: /tmp/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7dbb700 (LWP 57343)]

Thread 2 "a.out" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff7dbb700 (LWP 57343)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) up
#1  0x00007ffff7de4535 in __GI_abort () at abort.c:79
79      abort.c: No such file or directory.
(gdb)
#2  0x0000555555555166 in fn (p=0x0) at t.c:5
5         abort();
(gdb) info thread
  Id   Target Id                                 Frame
  1    Thread 0x7ffff7dbc740 (LWP 57321) "a.out" 0x00007ffff7f894b8 in __GI___pthread_timedjoin_ex (threadid=140737351759616, thread_return=0x0, abstime=<optimized out>, block=<optimized out>) at pthread_join_common.c:84
* 2    Thread 0x7ffff7dbb700 (LWP 57343) "a.out" __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50

在GLIBC下,pthread_t == GDB在info threads ==指向struct pthread的指针中打印的地址。您可以通过以下方式确认这一点:

(gdb) thread 1
[Switching to thread 1 (Thread 0x7ffff7dbc740 (LWP 83723))]
#0  0x00007ffff7f894b8 in __GI___pthread_timedjoin_ex (threadid=140737351759616, thread_return=0x0, abstime=<optimized out>, block=<optimized out>) at pthread_join_common.c:84
84      pthread_join_common.c: No such file or directory.
(gdb) up
#1  0x000055555555519c in main () at t.c:11
11        pthread_join(tid, NULL);
(gdb) p/x tid
$1 = 0x7ffff7dbb700

使用该信息:

(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff7dbb700 (LWP 83746))]
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.

(gdb) p (struct pthread*)0x7ffff7dbb700
$2 = (struct pthread *) 0x7ffff7dbb700
(gdb) p $1->stackblock
$3 = (void *) 0x7ffff75bb000
(gdb) p $1->stackblock_size
$4 = 8392704
(gdb) p/x 0x7ffff75bb000 + 8392704
$5 = 0x7ffff7dbc000
(gdb) p &p
$6 = (void **) 0x7ffff7dbaee8

如您所见,此线程堆栈区域为[0x7ffff75bb000, 0x7ffff7dbc000),而&p位于堆栈顶部之下。