WinDbg не отображает исходные строки, несмотря на загрузку личных файлов pdb

#dll #debugging #windbg

#dll #отладка #windbg

Вопрос:

Я пытаюсь отладить проблему в собственной библиотеке DLL с помощью WinDbg. Я полагаю, что у меня загружены личные символы, но WinDbg не отображает исходные строки или информацию о параметрах. Вот что я наблюдаю; любая помощь была бы высоко оценена!

У меня есть PDB, который, как я полагаю, соответствует DLL в пути поиска символов. Запускаю lm, я вижу:

 01050000 01058000   3NMSMTHR C (private pdb symbols)  e:ads_symbols3NMSMTHR.pdb
  

Поскольку здесь указано «личные символы pdb», я ожидаю, что это частная pdb.

Я также запустил symchk и вижу следующий вывод:

 C:utilsinetmgrpatch01>"c:Program FilesDebugging Tools for Windows (x86)symchk.exe" /v 3nmsmthr.dll /s c:utilsinetmgrpatch01
[SYMCHK] Searching for symbols to C:utilsinetmgrpatch013nmsmthr.dll in path c:utilsinetmgrpatch01
DBGHELP: Symbol Search Path: c:utilsinetmgrpatch01
[SYMCHK] Using search path "c:utilsinetmgrpatch01"
DBGHELP: No header for C:utilsinetmgrpatch013NMSMTHR.DLL.  Searching for image on disk
DBGHELP: C:utilsinetmgrpatch013NMSMTHR.DLL - OK
DBGHELP: 3NMSMTHR - private symbols amp; lines
     c:utilsinetmgrpatch013NMSMTHR.pdb
[SYMCHK] MODULE64 Info ----------------------
[SYMCHK] Struct size: 1680 bytes
[SYMCHK] Base: 0x10000000
[SYMCHK] Image size: 32768 bytes
[SYMCHK] Date: 0x4cc1b0f8
[SYMCHK] Checksum: 0x00000000
[SYMCHK] NumSyms: 0
[SYMCHK] SymType: SymPDB
[SYMCHK] ModName: 3NMSMTHR
[SYMCHK] ImageName: C:utilsinetmgrpatch013NMSMTHR.DLL
[SYMCHK] LoadedImage: C:utilsinetmgrpatch013NMSMTHR.DLL
[SYMCHK] PDB: "c:utilsinetmgrpatch013NMSMTHR.pdb"
[SYMCHK] CV: RSDS
[SYMCHK] CV DWORD: 0x53445352
[SYMCHK] CV Data:  I:usrbpiadrutl3NMSMTHR.pdb
[SYMCHK] PDB Sig:  0
[SYMCHK] PDB7 Sig: {A865C40A-5070-4752-AD1F-CD3087843807}
[SYMCHK] Age: 4
[SYMCHK] PDB Matched:  TRUE
[SYMCHK] DBG Matched:  TRUE
[SYMCHK] Line nubmers: TRUE
[SYMCHK] Global syms:  TRUE
[SYMCHK] Type Info:    TRUE
[SYMCHK] ------------------------------------
SymbolCheckVersion  0x00000002
Result              0x001f0001
DbgFilename
DbgTimeDateStamp    0x4cc1b0f8
DbgSizeOfImage      0x00008000
DbgChecksum         0x00000000
PdbFilename         c:utilsinetmgrpatch013NMSMTHR.pdb
PdbSignature        {A865C40A-5070-4752-AD1F-CD3087843807}
PdbDbiAge           0x00000004
[SYMCHK] [ 0x00000000 - 0x001f0001 ] Checked "C:utilsinetmgrpatch013NMSMTHR.DLL"

SYMCHK: FAILED files = 0
SYMCHK: PASSED   IGNORED files = 1
  

Это позволяет найти PDB по правильному пути, который я указал (обратите внимание, что я скопировал именно этот файл PDB в e:ads_symbols этот путь виден в выводе lm). В выводе symchk указаны номера строк: true, и поэтому я ожидаю увидеть информацию о личном стиле. Однако, если я запускаю ~ kv, то для моих функций в трассировке стека я вижу:

 00bef2ac 01052a8a 00000000 00000000 00020aa4 3NMSMTHR!BPMThrProcTerm 0x2c0
00bef2cc 100073eb 00bef4d8 00000000 00000000 3NMSMTHR!BPMThrThreadInitName 0x2a
  

И это не похоже на чтение личной информации — я не получаю список исходных текстов, как я делаю для функций MS CRT, у которых есть личные символы на сервере символов MSFT. Также, если я сделаю x / t / d 3NMSMTHR!ThreadInitName затем я получаю

 01052a60 <NoType> 3NMSMTHR!BPMThrThreadInitName = <no type information>
  

И, наконец, если я попытаюсь использовать .frame3 (чтобы перейти к этому кадру), а затем выполнить dv для отображения локальных файлов, я получаю:

 0:001> .frame
03 00bef2cc 100073eb 3NMSMTHR!BPMThrThreadInitName 0x2a
0:001> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details.
  

Для меня это не имеет смысла. Буду признателен за любую помощь. Моя общая цель — получить информацию о параметрах и источнике. Или для подтверждения того, что имеющийся у меня PDB-файл на самом деле НЕ является частными символами. Я не создавал эту DLL или PDB и не знаю никаких подробностей о переданных ей параметрах компоновщика.

Thanks!

EDIT:

I failed to mention that I am getting the checksum error:

 *** WARNING: Unable to verify checksum for C:utilsinetmgr3NMSMTHR.dll
  

Извините! Я пытался запустить .команда lines, как предложено ниже, и я вижу:

 *** WARNING: Unable to verify checksum for C:utilsinetmgr3NMSMTHR.dll
DBGHELP: 3NMSMTHR - private symbols amp; lines 
    e:ads_symbols3NMSMTHR.pdb
Line number information will not be loaded
  

Так что, я думаю, это моя проблема. Что приводит к моему следующему вопросу: есть ли способ исправить контрольную сумму (которая указана как 0, см. Выше вывод symchk)? Этот PDB является правильным, учитывая вывод symchk. Могу ли я заставить его обойти проверку контрольной суммы?

ПРАВКА2:

Для всех, кто сталкивался с этим: я смог исправить предупреждение о контрольной сумме с помощью:

 editbin /release 3NMSMTHR.DLL
  

Это устанавливает контрольную сумму в заголовке PE. Затем мне пришлось запустить

 .symopt 0x40
  

В WinDbg, чтобы заставить его загрузить PDB, даже если временная метка в DLL была другой. Я уверен, что в качестве альтернативы я мог бы использовать какую-нибудь утилиту для обновления измененной метки времени.

Это исправило предупреждение о контрольной сумме … но по-прежнему нет информации о параметрах (запуск dv в правом кадре), Нет информации об исходной строке и т.д.

Итак, теперь я потерян. Возможно ли, что эти PDF-файлы не содержат этой информации? Как я могу это подтвердить? Как бы я собрал их, чтобы содержать это? Для их создания мы используем NMAKE.

ПРАВКА3:

Я перестроил DLL и PDB как DEBUG, а затем получил всю информацию трассировки стека, которую я ожидал. Итак, теперь мой вопрос: (1) возможно ли встроить release и получить статические функции, информацию о параметрах и т.д. (информация о личном символе)? и (2) трассировка стека, которую я получал с выпуском dll pdbs, была неверной — первая точка входа в функцию была правильной, но затем следующий кадр стека показал функцию, которая не была вызвана. Я предполагаю, что библиотека DLL выпуска встроила некоторые функции, и каким-то образом PDB просто «угадывала» функцию в этом фрейме? Очень странно.

Ответ №1:

Вы пробовали .команда lines?

Комментарии:

1. Спасибо за отзыв! По крайней мере, теперь я вижу, что windbg предпочитает не загружать информацию о строке из-за проблемы с контрольной суммой. Есть идеи, как это обойти?

Ответ №2:

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

  1. Вы компилируете с помощью /Zi или /ZI (Формат отладочной информации — один из двух вариантов базы данных программы).
  2. Вы не компилируете с помощью /Oy (указатели на фреймы опускаются).
  3. Вы связываетесь с /DEBUG (генерируете отладочную информацию).
  4. Вы сохраняете (но не распространяете) результирующий pdb-файл.

Главное — избегать пропуска указателей на фреймы; их пропуск экономит немного времени / пространства при вызове функции, но очень затрудняет прохождение по стеку. Обратите внимание, что вы все еще можете получать нечетные трассировки стека из релизных сборок из-за других настроек оптимизации (особенно встраивания), но они все равно должны содержать большинство интересных функций.

Ответ №3:

У вас не будет информации о типе, если функция написана на языке ассемблера. Также возможно, что к DLL была подключена статическая библиотека, и в статической библиотеке не было полной отладочной информации.

Комментарии:

1. Спасибо за ваш отзыв! Смотрите мою правку выше. Я тупо забыл упомянуть ошибку контрольной суммы.

Ответ №4:

Я знаю, что это устарело, но для всех, кто сталкивался с этой проблемой, у меня сработало запуск «.lines -e». Вероятно, это то, что предлагал Навин.