Reputation: 1015
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
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