WinDbg -- как отладить краш в DLL
От: b0r3d0m  
Дата: 30.09.16 15:58
Оценка:
Всем привет.

Пришлось искать причину падения DLL.
Из известной информации -- адрес, по которому загрузился мой модуль, и call stack с указанием конкретного адреса, по которому произошёл краш.
Из доступных материалов -- сам PE-файл (.dll), соответствующий ему .pdb и сорцы.
Обращаю ваше внимание, что дамп-файла не имею.

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

WinDbg -z somebin.dll


Заглянул в online help и чёт не догнал:

-z DumpFile
Specifies the name of a crash dump file to debug. If the path and file name contain spaces, this must be surrounded by quotation marks. It is possible to open several dump files at once by including multiple -z options, each followed by a different DumpFile value


Это почему это они -z используют, если в документации явно сказано, что данная опция предназначена для указания имени дамп-файла, а не бинарника?

Ну да ладно, попробовал -- получилось (что примечательно, в GUI пункта для отладки DLL я не нашёл).

WinDbg тут же доложил:

ModLoad: 10000000 100f0000 somebin.dll


Я так понимаю, 10000000 -- это адрес, по которому сам WinDbg загрузил переданный ему модуль, верно? Если так, то что тогда обозначает второй адрес?

Далее я посмотрел на адрес, по которому моя DLL была загружена host-процессом в момент падения. Им оказался 0x6F760000.

Далее я взглянул на адрес, по которому произошло падение, и увидел 0x6F7E9521.

0x6F7E9521 — 0x6F760000 = 0x89521

Таким образом, я получил адрес в моём бинарнике, по которому произошло падение, и который не привязан к адресу, по которому он загрузился (я ведь прав?).

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

ln 10000000 + 89521


, т.е. к 10000000 (по которому, как я предполагаю, был загружен мой модуль WinDbg'ом) прибавил только что вычисленный 0x89521.

Получил выхлоп в виде двух функций:

main.cpp(379)+0x1c
SomeProject!Foo::Bar+0x19 | (10089540) SomeProject!Foo::Baz


Насколько я понял, вторая из них -- это следующий за найденным символ. В официальной документации этого сказано не было, но вот здесь нашёл следующее:

'ln' will find the symbol, report its address, and in addition report the address and the name of the symbol that follows the specified one


Вот сейчас сижу, анализирую.

Вопрос -- всё ли правильно я делаю? Смущает много чего из-за отсутствия нормальной документации (по крайней мере, у меня debugger.chm, о котором говорится в мануалах, нигде не оказалось, а в онлайн-доках, как вы видите, много чего просто опускается).
Re: WinDbg -- как отладить краш в DLL
От: b0r3d0m  
Дата: 02.10.16 13:51
Оценка:
Забыл уточнить:

B>Из известной информации -- адрес, по которому загрузился мой модуль, и call stack с указанием конкретного адреса, по которому произошёл краш.


Callstack, который у меня имеется, содержит лишь адреса функций, а не их названия. Собственно, чтобы замапить адреса к названиям, я и взялся за WinDbg.
Re: WinDbg -- как отладить краш в DLL
От: zou  
Дата: 02.10.16 18:04
Оценка: 3 (1)
Здравствуйте, b0r3d0m, Вы писали:

B>Ну да ладно, попробовал -- получилось (что примечательно, в GUI пункта для отладки DLL я не нашёл).

В GUI File -> Open Crash Dump (Ctrl-D)

B>

B>ModLoad: 10000000 100f0000 somebin.dll


B>Я так понимаю, 10000000 -- это адрес, по которому сам WinDbg загрузил переданный ему модуль, верно? Если так, то что тогда обозначает второй адрес?

Конец диапазона адресов, на который замаплена DLL.


B>Для получения имени функции, которая находится по этому адресу, я воспользовался следующей командой:


B>

B>ln 10000000 + 89521


Я бы еще попробовал uf 10000000 + 89521

B>Насколько я понял, вторая из них -- это следующий за найденным символ. В официальной документации этого сказано не было, но вот здесь нашёл следующее:


B>

B>'ln' will find the symbol, report its address, and in addition report the address and the name of the symbol that follows the specified one


ln выдает предшествующий и следующий за указанным адресом символ, поэтому их два.

B>Вот сейчас сижу, анализирую.


B>Вопрос -- всё ли правильно я делаю? Смущает много чего из-за отсутствия нормальной документации (по крайней мере, у меня debugger.chm, о котором говорится в мануалах, нигде не оказалось, а в онлайн-доках, как вы видите, много чего просто опускается).

Все правильно. Из имеющейся информации кроме места падения в коде и читаемого стека, наверное больше ничего не восстановить. chm у меня всегда в каталоге с windbg.exe лежал, не знаю как его может не быть.
Re[2]: WinDbg -- как отладить краш в DLL
От: b0r3d0m  
Дата: 02.10.16 22:13
Оценка:
B>>Ну да ладно, попробовал -- получилось (что примечательно, в GUI пункта для отладки DLL я не нашёл).
zou>В GUI File -> Open Crash Dump (Ctrl-D)

Скорее, вопрос такой -- почему это называется crash dump'ом? Оно ведь ни разу не crash dump, а исследуемый PE-файл.

B>>

B>>ModLoad: 10000000 100f0000 somebin.dll


B>>Я так понимаю, 10000000 -- это адрес, по которому сам WinDbg загрузил переданный ему модуль, верно? Если так, то что тогда обозначает второй адрес?

zou>Конец диапазона адресов, на который замаплена DLL.

Ясно, спасибо.

B>>Для получения имени функции, которая находится по этому адресу, я воспользовался следующей командой:


B>>

B>>ln 10000000 + 89521


zou>Я бы еще попробовал uf 10000000 + 89521


Ну да, это тоже может помочь в локализации места, спасибо.

B>>Насколько я понял, вторая из них -- это следующий за найденным символ. В официальной документации этого сказано не было, но вот здесь нашёл следующее:


B>>

B>>'ln' will find the symbol, report its address, and in addition report the address and the name of the symbol that follows the specified one


zou>ln выдает предшествующий и следующий за указанным адресом символ, поэтому их два.


А есть ли в этом какой-то практический смысл?

zou>chm у меня всегда в каталоге с windbg.exe лежал, не знаю как его может не быть.


Я, возможно, качал WinDbg отдельно от WDK, и в той сборке действительно не было debugger.chm.
Re[3]: WinDbg -- как отладить краш в DLL
От: zou  
Дата: 03.10.16 13:54
Оценка: 3 (1)
Здравствуйте, b0r3d0m, Вы писали:

B>Скорее, вопрос такой -- почему это называется crash dump'ом? Оно ведь ни разу не crash dump, а исследуемый PE-файл.

Не знаю. В 99% загружают именно дамп. Наверное, проблематично кратко сформулировать в UI (чтобы это не вызвало новых вопросов), что есть возможность кроме дампа загрузить dll или exe, но это не будет запуском exe, и в каких случаях это полезно. Но, в принципе, согласен, что можно было бы более явно это сделать.

zou>>ln выдает предшествующий и следующий за указанным адресом символ, поэтому их два.


B>А есть ли в этом какой-то практический смысл?

Не уверен, но, видимо, из общих соображений видится, что если есть некий "примерный" адрес (возможно, полученный в результате ошибки вычисления указателя в программе), то может быть интересен символ как предшествующий ему, так и следующий сразу за ним.
Re: WinDbg -- как отладить краш в DLL
От: Lexey Россия  
Дата: 03.10.16 15:04
Оценка: 1 (1)
Здравствуйте, b0r3d0m, Вы писали:

B>Пришлось искать причину падения DLL.


На будущее советую включить создание map-файлов при сборке. При их наличии все эти танцы с windbg можно опустить — функция, в которой произошел крэш, находится простым поиском по map-файлу.
Re[4]: WinDbg -- как отладить краш в DLL
От: b0r3d0m  
Дата: 03.10.16 19:56
Оценка:
B>>Скорее, вопрос такой -- почему это называется crash dump'ом? Оно ведь ни разу не crash dump, а исследуемый PE-файл.
zou>Не знаю. В 99% загружают именно дамп. Наверное, проблематично кратко сформулировать в UI (чтобы это не вызвало новых вопросов), что есть возможность кроме дампа загрузить dll или exe, но это не будет запуском exe
"Open PE"? Ну да ладно, сделали и сделали.
Re[2]: WinDbg -- как отладить краш в DLL
От: b0r3d0m  
Дата: 03.10.16 19:58
Оценка:
L>На будущее советую включить создание map-файлов при сборке. При их наличии все эти танцы с windbg можно опустить — функция, в которой произошел крэш, находится простым поиском по map-файлу.
Да не сильно-то это отличается. Ещё и шанс ошибиться выше -- сравнивать шестнадцатеричные адреса придётся глазами, вероятность ошибиться возрастает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.