Где (точно) находится стек вызовов? - PullRequest
2 голосов
/ 13 февраля 2012

Как я могу найти адресные границы стека вызовов во время выполнения (через некоторый символ или регистр)? Я использую nm и readelf, чтобы выбрать символы, и я не нахожу их. В случае регистров кажется, что я ограничен указателями базы и стека текущего кадра, а не начальным адресом.

Я бы хотел уклониться от ответов, связанных с разбором /proc/pid/maps - Я всегда чувствую неловкий анализ текста для системной проблемы. Я использую g++ на Linux x86/x86_64.

РЕДАКТИРОВАТЬ: Могу ли я использовать регистр сегмента x86 SS для его расчета?

Ответы [ 4 ]

2 голосов
/ 13 февраля 2012

Файл /proc/pid/maps в Linux предоставляет некоторую информацию о отображениях памяти процесса:

$ 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]

Команда pmap(1) форматирует эту информацию в виде, который я считаю более приятным:

$ 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

Кстати, в исходном файле eglibc dl-execstack.c я обнаружил следующий комментарий: Не существует переносимого способа узнать границы стека исходного потока, чтобы mprotect it. Это, вероятно, означает, что лучший механизм - это анализ файлов /proc/pid/maps, хотя я думаю, что мы все согласны, что это плохо.

1 голос
/ 13 февраля 2012

Самое близкое, что вы получите, это /proc/self/maps, но даже это не поможет, если ваша программа многопоточная. Вы, вероятно, должны просто признать, что это не то, что вы можете сделать в C. Было бы полезно, если бы мы знали, чего вы хотите достичь.

1 голос
/ 13 февраля 2012

Указатель стека current доступен в регистре esp.Однако, поскольку стеки выделяются во время выполнения (поскольку может быть несколько потоков), вам придется погрузиться в личные данные вашей библиотеки времени выполнения, чтобы узнать, где находятся границы текущего стека.

0 голосов
/ 13 февраля 2012

Нет причин для объектного файла содержать адрес стека вызовов. Стек вызовов выделяется OP после загрузки исполняемого файла.

Обычно rsp (или esp, или что у вас есть на вашей платформе) содержат адрес нижней части стека вызовов. Это означает, что он должен отличаться при вызове функции (и, возможно, даже при объявлении переменной).

...