eXeL@B —› Вопросы новичков —› WinDbg -- как отладить краш в DLL |
Посл.ответ | Сообщение |
|
Создано: 02 октября 2016 16:19 · Личное сообщение · #1 Всем привет. Пришлось искать причину падения DLL. Из известной информации -- адрес, по которому загрузился мой модуль, и call stack с указанием конкретного адреса, по которому произошёл краш. Стоит отметить, что callstack, который у меня имеется, содержит лишь адреса функций, а не их названия. Собственно, чтобы замапить адреса к названиям, я и взялся за WinDbg. Из доступных материалов -- сам PE-файл (.dll), соответствующий ему .pdb и сорцы. Обращаю ваше внимание, что дамп-файла не имею. В интернете наткнулся на Code:
Заглянул в -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 тут же доложил: Code:
Я так понимаю, 10000000 -- это адрес, по которому сам WinDbg загрузил переданный ему модуль, верно? Если так, то что тогда обозначает второй адрес? Далее я посмотрел на адрес, по которому моя DLL была загружена host-процессом в момент падения. Им оказался 0x6F760000. Далее я взглянул на адрес, по которому произошло падение, и увидел 0x6F7E9521. 0x6F7E9521 — 0x6F760000 = 0x89521 Таким образом, я получил адрес в моём бинарнике, по которому произошло падение, и который не привязан к адресу, по которому он загрузился (я ведь прав?). Для получения имени функции, которая находится по этому адресу, я воспользовался следующей командой: ln 10000000 + 89521 , т.е. к 10000000 (по которому, как я предполагаю, был загружен мой модуль WinDbg'ом) прибавил только что вычисленный 0x89521. Получил выхлоп в виде двух функций: Code:
Насколько я понял, вторая из них -- это следующий за найденным символ. В '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, о котором говорится в мануалах, нигде не оказалось, а в онлайн-доках, как вы видите, много чего просто опускается). |
|
Создано: 02 октября 2016 17:46 · Личное сообщение · #2 |
|
Создано: 02 октября 2016 18:02 · Личное сообщение · #3 |
|
Создано: 02 октября 2016 18:06 · Личное сообщение · #4 |
|
Создано: 02 октября 2016 19:39 · Личное сообщение · #5 difexacaw пишет: Инфу сюда всю давайте калстек модуль, всё что имеется. А зачем? Тут просто два момента: - Модуль я не могу предоставить в связи с соглашением - Я не ищу готового решения проблемы (тем более, что причину краша, кажется, я уже нашёл), меня интересуют тонкости работы с WinDbg. Если быть более точным, то ответы на вопросы, обозначенные в первом сообщении. На них, как мне кажется, можно ответить и без дампов / callstack'ов / конкретных модулей Отвечайте лучше вопросом на вопрос, так и я больше пойму, и вам меньше за меня придётся работы делать |
|
Создано: 02 октября 2016 20:06 · Личное сообщение · #6 b0r3d0m пишет: ModLoad: 10000000 100f0000 somebin.dll Я так понимаю, 10000000 -- это адрес, по которому сам WinDbg загрузил переданный ему модуль, верно? Если так, то что тогда обозначает второй адрес? Граница образа. b0r3d0m пишет: Обращаю ваше внимание, что дамп-файла не имею А жаль! Так бы .ecxr и в ответ что-нибудь вроде Code:
----- IZ.RU | Сообщение посчитали полезным: b0r3d0m |
|
Создано: 02 октября 2016 20:10 · Личное сообщение · #7 DenCoder пишет: Граница образа Это вы про второе значение, да? Про первое (10000000) правильно сказал тогда, получается? DenCoder пишет: А жаль! Так бы .ecxr и в ответ что-нибудь вроде Да не спорю. Но что поделаешь, если на компьютере, где произошло падение, не была установлена автоматическая генерация дампов, а у себя краш воспроизвести не получается? Вот и мучаюсь без дополнительной инфы. |
|
Создано: 02 октября 2016 23:54 · Личное сообщение · #8 b0r3d0m пишет: Это вы про второе значение, да? Про первое (10000000) правильно сказал тогда, получается? не совсем. оба значения - это нижняя и верхняя границы образа тоесть первое - текущий imagebase, а второе - imagebase+sizeofimage b0r3d0m пишет: я получил адрес в моём бинарнике, по которому произошло падение, и который не привязан к адресу, по которому он загрузился (я ведь прав?). да. именно это и называется RVA b0r3d0m пишет: Вопрос -- всё ли правильно я делаю? если дампа всё равно нет, какой смысл мучать WinDbg? в IDA дизасм намного приятнее в плане анализа. А так как в ООП коде 80% крашей происходят из-за кривых указателей и неправильных размеров буфера, реальная ошибка может находиться вообще в другом модуле, а не там где оно упало с исключением. Поэтому без стэка вызовов действительно будет нелегко. b0r3d0m пишет: у меня debugger.chm, о котором говорится в мануалах, нигде не оказалось странно, у меня он в той же папке что и WinDbg.exe - | Сообщение посчитали полезным: b0r3d0m |
|
Создано: 03 октября 2016 09:56 · Личное сообщение · #9 |
|
Создано: 03 октября 2016 15:31 · Личное сообщение · #10 -=AkaBOSS=- пишет: если дампа всё равно нет, какой смысл мучать WinDbg? в IDA дизасм намного приятнее в плане анализа А зачем мне дизасм? Я лишь хочу callstack "восстановить" (имена функций получить хотя бы). У меня даже исходники есть, вопрос именно в месте краша и том, как в это место программа попала. -=AkaBOSS=- пишет: А так как в ООП коде 80% крашей происходят из-за кривых указателей и неправильных размеров буфера А при чём здесь ООП? -=AkaBOSS=- пишет: странно, у меня он в той же папке что и WinDbg.exe Да это я качал WinDbg без WDK, видимо, вот и получилось так. difexacaw пишет: А смысл в том, что нужно на этапе разработки позаботиться об таких механизмах Не спорю, нужно. Но программа старая, и уже была отправлена заказчикам без подобных механизмов. |
|
Создано: 03 октября 2016 15:51 · Личное сообщение · #11 |
|
Создано: 03 октября 2016 16:46 · Личное сообщение · #12 DenCoder пишет: Без как минимум дампа стека это не сделать! Что вы подразумеваете под "дампом стека"? В самом начале темы я, например, сказал: > Из известной информации -- адрес, по которому загрузился мой модуль, и call stack с указанием конкретного адреса, по которому произошёл краш. Стоит отметить, что callstack, который у меня имеется, содержит лишь адреса функций, а не их названия. Собственно, чтобы замапить адреса к названиям, я и взялся за WinDbg. .pdb есть, осталось дело за малым -- связать адреса, указанные в "неполноценном" callstack'е, и имена функций, указанные в .pdb-файле. |
|
Создано: 03 октября 2016 19:13 · Личное сообщение · #13 Спустя 10 постов и позабыл уже, что у Вас есть... Дампом, вообще говоря, может быть как вся память процесса, так и отдельный регион. Дамп стека - Ваш call stack. На стеке, кроме адресов возврата также могут быть и аргументы, если вызов функций по cdecl/stdcall, а также локальные переменные функций. Какие локальные переменные где у Вас - это только сопоставлять сорцы дизасму кода. Главного Вы не сообщили - какая ошибка у Вас? 0xC0000005 ? На чтение или запись? И по какому адресу обращение к памяти? Адрес обращения либо через аргументы передаётся, либо высчитывается где-то на локальных переменных. Добавлено спустя 10 минут Ну понятно - callstack восстановите, с аргументами. Дальше прогоните функцию за функцией поочерёдно с указанными в стеке аргументами, проследите, где неверна логика... если не учавствуют глобальные переменные, в структурах/классах поля-указатели на массивы или объекты структур/классов... ----- IZ.RU | Сообщение посчитали полезным: b0r3d0m |
|
Создано: 03 октября 2016 22:44 · Личное сообщение · #14 DenCoder пишет: Главного Вы не сообщили - какая ошибка у Вас? 0xC0000005 ? Да, Access Violation. Падает в ntdll, но сама проблема, конечно же, кроется где-то в пользовательском коде. > Unhandled exception at 0x77E61037 (ntdll.dll) DenCoder пишет: На чтение или запись? На чтение -- "Access violation reading location 0x00000044". |
|
Создано: 04 октября 2016 00:03 · Личное сообщение · #15 Если используется пара операторов new/delete или функций malloc/free для выделения/удаления памяти: Приложение хранит "вокруг" выделенного региона памяти (того, который выделяется оператором new в си) служебные данные - самыми важными будут размер и указатель на свободный регион в куче. Если затереть эту информацию, дальнейшие попытки выделить новый регион или удалить этот и могут приводить к ошибкам внутри ntdll.dll. ----- IZ.RU |
|
Создано: 09 октября 2016 05:54 · Личное сообщение · #16 |
eXeL@B —› Вопросы новичков —› WinDbg -- как отладить краш в DLL |