2017-02-18 2 views
2

Я взял некоторые онлайн-курсы, в которых рассказывалось об использовании стека, и они хороши, но скорее теоретические. Поэтому я пытался понять это, показывая стек какой-то простой программы на C. Я нашел несколько способов сделать это и попытался использовать gdb (backtrace ...).Как я могу показать содержимое стека в C?

Тем не менее, я могу показывать информацию о стеке при возникновении ошибок. Мне интересно, есть ли способ показать стек, даже если программа правильно запущена?

+0

Мы говорим о «стеке вызовов», а не «стек данных», правильно? – Aubin

+4

Возможный дубликат [стека вызовов на печать в C или C++] (http://stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c) – Aubin

+0

Да Aubin, стек вызовов действительно. Спасибо за информацию, и я только что попробовал. Но backtrace, кажется, только показывает вызываемые функции. Я ищу способ отображения подробной информации в стеке, такой как значение параметров, переменных, SP и так далее. – Rick

ответ

3

В теории, вы не можете быть уверены в том, что существует какой-либо стек.

Например, компилятор может inline каждый вызов функции. Или он мог бы сделать какую-то целую программу static analysis и выяснить, что стека не требуется. Или компилятор сделал optimize некоторые звонки как tail calls.

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

На практике, вы можете запустить программу в отладчике (например, gdb) и остановка программа (например, с помощью Ctrl C в вашей gdb сессии), а затем выполнить команду backtrace (или bt) из gdb и examine the stack отлаженного процесса.


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

Если вы хотите получить доступ к call stackпрограммно внутри программы на Linux (с GNU LIBC), вы можете использовать backtrace functions (они не являются стандартными, и не может работать, в частности, с сильными оптимизациями). Или даже Ian Taylor libbacktrace (тогда лучше скомпилировать весь ваш код с -g, так как libbacktrace использует отладочную информацию в формате DWARF).

В комментарии вы добавили:

Я ищу способ показать подробную информацию в стеке, такие как значения параметров, переменных, SP и так далее.

Это невозможно вообще (во время выполнения, изнутри вашей программы). Переменные и параметры известны только компилятору (и забыты во время выполнения).В машинный код у вас есть только ячейки памяти и регистры (и возможно стоп-кадров, которые могут потеряться с -fomit-stack-pointer compile option ....). Кроме того, вы часто компилируете свой код C с помощью optimizations, а затем, вероятно, некоторые переменные не сидят в стеке (но только в регистре).

Обратите внимание, что C не имеет introspection или reflection, без явного continuations, и это не homoiconic языка.

+0

Это решает проблемы, которые у меня возникают, и дает действительно хорошее объяснение. большое спасибо – Rick

2

Мне интересно, есть ли способ показать стек, даже если программа правильно запущена?

Да: вы можете исследовать стек в любой произвольной точке исполнения вашей программы: просто установите точку останова на интересующую вас инструкцию или выполните однопроцессорную программу.

Например:

(gdb) break main 
(gdb) run 

... program stops after main prolog 
(gdb) where # examine stack 
(gdb) stepi # execute one instruction 
(gdb) where 
(gdb) stepi 
... repeat until you reach syscall SYS_exit, or until you are too bored to continue 
+0

Но это использует отладчик .... –

+1

@BasileStarynkevitch Он спрашивает *, как использовать отладчик для проверки состояния (только не на аварийная точка). Обратите внимание на тег GDB в вопросе. –

Смежные вопросы