Показать сообщение отдельно

  #7  
Старый 25.06.2009, 13:07
slesh
Познавший АНТИЧАТ
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


По умолчанию

т.к. судя по всему мало кто это использует или комуто неинтерестно это придется рассказать самому )
Есть такая апишка - SetUnhandledExceptionFilter. Через неё можно устанавливать собственный обработчик исключений для процесса.
Т.е. даже если ошибка произошла в каком либо потоке приложения, то всё равно будет вызван этот обработчик. Дригими словами это типа try except но в глобальном масштабе всего приложения. Вообще эта функция какбы заменяет обработчик ошибок который есть в винде (который показывает сообщение что прога выполнила некорректрую операцию итд).

Использовать его очень удобно для создания стабильных приложений. К примеру если в приложенни появится ошибка, то с помошью этой технологии её можно перехватить (даже без показа на экран) и запустить приложение заново или даже для удобства скинуть отладочный дамп на винт.
Использование очень просто:
Код:
// наш фильтр
LONG MyExceptHandle(struct _EXCEPTION_POINTERS *pExceptionInfo)
{
 char buf[256];
 GetModuleFileNameA(0,buf,256); // получим имя нашей проги
 printf("ERROR\n");
 WinExec(buf,SW_SHOW); // запустим заново её
 ExitProcess(0); // завершим процесс
 return 0;
}  

int main(int argc, char* argv[])
{
 printf("SRART\n");
 // ставим свой фильтр исключений
 SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&MyExceptHandle); 
__asm
 {
  hlt // делаем ошибку
 }
 return 0;
}
Хоть перезапуск лучше делать с следящем процесс.
Лично я иногда использую слудующего рода конструкцию

Код:
LONG MyExceptHandle(struct _EXCEPTION_POINTERS *pExceptionInfo)
{
  _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
  SYSTEMTIME lt;
  char NAME[512];

  GetModuleFileNameA(0, NAME, 512); // получим имя нашей проги
  GetLocalTime(&lt); // получим системное время
  sprintf(NAME, "%s_%i-%i-%i_%i-%i-%i.dmp", NAME, lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
  
  ExInfo.ThreadId = GetCurrentThreadId(); // зададим ID потока
  ExInfo.ExceptionPointers = pExceptionInfo; // зададим исключение
  ExInfo.ClientPointers = 0;
  // создадим файл для дампа
 HANDLE hFile = CreateFileA(NAME, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL );
// скинем дамп в файл
  MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile,MiniDumpNormal,&ExInfo,0,0);
// закроем файл
  CloseHandle(hFile);
// завершим процес с кодом появившейся ошибки
  ExitProcess(pExceptionInfo->ExceptionRecord->ExceptionCode);
 return 0;
}
В этоге при ошибке в прогамме, в папке с прогой появится файл
имяпроги_дата_время.dmp в котором будет содержаться дамп программы на момент ошибки.
Далее этот файл можно свободно подгрузить в отладчик или даже в VC++ 2008 открыть и подробно изучить причину ошибки (при наличии исходников вообще можно видеть строку где произошла ошибка итд итп) Очень удобная вешь для отладки больших проектов.

Последний раз редактировалось slesh; 25.06.2009 в 13:16..
 
Ответить с цитированием