zorgg@nudnik
Home / 2006 / 09 / 23 / entry # 129

Тестирование и отладка

23.09.2006 09:03
Пост для самых маленьких. Самые большие могут не читать.

Допустим, вы работаете над программой на С++, которую по мере разработки тестирует другой человек или группа людей.

Допустим, ваша программа с завидной регулярностью валится.

Допустим, это сопровождается не сообщением

«Уважаемый тестер! Программа свалилась по причине того, что разработчик в файле MyFile.cpp, строке 12 написал new char[ strlen( str + 1 ) ] вместо new char[ strlen( str ) + 1 ]. Подскажите разработчику, чтобы он больше так не делал»
а чем-то вроде
(0x80000003) occurred in the application at location 0x0041d12b.

Что делать.

Значит, во-первых: 0x0041d12b – это адрес того места, в котором случилось плохое (это плохое называется «исключением»). Можно попробовать запустить программу в режиме отладки (Step Into) и ручками записать это значение в регистр EIP. Вероятнее всего, при этом отладчик перепрыгнет на ту строчку кода, которая сделала бяку.

Во-вторых: Воспользоваться библиотекой DbgHelp (которая входит в комплект Visual Studio), а точнее функцией MiniDumpWriteDump. В этом месте мне придется прекратить паясничать и называть исключения «какой», так как я совершенно не горю желанием писать развернутый howto для идиотов, не знающих как подключить библиотеку.

В общем, библиотеку нужно подключить, а затем сделать что-то похожее на вот это:

#include <dbghelp.h>

void DumpIt( HANDLE hFile, PEXCEPTION_POINTERS excpInfo)
{
MessageBox( NULL, "An exception!", "OMG NO", MB_OK | MB_ICONSTOP );

MINIDUMP_EXCEPTION_INFORMATION eInfo;
eInfo.ThreadId = GetCurrentThreadId();
eInfo.ExceptionPointers = excpInfo;
eInfo.ClientPointers = FALSE;

MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
excpInfo ? &eInfo : NULL,
NULL,
NULL);
}

//...

hDump_File = CreateFile("crash.dmp", GENERIC_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);

__try
{
// Сюда вписать опасный код. В моем случае - всё приложение.
}

__except(DumpIt(hDump_File, GetExceptionInformation()), 0) {}

CloseHandle(hDump_File);

Удачи в отладке.

Update: А, ну гениально. Самое главное забыл сказать. Вышеприведенный код в случае «падения» запишет в файл hDump_File некоторую информацию, с помощью которой можно более или менее точно восстановить обстоятельства крушения. Этот файл можно открыть студией (Open Project/Solution), нажать F5 — и оказаться в условиях, близких к тем, которые привели к катастрофе. Желательно, чтобы файл имел расширение .dmp, это облегчит студии понимание, что ей пытаются всучить.

Ссылка по теме: Статья на английском с примерами. Кроме самой функции MiniDumpWriteDump в статье (и примерах) много лишней ерунды, зато примеры компилируются и работают. Sapienti sat, всё такое.

 ::