У меня есть резервная копия процесса, который потерпел крах (трудно воспроизвести).

Я выяснил, что что-то идет не так в функции, которая только что вернулась (она вернула указатель NULL, а не указатель, отличный от NULL).

Мне было бы очень полезно узнать содержимое переменных стека в этой функции. Я думаю, что на большинстве архитектур возврат из функции означает просто изменение указателя стека. Другими словами, эти значения все еще там (ниже указателя стека, если мы возьмем x86 в качестве примера).

Может ли кто-нибудь подтвердить, что мои рассуждения верны, и, возможно, привести пример, как это сделать с помощью gdb?

Верны ли мои рассуждения и для MIPS?

6
Paul Praet 10 Мар 2015 в 11:19

2 ответа

Лучший ответ

Локальные переменные могли храниться в стеке, но не обязательно. Если в регистры помещается лишь небольшое количество переменных и код оптимизирован, то локальные переменные никогда не сохранялись в стеке. В зависимости от используемого соглашения о вызовах окончательные значения локальных переменных могут по-прежнему сохраняться в регистрах.

Дизассемблируйте рассматриваемую функцию (вы можете использовать objdump -dS для этого, чтобы вы могли легко сопоставить источник). Посмотрите, как осуществлялся доступ к локальным переменным. Были ли они сохранены в памяти или регистрах? Были ли уже восстановлены регистры до их значений, актуальных для вызывающего абонента?

Если исходное значение регистра не было восстановлено, вы можете просто проверить регистр, который использовался для локального хранения. Если он уже был восстановлен, то, вероятно, утерян.

Если локальные значения были сохранены в стеке, то пролог функции (первые инструкции) должен рассказать вам, как управлялись стек и указатель кадра. Принимая во внимание, что вызов также сохраняется в стеке (сохраняется на ПК), вы можете вычислить значение указателя стека / кадра, используемого в этой функции. Затем используйте x для проверки ячеек памяти.

В зависимости от вызываемой функции вы также можете проверить ее аргументы (при вызове) и пересчитать значение локальных переменных.

4
dbrank0 10 Мар 2015 в 12:16

Вы можете увидеть локальную переменную, которая не была оптимизирована, используя:

info locals

Однако он может не работать в функции, которая уже возвращается. Если вы можете снова запустить эту программу, попробуйте поставить точку останова непосредственно перед возвратом функции.

В противном случае вы можете вручную исследовать стек, используя x/x и info register, чтобы узнать адрес указателя стека.

Затем вы можете просмотреть стек, используя up и down.

0
blue112 10 Мар 2015 в 08:27