Зачем отладчику нужны символы для восстановления стека?
При отладке в 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 ответа:
Я думаю, это потому, что не все функции следуют "стандартной" компоновке стека. Обычно каждая функция начинается с:
push ebp mov ebp,esp
И заканчивается на
pop ebp ret
При этом каждая функция создает свой так называемый фрейм стека.
EBP
всегда указывает на начало верхнего кадра стека. В каждом кадре первыми двумя значениями являются указатель на предыдущий кадр стека и адрес возврата функции.Используя эту информацию, можно легко восстановить стек. Однако:
- эта информация стека не будет включать имена функций и информацию о параметрах.
- не все функции подчиняются этой компоновке фрейма стека. Если некоторые оптимизации включены (например, / Oy, опустить указатели фрейма стека) - макет стека отличается.
Некоторое время назад я и сам пытался это понять.
По состоянию на 2013 год FPO не используется в MSFT и обычно не одобряется. Я действительно столкнулся с другой технологией MS binary, используемой внутри, что, вероятно, затрудняет наивное прохождение цепочки EBP: Основные инструменты блоков .
Как отмечалось в посте, PDBs действительно включают "StackFrameTypeEnum", и в другом месте намекается, что они включают "программу размотки" для кадра стека. Так что в целом, они все еще необходимы, и кровавые подробности того, почему именно-не задокументированы.
Символы
Отделяются от связанного двоичного кода, чтобы уменьшить размер двоичных файлов доставки. Проверьте, насколько велики ваши PDB-файлы-огромные, особенно по сравнению с соответствующим двоичным файлом (EXE / DLL). Вы не хотите, чтобы эти накладные расходы каждый раз, когда двоичный файл поставляется, устанавливается и используется. Это особенно важно во время загрузки. В конце концов, информация о символах предназначена только для отладки, а не для корректной работы кода. При условии, что вы сохраняете символы, соответствующие вашим отправленным двоичным файлам, вы все еще можете отлаживать проблемы после смерти со всеми загруженными символами.