Desperado17
Desperado17

Reputation: 1015

Getting stack area of a thread in GDB

Is there a way to print out the minimum/maximum stack pointer of a thread in GDB or at least the bottom of the stack? The threads are created through pthread in a linux environment.

Regards.

Upvotes: 2

Views: 1516

Answers (1)

Employed Russian
Employed Russian

Reputation: 213955

Is there a way

Sure. It requires installing debug symbols for GLIBC (libc6-dbg or similar).

Example:

#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;
}

Compile with 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

Under GLIBC, the pthread_t == the address GDB prints in info threads == pointer to struct pthread. You can confirm this with:

(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

Using that info:

(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

As you can see, this thread stack region is [0x7ffff75bb000, 0x7ffff7dbc000), and &p is just under the top of stack.

Upvotes: 2

Related Questions