[MVS2008] Отловить падение программы

Тема в разделе "LANGS.C", создана пользователем MuForum, 10 авг 2010.

  1. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Доброго времени суток.
    Работаю на "Microsoft Visual Studio 2008", язык программирования "C++".

    Есть программа которая использует MFC.

    # Задача: Отловить падение/crash программы и определить имя или индекс модуля и если возможно имя функции.



    P.S. -> Прошу помочь с проблемой, готов заплатить деньги за помощь.
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ну JIT в помощь, в чём проблема-то?
    или она крашится без эксепшена?
     
  3. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    1. Программа запускается не под отладчиком, а на другом компьютере.
    2. Программа написана на VC++, а не на .NET VC++.
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    и что?
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    да и удаленную отладку никто не отменял.
     
  6. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    SetUnhandledExceptionFilter, там сгенирировать минидамп и выслать вместе с модулем куда нужно
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    MuForum
    Что вы сделали для решения этой задачи ?
     
  8. СFF

    СFF PP

    Публикаций:
    0
    Регистрация:
    16 янв 2009
    Сообщения:
    233
    Так ничего он не сделал. Поэтому и плотит что лень
     
  9. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Благодарю за помощь принявших участие.

    Я решил следующим образом.
    1. В самой программе при падение делаю дамп.
    Код (Text):
    1. typedef BOOL (*MINIDUMPWRITEDUMP)
    2. (
    3.     IN HANDLE hProcess,
    4.     IN DWORD ProcessId,
    5.     IN HANDLE hFile,
    6.     IN MINIDUMP_TYPE DumpType,
    7.     IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
    8.     IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
    9.     IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
    10. );
    11. //---------------------------------------------------------------------------
    12.  
    13. void SetExceptionHook();
    14. LONG TopLevelFilter(struct _EXCEPTION_POINTERS * pExceptionInfo);
    15. //---------------------------------------------------------------------------
    16.  
    17. void SetExceptionHook()
    18. {
    19.     ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopLevelFilter);
    20. }
    21. //---------------------------------------------------------------------------
    22.  
    23. LONG TopLevelFilter(struct _EXCEPTION_POINTERS * pExceptionInfo)
    24. {
    25.     // По умолчанию завершим процесс стандартным образом;
    26.     LONG retval        = EXCEPTION_CONTINUE_SEARCH;
    27.     // ----
    28.     // Сначала попробуем загрузить библиотеку рядом с EXE, т.к.
    29.     // В System32 может быть старая версия.
    30.     HMODULE hDll            = NULL;
    31.     // ----
    32.     TCHAR szDbgHelpPath[_MAX_PATH];
    33.     memset(szDbgHelpPath, 0, _MAX_PATH);
    34.     // ----
    35.     if ( GetModuleFileName(NULL, szDbgHelpPath, _MAX_PATH) != 0 )
    36.     {
    37.         TCHAR * pSlash        = _tcsrchr(szDbgHelpPath, '\\');
    38.         // ----
    39.         if ( pSlash != 0 )
    40.         {
    41.             _tcscpy(pSlash + 1, _T("DBGHELP.DLL"));
    42.             // ----
    43.             hDll            = ::LoadLibrary(szDbgHelpPath);
    44.         }
    45.     }
    46.     // ----
    47.     if ( hDll == NULL )
    48.     {
    49.         // Если загрузка не удалась,
    50.         // Пробуем загрузить любую доступную версию;
    51.         hDll            = ::LoadLibrary( _T("DBGHELP.DLL"));
    52.     }
    53.     // ----
    54.     LPCTSTR szResult    = NULL;
    55.     // ----
    56.     if ( hDll == NULL )
    57.     {
    58.         szResult        = _T("DBGHELP.DLL не найдена");
    59.         // ----
    60.         MessageBox(NULL, szResult, _T("ProgramName"), MB_OK);
    61.         // ----
    62.         return retval;
    63.     }
    64.     // ----
    65.     // Если библиотека загружена - получаем адрес MiniDumpWriteDump();
    66.     MINIDUMPWRITEDUMP pDump    = (MINIDUMPWRITEDUMP)GetProcAddress(hDll, "MiniDumpWriteDump");
    67.     // ----
    68.     if ( pDump == NULL )
    69.     {
    70.         szResult = _T("DBGHELP.DLL старая");
    71.         // ----
    72.         MessageBox(NULL, szResult, _T("ProgramName"), MB_OK);
    73.         // ----
    74.         return retval;
    75.     }
    76.     // ----
    77.     TCHAR        szDumpPath[_MAX_PATH];
    78.     memset(szDumpPath, 0, _MAX_PATH);
    79.     // ----
    80.     TCHAR        szScratch[_MAX_PATH];
    81.     memset(szScratch, 0, _MAX_PATH);
    82.     // ----
    83.     // Будем записывать файл во временную папку;
    84.     // ----
    85.     SYSTEMTIME SysTime;
    86.     GetLocalTime( & SysTime);
    87.     // ----
    88.     char lpCurDir[_MAX_PATH];
    89.     memset(lpCurDir, 0, _MAX_PATH);
    90.     // ----
    91.     GetCurrentDirectory(_MAX_PATH - 1, lpCurDir);
    92.     // ----
    93.     sprintf(szDumpPath, "%s\\ProgramName_Dump_%02d-%02d-%02d_%02d.%02d.%04d.dmp\0",
    94.         lpCurDir,
    95.         SysTime.wHour, SysTime.wMinute, SysTime.wSecond,
    96.         SysTime.wDay, SysTime.wMonth, SysTime.wYear);
    97.     // ----
    98.     // Сообщаем пользователю, что процесс на грани смерти и
    99.     // предлагаем сохранить дамп;
    100.     // ----
    101.     // Создаём файл;
    102.     HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
    103.                                 CREATE_ALWAYS,
    104.                                 FILE_ATTRIBUTE_NORMAL, NULL);
    105.     // ----
    106.     if ( hFile == INVALID_HANDLE_VALUE )
    107.     {
    108.         _stprintf(szScratch,
    109.             _T("Ошибка создания диагностического файла '%s' (код %d)"),
    110.             szDumpPath, GetLastError() );
    111.         // ----
    112.         szResult    = szScratch;
    113.         // ----
    114.         return retval;
    115.     }
    116.     // ----
    117.     _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
    118.     // ----
    119.     ExInfo.ThreadId                = ::GetCurrentThreadId();
    120.     ExInfo.ExceptionPointers    = pExceptionInfo;
    121.     ExInfo.ClientPointers        = NULL;
    122.     // ----
    123.     // И записать в него дамп;
    124.     BOOL bOK        = pDump(GetCurrentProcess(), GetCurrentProcessId(),
    125.                             hFile, MiniDumpNormal, & ExInfo, NULL, NULL);
    126.     // ----
    127.     if ( bOK != 0 )
    128.     {
    129.         _stprintf(szScratch, _T("Файл сохранен в: '%s'"), szDumpPath);
    130.         // ----
    131.         szResult        = szScratch;
    132.         // ----
    133.         retval            = EXCEPTION_EXECUTE_HANDLER;
    134.     }
    135.     else
    136.     {
    137.         _stprintf(szScratch,
    138.             _T("Ошибка сохранения '%s' (код %d)"),
    139.             szDumpPath, GetLastError());
    140.         // ----
    141.         szResult        = szScratch;
    142.     }
    143.     // ----
    144.     ::CloseHandle(hFile);
    145.     // ----
    146.     return retval;
    147. }
    148. //---------------------------------------------------------------------------
    149.  
    150. // # Write in function;
    151. SetExceptionHook();
    152. //---------------------------------------------------------------------------
    Затем при помощи WinDbg (WDK Windows Driver Kit), окрываем Crash log и смотрим что не так.


    P.S. -> Необходимо установить "symbols path".