Зачем отладчику нужны символы для восстановления стека?


При отладке в Visual Studio, если символы для стека вызовов отсутствуют, например:

00 > HelloWorld.exe!my_function(int y=42)  Line 291
01   dynlib2.dll!10011435()  
  [Frames below may be incorrect and/or missing, no symbols loaded for dynlib2.dll] 
02   dynlib2.dll!10011497()  
03   HelloWorld.exe!wmain(int __formal=1, int __formal=1)  Line 297 + 0xd bytes
04   HelloWorld.exe!__tmainCRTStartup()  Line 594 + 0x19 bytes
05   HelloWorld.exe!wmainCRTStartup()  Line 414
06   kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes 

Отладчик выдаст предупреждение Frames below may be incorrect and/or missing.

(Обратите внимание, что только строки 01 и 02 не имеют символов. Строка 00, Где я устанавливаю точку останова, и все остальные строки имеют загруженные символы.)

Теперь я знаю, как исправить предупреждение (->get pdb file), но я не совсем понимаю, почему оно отображается! Стек, который я вставил выше, полностью в порядке, просто у меня нет файла pdb для динлиб-2.модуль DLL.

Зачем отладчику нужен файл символов,чтобы убедиться в правильности стека?

3 2

3 ответа:

Я думаю, это потому, что не все функции следуют "стандартной" компоновке стека. Обычно каждая функция начинается с:

push        ebp  
mov         ebp,esp 

И заканчивается на

pop         ebp  
ret

При этом каждая функция создает свой так называемый фрейм стека. EBP всегда указывает на начало верхнего кадра стека. В каждом кадре первыми двумя значениями являются указатель на предыдущий кадр стека и адрес возврата функции.

Используя эту информацию, можно легко восстановить стек. Однако:

  1. эта информация стека не будет включать имена функций и информацию о параметрах.
  2. не все функции подчиняются этой компоновке фрейма стека. Если некоторые оптимизации включены (например, / Oy, опустить указатели фрейма стека) - макет стека отличается.

Некоторое время назад я и сам пытался это понять.

По состоянию на 2013 год FPO не используется в MSFT и обычно не одобряется. Я действительно столкнулся с другой технологией MS binary, используемой внутри, что, вероятно, затрудняет наивное прохождение цепочки EBP: Основные инструменты блоков .

Как отмечалось в посте, PDBs действительно включают "StackFrameTypeEnum", и в другом месте намекается, что они включают "программу размотки" для кадра стека. Так что в целом, они все еще необходимы, и кровавые подробности того, почему именно-не задокументированы.

Символы

Отделяются от связанного двоичного кода, чтобы уменьшить размер двоичных файлов доставки. Проверьте, насколько велики ваши PDB-файлы-огромные, особенно по сравнению с соответствующим двоичным файлом (EXE / DLL). Вы не хотите, чтобы эти накладные расходы каждый раз, когда двоичный файл поставляется, устанавливается и используется. Это особенно важно во время загрузки. В конце концов, информация о символах предназначена только для отладки, а не для корректной работы кода. При условии, что вы сохраняете символы, соответствующие вашим отправленным двоичным файлам, вы все еще можете отлаживать проблемы после смерти со всеми загруженными символами.