sholsapp
sholsapp

Reputation: 16080

Where (exactly) is the call stack?

How can I find the address bounds of the call stack at runtime (via some symbol or register)? I'm using nm and readelf to pick through my symbols and I'm not finding one. In the case of registers, it seems I'm limited to the current frame's base and stack pointers and not the starting address.

I'd like to shy away from answers that involve parsing /proc/pid/maps - I always feel awkward parsing text for a systems-related problem. I'm using g++ on Linux x86/x86_64.

EDIT: Can I use the x86 segment register SS to calculate it?

Upvotes: 2

Views: 623

Answers (4)

sarnold
sarnold

Reputation: 104080

The /proc/pid/maps file on Linux provides some information on a process's memory mappings:

$ cat /proc/self/maps 
00400000-0040b000 r-xp 00000000 08:03 709349                             /bin/cat
0060a000-0060b000 r--p 0000a000 08:03 709349                             /bin/cat
0060b000-0060c000 rw-p 0000b000 08:03 709349                             /bin/cat
00a2d000-00a4e000 rw-p 00000000 00:00 0                                  [heap]
7f6fdf418000-7f6fdf6bd000 r--p 00000000 08:03 489885                     /usr/lib/locale/locale-archive
...
7fff4669e000-7fff466bf000 rw-p 00000000 00:00 0                          [stack]
7fff467ff000-7fff46800000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

The pmap(1) command formats this information into a display that I find more pleasing:

$ pmap $$
11680:   bash
0000000000400000    896K r-x--  /bin/bash
...
00007ff31ae2d000      8K rw---  /lib/x86_64-linux-gnu/ld-2.13.so
00007fff66dd2000    132K rw---    [ stack ]
00007fff66dff000      4K r-x--    [ anon ]
ffffffffff600000      4K r-x--    [ anon ]
 total            29336K

Incidentally, in the eglibc source file dl-execstack.c, I found the following comment: There is no portable way to know the bounds of the initial thread's stack so as to mprotect it. This probably means the best mechanism is to parse the /proc/pid/maps files, even though I think we're all agreed it is tacky.

Upvotes: 2

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215287

The closest you'll get is /proc/self/maps, but even that's not going to make it easy if your program is multi-threaded. You probably should just accept that this is not something you can do in C. It would help if we knew what you want to achieve.

Upvotes: 1

asaelr
asaelr

Reputation: 5456

There is no reason for an object file to contain the address of call stack. The call stack is been allocated by the OP after it load a runnable file.

Usually, rsp (or esp, or whatever you have in your platform) contain the address of the bottom of the call stack. Which mean, it should differ when you call a function (and maybe even when you declare a variable).

Upvotes: 0

Greg Hewgill
Greg Hewgill

Reputation: 993333

The current stack pointer is available in the esp register. However, since stacks are allocated at runtime (because there might be multiple threads), you will have to dive into the private data of your runtime library to find out where the bounds of the current stack are.

Upvotes: 1

Related Questions