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

标签 linux gdb

有没有办法打印出GDB中线程的最小/最大堆栈指针或至少打印堆栈底部?在Linux环境下,线程是通过pthread创建的。

问候。

最佳答案

Is there a way

当然。它需要安装 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 在 infothreads 中打印的地址 == 指向 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就在堆栈顶部下方。

关于linux - 在GDB中获取线程的堆栈区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61747545/

相关文章:

linux - 无法使用 npm 在 linux mint 17 中安装 mean-cli

linux - 如何在 Linux 中添加具有 VID/PID 的设备

/dev下创建伪设备节点

python - 如何在 Linux 中截取屏幕截图(高 fps)(编程)

我可以使用 GDB 跳过整个文件(malloc.c 等)吗?

c++ - GDB 报告的额外线程是怎么回事?

linux - Ushare 重新扫描文件系统而不重新启动

c++ - GDB 跳过了我的代码!

debugging - 使用 GDB 调试 Go 时的奇怪行为

go - 如何将地址转换为类型并在 GDB for Golang 中打印它