Сейчас на форуме: cppasm, tyns777, dutyfree, asfa (+6 невидимых)

 eXeL@B —› Вопросы новичков —› WinDbg -- как отладить краш в DLL
Посл.ответ Сообщение

Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 02 октября 2016 16:19
· Личное сообщение · #1

Всем привет.

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

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

Code:
  1. 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 тут же доложил:

Code:
  1. ModLoad: 10000000 100f0000 somebin.dll


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

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

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

0x6F7E9521 — 0x6F760000 = 0x89521

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

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

ln 10000000 + 89521

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

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

Code:
  1. main.cpp(379)+0x1c
  2. 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, о котором говорится в мануалах, нигде не оказалось, а в онлайн-доках, как вы видите, много чего просто опускается).




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 02 октября 2016 17:46
· Личное сообщение · #2

Дамп в студию.

-----
vx




Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 02 октября 2016 18:02
· Личное сообщение · #3

difexacaw пишет:
Дамп в студию.

Какой дамп? Я же написал:
> Обращаю ваше внимание, что дамп-файла не имею




Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 02 октября 2016 18:06
· Личное сообщение · #4

b0r3d0m

Инфу сюда всю давайте калстек модуль, всё что имеется.

-----
vx




Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 02 октября 2016 19:39
· Личное сообщение · #5

difexacaw пишет:
Инфу сюда всю давайте калстек модуль, всё что имеется.

А зачем? Тут просто два момента:
- Модуль я не могу предоставить в связи с соглашением
- Я не ищу готового решения проблемы (тем более, что причину краша, кажется, я уже нашёл), меня интересуют тонкости работы с WinDbg. Если быть более точным, то ответы на вопросы, обозначенные в первом сообщении. На них, как мне кажется, можно ответить и без дампов / callstack'ов / конкретных модулей
Отвечайте лучше вопросом на вопрос, так и я больше пойму, и вам меньше за меня придётся работы делать




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 02 октября 2016 20:06
· Личное сообщение · #6

b0r3d0m пишет:
ModLoad: 10000000 100f0000 somebin.dll
Я так понимаю, 10000000 -- это адрес, по которому сам WinDbg загрузил переданный ему модуль, верно? Если так, то что тогда обозначает второй адрес?

Граница образа.

b0r3d0m пишет:
Обращаю ваше внимание, что дамп-файла не имею

А жаль! Так бы .ecxr и в ответ что-нибудь вроде
Code:
  1. rax=0000000097303efb rbx=000000005760eca0 rcx=000000005760eca0
  2. rdx=0000000000000080 rsi=000000000b424b10 rdi=000000005d5a51e0
  3. rip=00000000438b088e rsp=000000005760eb98 rbp=0000000000000000
  4.  r8=000000005760ecc0  r9=00000000450df850 r10=00000000450df850
  5. r11=00000000450df850 r12=0000000000000000 r13=0000000000000000
  6. r14=0000000000000000 r15=0000000000000000
  7. iopl=0         nv up ei ng nz na pe nc
  8. cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010282
  9. Unable to load image C:\Path\module.DLL, Win32 error 0n2
  10. *** WARNING: Unable to verify timestamp for module.DLL
  11. *** ERROR: Module load completed but symbols could not be loaded for module.DLL
  12. module+0x7088e:
  13. 00000000`438b088e 8500            test    dword ptr [rax],eax ds:00000000`97303efb=????????


-----
IZ.RU


| Сообщение посчитали полезным: b0r3d0m

Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 02 октября 2016 20:10
· Личное сообщение · #7

DenCoder пишет:
Граница образа

Это вы про второе значение, да? Про первое (10000000) правильно сказал тогда, получается?

DenCoder пишет:
А жаль! Так бы .ecxr и в ответ что-нибудь вроде

Да не спорю. Но что поделаешь, если на компьютере, где произошло падение, не была установлена автоматическая генерация дампов, а у себя краш воспроизвести не получается? Вот и мучаюсь без дополнительной инфы.




Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 02 октября 2016 23:54
· Личное сообщение · #8

b0r3d0m пишет:
Это вы про второе значение, да? Про первое (10000000) правильно сказал тогда, получается?

не совсем. оба значения - это нижняя и верхняя границы образа
тоесть первое - текущий imagebase, а второе - imagebase+sizeofimage

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

да. именно это и называется RVA

b0r3d0m пишет:
Вопрос -- всё ли правильно я делаю?

если дампа всё равно нет, какой смысл мучать WinDbg? в IDA дизасм намного приятнее в плане анализа.
А так как в ООП коде 80% крашей происходят из-за кривых указателей и неправильных размеров буфера, реальная ошибка может находиться вообще в другом модуле, а не там где оно упало с исключением. Поэтому без стэка вызовов действительно будет нелегко.

b0r3d0m пишет:
у меня debugger.chm, о котором говорится в мануалах, нигде не оказалось

странно, у меня он в той же папке что и WinDbg.exe - версия 6.11.1.404

| Сообщение посчитали полезным: b0r3d0m


Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 03 октября 2016 09:56
· Личное сообщение · #9

Как то был вопрос, крэшилась апликуха, как всегда не были встроены средства диагностики. Долго мы капались в той инфе, которая имелась, почему то бился хип; проблему решить так и не удалось. А смысл в том, что нужно на этапе разработки позаботиться об таких механизмах.

-----
vx




Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 октября 2016 15:31
· Личное сообщение · #10

-=AkaBOSS=- пишет:
если дампа всё равно нет, какой смысл мучать WinDbg? в IDA дизасм намного приятнее в плане анализа

А зачем мне дизасм? Я лишь хочу callstack "восстановить" (имена функций получить хотя бы). У меня даже исходники есть, вопрос именно в месте краша и том, как в это место программа попала.

-=AkaBOSS=- пишет:
А так как в ООП коде 80% крашей происходят из-за кривых указателей и неправильных размеров буфера

А при чём здесь ООП?

-=AkaBOSS=- пишет:
странно, у меня он в той же папке что и WinDbg.exe

Да это я качал WinDbg без WDK, видимо, вот и получилось так.

difexacaw пишет:
А смысл в том, что нужно на этапе разработки позаботиться об таких механизмах

Не спорю, нужно. Но программа старая, и уже была отправлена заказчикам без подобных механизмов.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 03 октября 2016 15:51
· Личное сообщение · #11

b0r3d0m пишет:
Я лишь хочу callstack "восстановить"

Без как минимум дампа стека это не сделать!

Кроме сорцов и места ошибки у Вас ничего больше нет - составляйте тесты, тестите, имититируйте ошибочную ситуацию, в отладчике смотрите, что получается.

-----
IZ.RU




Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 октября 2016 16:46
· Личное сообщение · #12

DenCoder пишет:
Без как минимум дампа стека это не сделать!

Что вы подразумеваете под "дампом стека"? В самом начале темы я, например, сказал:

> Из известной информации -- адрес, по которому загрузился мой модуль, и call stack с указанием конкретного адреса, по которому произошёл краш. Стоит отметить, что callstack, который у меня имеется, содержит лишь адреса функций, а не их названия. Собственно, чтобы замапить адреса к названиям, я и взялся за WinDbg.

.pdb есть, осталось дело за малым -- связать адреса, указанные в "неполноценном" callstack'е, и имена функций, указанные в .pdb-файле.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 03 октября 2016 19:13
· Личное сообщение · #13

Спустя 10 постов и позабыл уже, что у Вас есть...

Дампом, вообще говоря, может быть как вся память процесса, так и отдельный регион. Дамп стека - Ваш call stack. На стеке, кроме адресов возврата также могут быть и аргументы, если вызов функций по cdecl/stdcall, а также локальные переменные функций. Какие локальные переменные где у Вас - это только сопоставлять сорцы дизасму кода.

Главного Вы не сообщили - какая ошибка у Вас? 0xC0000005 ? На чтение или запись? И по какому адресу обращение к памяти? Адрес обращения либо через аргументы передаётся, либо высчитывается где-то на локальных переменных.

Добавлено спустя 10 минут
Ну понятно - callstack восстановите, с аргументами. Дальше прогоните функцию за функцией поочерёдно с указанными в стеке аргументами, проследите, где неверна логика... если не учавствуют глобальные переменные, в структурах/классах поля-указатели на массивы или объекты структур/классов...

-----
IZ.RU


| Сообщение посчитали полезным: b0r3d0m

Ранг: 10.7 (новичок), 2thx
Активность: 0.060
Статус: Участник

Создано: 03 октября 2016 22:44
· Личное сообщение · #14

DenCoder пишет:
Главного Вы не сообщили - какая ошибка у Вас? 0xC0000005 ?

Да, Access Violation.

Падает в ntdll, но сама проблема, конечно же, кроется где-то в пользовательском коде.

> Unhandled exception at 0x77E61037 (ntdll.dll)

DenCoder пишет:
На чтение или запись?

На чтение -- "Access violation reading location 0x00000044".




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 04 октября 2016 00:03
· Личное сообщение · #15

Если используется пара операторов new/delete или функций malloc/free для выделения/удаления памяти:
Приложение хранит "вокруг" выделенного региона памяти (того, который выделяется оператором new в си) служебные данные - самыми важными будут размер и указатель на свободный регион в куче. Если затереть эту информацию, дальнейшие попытки выделить новый регион или удалить этот и могут приводить к ошибкам внутри ntdll.dll.

-----
IZ.RU





Ранг: 337.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 09 октября 2016 05:54
· Личное сообщение · #16

Получается суть задачи это сдампить символы, тогда есть для этого различные тулзы и сурцы.

-----
vx



 eXeL@B —› Вопросы новичков —› WinDbg -- как отладить краш в DLL
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати