zoukankan      html  css  js  c++  java
  • 在国外一个开源项目摘出来的一个异常抛出DMP 类

    源代码地址

    http://www.koders.com/cpp/fid0D70CAB44456E71247468C98A1D01A2F758153FE.aspx?s=md5

    .h

     1 // FileZilla - a Windows ftp client
     2 
     3 // Copyright (C) 2004 - Tim Kosse <tim.kosse@gmx.de>
     4 
     5 // This program is free software; you can redistribute it and/or
     6 // modify it under the terms of the GNU General Public License
     7 // as published by the Free Software Foundation; either version 2
     8 // of the License, or (at your option) any later version.
     9 
    10 // This program is distributed in the hope that it will be useful,
    11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 // GNU General Public License for more details.
    14 
    15 // You should have received a copy of the GNU General Public License
    16 // along with this program; if not, write to the Free Software
    17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    18 
    19 // OptionsTypePage.cpp: Implementierungsdatei
    20 //
    21 
    22 #pragma once
    23 
    24 class CExceptionReport
    25 {
    26 public:
    27     CExceptionReport();
    28     ~CExceptionReport();
    29 
    30     static LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo);
    31 
    32 private:
    33     static void CreateReport(PEXCEPTION_POINTERS pExceptionInfo);
    34 
    35     static void StackWalk(CONTEXT Context);
    36     static BOOL GetAddrDetails(PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset);
    37     static bool writeMiniDump(PEXCEPTION_POINTERS pExceptionInfo);
    38     static LPTSTR GetExceptionString(DWORD dwCode);
    39 
    40     static int sendMail();
    41     static void SuspendThreads();
    42 
    43     static void AddToReport(const WCHAR * pText);
    44     static void AddToReport(const char * pText);
    45     static void AddToReport(int number);
    46     static void AddToReportHex(_int64 number, int minDigits = 0);
    47 
    48     static LPTOP_LEVEL_EXCEPTION_FILTER m_previousExceptionFilter;
    49     static TCHAR m_pLogFileName[MAX_PATH];
    50     static HANDLE m_hReportFile;
    51     static TCHAR m_pDmpFileName[MAX_PATH];
    52     static HANDLE m_hDumpFile;
    53     
    54     static BOOL m_bFirstRun;
    55 };
    56 
    57 
    58 extern CExceptionReport ExceptionReport; //global instance of class

    http://www.koders.com/cpp/fidFDBB1BB2C131F08BC93D5A3E6C9F8C772340A919.aspx?s=md5

    CPP

    View Code
      1 // FileZilla - a Windows ftp client
      2 
      3 // Copyright (C) 2004 - Tim Kosse <tim.kosse@gmx.de>
      4 
      5 // This program is free software; you can redistribute it and/or
      6 // modify it under the terms of the GNU General Public License
      7 // as published by the Free Software Foundation; either version 2
      8 // of the License, or (at your option) any later version.
      9 
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU General Public License for more details.
     14 
     15 // You should have received a copy of the GNU General Public License
     16 // along with this program; if not, write to the Free Software
     17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 // OptionsTypePage.cpp: Implementierungsdatei
     20 //
     21 
     22 #include "stdafx.h"
     23 #include <dbghelp.h>
     24 #include "ExceptionReport.h"
     25 #include "..\version.h"
     26 #include "ProcessorInfo.h"
     27 #include "WindowsVersion.h"
     28 #include "mailmsg.h"
     29 #include "Tlhelp32.h"
     30 
     31 typedef BOOL
     32 (_stdcall *tSymFromAddr)(
     33     IN  HANDLE            hProcess,
     34     IN  DWORD64            Address,
     35     OUT PDWORD64        Displacement,
     36     IN OUT PSYMBOL_INFO    Symbol
     37     );
     38 
     39 typedef DWORD
     40 (_stdcall *tSymGetOptions)(
     41     );
     42 
     43 typedef DWORD
     44 (_stdcall *tSymSetOptions)(
     45     IN DWORD   SymOptions
     46     );
     47 
     48 typedef BOOL
     49 (_stdcall *tSymCleanup)(
     50     IN HANDLE hProcess
     51     );
     52 
     53 typedef BOOL
     54 (_stdcall *tSymInitialize)(
     55     IN HANDLE    hProcess,
     56     IN PSTR        UserSearchPath,
     57     IN BOOL        fInvadeProcess
     58     );
     59 
     60 typedef BOOL
     61 (_stdcall *tSymGetLineFromAddr)(
     62     IN  HANDLE                hProcess,
     63     IN  DWORD                dwAddr,
     64     OUT PDWORD                pdwDisplacement,
     65     OUT PIMAGEHLP_LINE        Line
     66     );
     67 
     68 typedef BOOL
     69 (_stdcall *tStackWalk)(
     70     DWORD                            MachineType,
     71     HANDLE                            hProcess,
     72     HANDLE                            hThread,
     73     LPSTACKFRAME                    StackFrame,
     74     PVOID                            ContextRecord,
     75     PREAD_PROCESS_MEMORY_ROUTINE    ReadMemoryRoutine,
     76     PFUNCTION_TABLE_ACCESS_ROUTINE    FunctionTableAccessRoutine,
     77     PGET_MODULE_BASE_ROUTINE        GetModuleBaseRoutine,
     78     PTRANSLATE_ADDRESS_ROUTINE        TranslateAddress
     79     );
     80 
     81 typedef PVOID
     82 (_stdcall *tSymFunctionTableAccess)(
     83     HANDLE  hProcess,
     84     DWORD   AddrBase
     85     );
     86 
     87 typedef DWORD
     88 (_stdcall *tSymGetModuleBase)(
     89     IN  HANDLE              hProcess,
     90     IN  DWORD               dwAddr
     91     );
     92 
     93 typedef BOOL
     94 (_stdcall *tMiniDumpWriteDump)(
     95     HANDLE hProcess,
     96     DWORD ProcessId,
     97     HANDLE hFile,
     98     MINIDUMP_TYPE DumpType,
     99     PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
    100     PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
    101     PMINIDUMP_CALLBACK_INFORMATION CallbackParam
    102     );
    103 
    104 static tSymCleanup                pSymCleanup;
    105 static tSymInitialize            pSymInitialize;
    106 static tSymGetOptions            pSymGetOptions;
    107 static tSymSetOptions            pSymSetOptions;
    108 static tSymGetLineFromAddr        pSymGetLineFromAddr;
    109 static tSymFromAddr                pSymFromAddr;
    110 static tStackWalk                pStackWalk;
    111 static tSymFunctionTableAccess    pSymFunctionTableAccess;
    112 static tSymGetModuleBase        pSymGetModuleBase;
    113 static tMiniDumpWriteDump        pMiniDumpWriteDump;
    114 
    115 // Global class instance
    116 // static CExceptionReport ExceptionReport;
    117 
    118 LPTOP_LEVEL_EXCEPTION_FILTER CExceptionReport::m_previousExceptionFilter;
    119 TCHAR CExceptionReport::m_pLogFileName[MAX_PATH];
    120 HANDLE CExceptionReport::m_hReportFile;
    121 TCHAR CExceptionReport::m_pDmpFileName[MAX_PATH];
    122 HANDLE CExceptionReport::m_hDumpFile;
    123 BOOL CExceptionReport::m_bFirstRun;
    124 
    125 CExceptionReport::CExceptionReport()
    126 {
    127     m_bFirstRun = TRUE;
    128 
    129     m_previousExceptionFilter = SetUnhandledExceptionFilter(UnhandledExceptionFilter);
    130 
    131     // Retrieve report/dump filenames
    132     GetModuleFileName(0, m_pLogFileName, MAX_PATH);
    133 
    134     // Look for the '.' before the "EXE" extension.  Replace the extension
    135     // with "RPT"
    136     LPTSTR p = _tcsrchr(m_pLogFileName, _T('.'));
    137     if (p)
    138     {
    139         p++;
    140         *p = 0;
    141         _tcscpy(m_pDmpFileName, m_pLogFileName);
    142         _tcscpy(p, _T("rpt"));
    143         _tcscat(m_pDmpFileName, _T("dmp"));
    144     }
    145 }
    146 
    147 CExceptionReport::~CExceptionReport()
    148 {
    149     SetUnhandledExceptionFilter(m_previousExceptionFilter);
    150 }
    151 
    152 LONG WINAPI CExceptionReport::UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
    153 {
    154     if (!m_bFirstRun)
    155     {
    156         // Don't generate exception report twice
    157         if (m_previousExceptionFilter)
    158             return m_previousExceptionFilter(pExceptionInfo);
    159         else
    160             return EXCEPTION_CONTINUE_SEARCH;
    161     }
    162     else
    163         m_bFirstRun = FALSE;
    164 
    165     // Suspend all threads to freeze the current state
    166     SuspendThreads();
    167     
    168     HMODULE hDll = LoadLibrary(_T("dbghelp.dll"));
    169     if (!hDll)
    170     {
    171         if (m_previousExceptionFilter)
    172             return m_previousExceptionFilter(pExceptionInfo);
    173         else
    174             return EXCEPTION_CONTINUE_SEARCH;
    175     }
    176 
    177     pSymCleanup                = (tSymCleanup)GetProcAddress(hDll, "SymCleanup");
    178     pSymInitialize            = (tSymInitialize)GetProcAddress(hDll, "SymInitialize");
    179     pSymGetOptions            = (tSymGetOptions)GetProcAddress(hDll, "SymGetOptions");
    180     pSymSetOptions            = (tSymSetOptions)GetProcAddress(hDll, "SymSetOptions");
    181     pSymGetLineFromAddr        = (tSymGetLineFromAddr)GetProcAddress(hDll, "SymGetLineFromAddr");
    182     pSymFromAddr            = (tSymFromAddr)GetProcAddress(hDll, "SymFromAddr");
    183     pStackWalk                = (tStackWalk)GetProcAddress(hDll, "StackWalk");
    184     pSymFunctionTableAccess    = (tSymFunctionTableAccess)GetProcAddress(hDll, "SymFunctionTableAccess");
    185     pSymGetModuleBase        = (tSymGetModuleBase)GetProcAddress(hDll, "SymGetModuleBase");
    186     pMiniDumpWriteDump        = (tMiniDumpWriteDump)GetProcAddress(hDll, "MiniDumpWriteDump");
    187 
    188     if (!pSymCleanup            ||
    189         !pSymInitialize            ||
    190         !pSymGetOptions            ||
    191         !pSymSetOptions            ||
    192         !pSymGetLineFromAddr    ||
    193         !pSymFromAddr            ||
    194         !pStackWalk                ||
    195         !pSymFunctionTableAccess||
    196         !pSymGetModuleBase        ||
    197         !pMiniDumpWriteDump)
    198     {
    199         FreeLibrary(hDll);
    200         if (m_previousExceptionFilter)
    201             return m_previousExceptionFilter(pExceptionInfo);
    202         else
    203             return EXCEPTION_CONTINUE_SEARCH;
    204     }
    205 
    206     if (::MessageBox(NULL,
    207 _T("An unhandled exception has occurred in FileZilla Server\r\n\
    208 FileZilla Server has to be closed.\r\n\r\n\
    209 Would you like to generate an exception report?\r\n\
    210 The report contains all neccessary information about the exception,\r\n\
    211 including a call stack with function parameters and local variables.\r\n\r\n\
    212 If you're using the latest version of FileZilla Server, please send the generated exception record to the following mail address: Tim.Kosse@gmx.de\r\n\
    213 The report will be analyzed and the reason for this exception will be fixed in the next version of FileZilla Server.\r\n\r\n\
    214 Please note: It may be possible - though unlikely - that the exception report may contain personal and or confidential information. All exception reports will be processed higly confidential and solely to analyze the crash. The reports will be deleted immediately after processing.\r\n"),
    215         _T("FileZilla Server - Unhandled exception"), MB_APPLMODAL | MB_YESNO | MB_ICONSTOP)==IDYES)
    216     {
    217         m_hReportFile = CreateFile(m_pLogFileName, GENERIC_WRITE,FILE_SHARE_READ,
    218                                    0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0);
    219     
    220         m_hDumpFile = CreateFile(m_pDmpFileName, GENERIC_WRITE, FILE_SHARE_READ,
    221                                  0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,    0);
    222     
    223         if (m_hReportFile == INVALID_HANDLE_VALUE)
    224         {
    225             TCHAR tmp[MAX_PATH];
    226             _tcscpy(tmp, m_pLogFileName);
    227             TCHAR *pos=_tcsrchr(tmp, '\\');
    228             if (pos)
    229             {
    230                 pos++;
    231                 _stprintf(m_pLogFileName, _T("c:\\%s"), pos);
    232             }
    233             else
    234                 _stprintf(m_pLogFileName, _T("c:\\%s"), tmp);
    235         
    236             m_hReportFile = CreateFile(m_pLogFileName, GENERIC_WRITE,FILE_SHARE_READ,
    237                                        0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0);
    238         }
    239         if (m_hDumpFile == INVALID_HANDLE_VALUE)
    240         {
    241             TCHAR tmp[MAX_PATH];
    242             _tcscpy(tmp, m_pDmpFileName);
    243             TCHAR *pos=_tcsrchr(tmp, '\\');
    244             if (pos)
    245             {
    246                 pos++;
    247                 _stprintf(m_pDmpFileName, _T("c:\\%s"), pos);
    248             }
    249             else
    250                 _stprintf(m_pDmpFileName, _T("c:\\%s"), tmp);
    251         
    252             m_hDumpFile = CreateFile(m_pDmpFileName, GENERIC_WRITE, FILE_SHARE_READ,
    253                                      0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,    0);
    254         }
    255 
    256         int nError=0;
    257         if (m_hReportFile == INVALID_HANDLE_VALUE && INVALID_HANDLE_VALUE)
    258             nError = GetLastError();
    259         else
    260         {
    261 #ifdef TRY
    262             TRY
    263 #endif
    264             {
    265                 if (m_hReportFile != INVALID_HANDLE_VALUE)
    266                     CreateReport(pExceptionInfo);
    267     
    268                 CloseHandle(m_hReportFile);
    269             }
    270 #ifdef TRY
    271             CATCH_ALL(e);
    272             {
    273                 nError = GetLastError();
    274                 CloseHandle(m_hReportFile);
    275             }
    276             END_CATCH_ALL
    277 
    278             TRY
    279 #endif
    280             {
    281                 if (m_hDumpFile != INVALID_HANDLE_VALUE)
    282                     writeMiniDump(pExceptionInfo);
    283 
    284                 CloseHandle(m_hDumpFile);
    285                 nError = 0;
    286             }
    287 #ifdef TRY
    288             CATCH_ALL(e);
    289             {
    290                 CloseHandle(m_hDumpFile);
    291             }
    292             END_CATCH_ALL
    293 #endif
    294         }
    295 
    296         if (nError)
    297         {
    298         
    299             TCHAR tmp[1000];
    300             _stprintf(tmp, _T("Unable to create exception report, error code %d."), nError);
    301             MessageBox(0, tmp, _T("FileZilla Server - Unhandled eception"), MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
    302         }
    303         else
    304         {
    305             sendMail();
    306 
    307             TCHAR tmp[1000];
    308             _stprintf(tmp, _T("The exception report has been saved to \"%s\" and \"%s\".\n\
    309 Please make sure that you are using the latest version of FileZilla Server.\n\
    310 You can download the latest version from http://sourceforge.net/projects/filezilla/.\n\
    311 If you do use the latest version, please send the exception report to Tim.Kosse@gmx.de along with a brief explanation what you did before FileZilla Server crashed."), m_pLogFileName, m_pDmpFileName);
    312             MessageBox(0, tmp, _T("FileZilla Server - Unhandled eception"), MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
    313 
    314             FreeLibrary(hDll);
    315             return EXCEPTION_CONTINUE_SEARCH;
    316         }
    317     }
    318     FreeLibrary(hDll);
    319     if (m_previousExceptionFilter)
    320         return m_previousExceptionFilter(pExceptionInfo);
    321     else
    322         return EXCEPTION_CONTINUE_SEARCH;
    323 
    324 }
    325 
    326 void CExceptionReport::CreateReport(PEXCEPTION_POINTERS pExceptionInfo)
    327 {
    328     // Start out with a banner
    329     AddToReport("Exception report created by ");
    330     AddToReport(GetVersionString());
    331     AddToReport("\r\n===================================================\r\n\r\n");
    332     AddToReport("System details:\r\n");
    333     AddToReport("---------------\r\n\r\nOperating System:      ");
    334     
    335     TCHAR buffer[200];
    336     if (DisplaySystemVersion(buffer))
    337     {
    338         AddToReport(buffer);
    339         AddToReport("\r\n");
    340     }
    341     else
    342         AddToReport("Could not get OS version\r\n");
    343     
    344     CProcessorInfo pi;
    345     CMemoryInfo mi;
    346     AddToReport("Processor Information: ");
    347     AddToReport(pi.GetProcessorName());
    348     AddToReport("\r\nMemory Information:    ");
    349     AddToReport(mi.GetMemoryInfo());
    350     
    351     PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
    352 
    353     // Print fault type
    354     AddToReport("\r\nException Details:\r\n------------------\r\n\r\nException code: ");
    355     AddToReportHex(pExceptionRecord->ExceptionCode, 8);
    356     AddToReport(" ");
    357     AddToReport(GetExceptionString(pExceptionRecord->ExceptionCode));
    358     
    359     // Add fault address and module
    360     TCHAR szModule[MAX_PATH];
    361     memset(szModule, 0, MAX_PATH);
    362     DWORD dwSection, dwOffset;
    363     GetAddrDetails(pExceptionRecord->ExceptionAddress,
    364                       szModule,
    365                       sizeof(szModule),
    366                       dwSection, dwOffset);
    367 
    368     AddToReport("\r\nFault address:  ");
    369     AddToReportHex((int)pExceptionRecord->ExceptionAddress, 8);
    370     AddToReport(" ");
    371     AddToReportHex(dwSection, 2);
    372     AddToReport(":");
    373     AddToReportHex(dwOffset, 8);
    374     AddToReport(" ");
    375     AddToReport(szModule);
    376     AddToReport("\r\n");
    377 
    378     // Set up the symbol engine.
    379     DWORD dwOptions = pSymGetOptions() ;
    380 
    381     // Turn on line loading and deferred loading.
    382     pSymSetOptions(dwOptions | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
    383 
    384     PCONTEXT pContext = pExceptionInfo->ContextRecord;
    385 
    386     // Initialize DbgHelp
    387     if (!pSymInitialize(GetCurrentProcess(), 0, TRUE))
    388         return;
    389 
    390     StackWalk(*pContext);
    391 
    392     pSymCleanup(GetCurrentProcess());
    393 }
    394 
    395 LPTSTR CExceptionReport::GetExceptionString(DWORD dwCode)
    396 {
    397     #define EXCEPTION(x) case EXCEPTION_##x: return _T(#x);
    398 
    399     switch (dwCode)
    400     {
    401         EXCEPTION(ACCESS_VIOLATION)
    402         EXCEPTION(DATATYPE_MISALIGNMENT)
    403         EXCEPTION(BREAKPOINT)
    404         EXCEPTION(SINGLE_STEP)
    405         EXCEPTION(ARRAY_BOUNDS_EXCEEDED)
    406         EXCEPTION(FLT_DENORMAL_OPERAND)
    407         EXCEPTION(FLT_DIVIDE_BY_ZERO)
    408         EXCEPTION(FLT_INEXACT_RESULT)
    409         EXCEPTION(FLT_INVALID_OPERATION)
    410         EXCEPTION(FLT_OVERFLOW)
    411         EXCEPTION(FLT_STACK_CHECK)
    412         EXCEPTION(FLT_UNDERFLOW)
    413         EXCEPTION(INT_DIVIDE_BY_ZERO)
    414         EXCEPTION(INT_OVERFLOW)
    415         EXCEPTION(PRIV_INSTRUCTION)
    416         EXCEPTION(IN_PAGE_ERROR)
    417         EXCEPTION(ILLEGAL_INSTRUCTION)
    418         EXCEPTION(NONCONTINUABLE_EXCEPTION)
    419         EXCEPTION(STACK_OVERFLOW)
    420         EXCEPTION(INVALID_DISPOSITION)
    421         EXCEPTION(GUARD_PAGE)
    422         EXCEPTION(INVALID_HANDLE)
    423     }
    424 
    425     // Try to get descripbion of unknown exceptions
    426     static TCHAR buffer[512] = {0};
    427 
    428     FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
    429                   GetModuleHandle(_T("NTDLL.DLL")),
    430                   dwCode, 0, buffer, sizeof(buffer), 0);
    431 
    432     return buffer;
    433 }
    434 
    435 void CExceptionReport::StackWalk(CONTEXT Context)
    436 {
    437     USES_CONVERSION;
    438     AddToReport("\r\nCall stack:\r\n-----------\r\n\r\n");
    439     AddToReport("Address   Frame     Function            SourceFile\r\n");
    440     
    441     DWORD dwMachineType = 0;
    442 
    443     STACKFRAME sf;
    444     memset(&sf, 0, sizeof(sf));
    445 
    446 #ifdef _M_IX86
    447     // Initialize the STACKFRAME structure for the first call.  This is only
    448     // necessary for Intel CPUs, and isn't mentioned in the documentation.
    449     sf.AddrPC.Offset    = Context.Eip;
    450     sf.AddrPC.Mode        = AddrModeFlat;
    451     sf.AddrStack.Offset    = Context.Esp;
    452     sf.AddrStack.Mode    = AddrModeFlat;
    453     sf.AddrFrame.Offset    = Context.Ebp;
    454     sf.AddrFrame.Mode    = AddrModeFlat;
    455 
    456     dwMachineType = IMAGE_FILE_MACHINE_I386;
    457 #endif
    458 
    459     while (TRUE)
    460     {
    461         // Get next stack frame
    462         if (!pStackWalk(dwMachineType, GetCurrentProcess(), GetCurrentThread(),
    463                         &sf, &Context, 0, 
    464                         pSymFunctionTableAccess, pSymGetModuleBase,    0))
    465             break;
    466 
    467         if (!sf.AddrFrame.Offset)
    468             break; //Invalid frame
    469 
    470         AddToReportHex(sf.AddrPC.Offset, 8);
    471         AddToReport("  ");
    472         AddToReportHex(sf.AddrFrame.Offset, 8);
    473         AddToReport("  ");
    474         
    475         // Get function name for stack frame entry
    476         BYTE symbolBuffer[ sizeof(SYMBOL_INFO) + 1024 ];
    477         PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
    478         pSymbol->SizeOfStruct = sizeof(symbolBuffer);
    479         pSymbol->MaxNameLen = 1024;
    480                     
    481         DWORD64 symDisplacement = 0;    // Displacement of the input address,
    482                                         // relative to the start of the symbol
    483 
    484         if (pSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, &symDisplacement, pSymbol))
    485         {
    486             AddToReport(pSymbol->Name);
    487             AddToReport("+");
    488             AddToReportHex(symDisplacement);
    489         }
    490         else    // No symbol found.  Print out the logical address instead.
    491         {
    492             TCHAR szModule[MAX_PATH] = _T("");
    493             DWORD section = 0, offset = 0;
    494 
    495             GetAddrDetails((PVOID)sf.AddrPC.Offset,
    496                                 szModule, sizeof(szModule), section, offset);
    497 
    498             AddToReportHex(section, 4);
    499             AddToReport(":");
    500             AddToReportHex(offset, 8);
    501             AddToReport(" ");
    502             AddToReport(szModule);
    503         }
    504 
    505         // Get the source line for this stack frame entry
    506         IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
    507         DWORD dwLineDisplacement;
    508         if (pSymGetLineFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
    509                                 &dwLineDisplacement, &lineInfo))
    510         {
    511             AddToReport("  ");
    512             AddToReport(lineInfo.FileName);
    513             AddToReport(" line ");
    514             AddToReport(lineInfo.LineNumber);
    515         }
    516 
    517         AddToReport("\r\n");
    518     }
    519 
    520 }
    521 
    522 bool CExceptionReport::writeMiniDump(PEXCEPTION_POINTERS pExceptionInfo)
    523 {
    524     // Write the minidump to the file
    525     MINIDUMP_EXCEPTION_INFORMATION eInfo;
    526     eInfo.ThreadId = GetCurrentThreadId();
    527     eInfo.ExceptionPointers = pExceptionInfo;
    528     eInfo.ClientPointers = FALSE;
    529 
    530     MINIDUMP_CALLBACK_INFORMATION cbMiniDump;
    531     cbMiniDump.CallbackRoutine = 0;
    532     cbMiniDump.CallbackParam = 0;
    533 
    534 
    535     pMiniDumpWriteDump(
    536         GetCurrentProcess(),
    537         GetCurrentProcessId(),
    538         m_hDumpFile,
    539         MiniDumpNormal,
    540         pExceptionInfo ? &eInfo : NULL,
    541         NULL,
    542         &cbMiniDump);
    543 
    544     // Close file
    545     CloseHandle(m_hDumpFile);
    546 
    547     return true;
    548 }
    549 
    550 int CExceptionReport::sendMail()
    551 {
    552     CMailMsg mail;
    553 
    554     mail.SetTo(_T("tim.kosse@gmx.de"), _T("Tim Kosse"));
    555 
    556     TCHAR str[4096];
    557     _stprintf(str, _T("Exception report created by %s\r\n\r\n"), (LPCTSTR)GetVersionString());
    558     mail.SetSubject(str);
    559 
    560     mail.SetMessage(_T("Enter your comments here, what did you do with FileZilla Server before it crashed?"));
    561 
    562     mail.AddAttachment(m_pLogFileName, _T("FileZillaServer.rpt"));
    563     mail.AddAttachment(m_pDmpFileName, _T("FileZillaServer.dmp"));
    564 
    565     return mail.Send();
    566 }
    567 
    568 void CExceptionReport::SuspendThreads()
    569 {
    570     // Try to get OpenThread and Thread32* function from kernel32.dll, since it's not available on Win95/98
    571     typedef HANDLE (WINAPI *tOpenThread)    (DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);
    572     typedef BOOL (WINAPI *tThread32First)    (HANDLE hSnapshot, LPTHREADENTRY32 lpte);
    573     typedef BOOL (WINAPI *tThread32Next)    (HANDLE hSnapshot, LPTHREADENTRY32 lpte);
    574     typedef HANDLE (WINAPI *tCreateToolhelp32Snapshot)    (DWORD dwFlags, DWORD th32ProcessID);
    575 
    576     HMODULE hKernel32Dll = LoadLibrary(_T("kernel32.dll"));
    577     if (!hKernel32Dll)
    578         return;
    579     tOpenThread        pOpenThread        = (tOpenThread)        GetProcAddress(hKernel32Dll, "OpenThread");
    580     tThread32First    pThread32First    = (tThread32First)    GetProcAddress(hKernel32Dll, "Thread32First");
    581     tThread32Next    pThread32Next    = (tThread32Next)    GetProcAddress(hKernel32Dll, "Thread32Next");
    582     tCreateToolhelp32Snapshot pCreateToolhelp32Snapshot    = (tCreateToolhelp32Snapshot)    GetProcAddress(hKernel32Dll, "CreateToolhelp32Snapshot");
    583     if (!pOpenThread    ||
    584         !pThread32First    ||
    585         !pThread32Next    ||
    586         !pCreateToolhelp32Snapshot)
    587     {
    588         CloseHandle(hKernel32Dll);
    589         return;
    590     }
    591 
    592     HANDLE hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    593 
    594     // Get information about own process/thread
    595     DWORD ownProcessId = GetCurrentProcessId();
    596     DWORD ownThreadId = GetCurrentThreadId();
    597 
    598     // Enumerate threads
    599     THREADENTRY32 entry;
    600     entry.dwSize = sizeof(THREADENTRY32);
    601     BOOL bNext = pThread32First(hSnapshot, &entry);
    602     while (bNext)
    603     {
    604         if (entry.th32OwnerProcessID == ownProcessId &&
    605             entry.th32ThreadID != ownThreadId)
    606         {
    607             // Suspen threads of own process
    608             HANDLE hThread = pOpenThread(THREAD_SUSPEND_RESUME, FALSE, entry.th32ThreadID);
    609             if (hThread)
    610                 SuspendThread(hThread);
    611         }
    612         bNext = pThread32Next(hSnapshot, &entry);
    613     }
    614     CloseHandle(hKernel32Dll);
    615 }
    616 
    617 void CExceptionReport::AddToReport(const char * pText)
    618 {
    619     DWORD bytesWritten = 0;
    620     WriteFile(m_hReportFile, pText, strlen(pText), &bytesWritten, 0);
    621 }
    622 
    623 void CExceptionReport::AddToReport(const WCHAR * pText)
    624 {
    625     USES_CONVERSION;
    626     AddToReport(W2A(pText));
    627 }
    628 
    629 void CExceptionReport::AddToReport(int number)
    630 {
    631     char buffer[sizeof(int) * 4];
    632     sprintf(buffer, "%d", number);
    633     AddToReport(buffer);
    634 }
    635 
    636 void CExceptionReport::AddToReportHex(_int64 number, int minDigits /*=0*/)
    637 {
    638     char buffer[sizeof(_int64) * 2 + 1];
    639     if (!minDigits)
    640         sprintf(buffer, "%I64X", number);
    641     else
    642     {
    643         char fmt[10];
    644         sprintf(fmt, "%%0%dI64X", minDigits);
    645         sprintf(buffer, fmt, number);
    646     }
    647     AddToReport(buffer);
    648 }
    649 
    650 BOOL CExceptionReport::GetAddrDetails(PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset)
    651 {
    652     // Get details about an address: Module name, section and offet
    653     
    654     // Get information about the provided address
    655     MEMORY_BASIC_INFORMATION mbi;
    656     if (!VirtualQuery(addr, &mbi, sizeof(mbi)))
    657         return FALSE;
    658 
    659     // Get module
    660     DWORD hMod = (DWORD)mbi.AllocationBase;
    661     if (!GetModuleFileName((HMODULE)hMod, szModule, len))
    662         return FALSE;
    663 
    664     
    665     // Get DOS header of module
    666     PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod;
    667 
    668     // Advance to PE header and get the section information
    669     PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(hMod + pDosHeader->e_lfanew);
    670     PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeader);
    671 
    672     // Get module load address
    673     DWORD lAddr = (DWORD)addr - hMod; 
    674 
    675     // Search for a section which contains the address
    676     for (unsigned int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++)
    677     {
    678         // Calculate section start and end addresses
    679         DWORD startAddr = pSection->VirtualAddress;
    680         DWORD endAddr = startAddr;
    681         if (pSection->SizeOfRawData > pSection->Misc.VirtualSize)
    682             endAddr += pSection->SizeOfRawData;
    683         else
    684             pSection->Misc.VirtualSize;
    685 
    686         // Look if provided address is between startAddr and endAddr
    687         if (lAddr >= startAddr && lAddr <= endAddr)
    688         {
    689             // We've found the section, set section index and offset
    690             section = i+1;
    691             offset = lAddr - startAddr;
    692             return TRUE;
    693         }
    694         pSection++;
    695     }
    696 
    697     // Section not found, very strange
    698     return FALSE;
    699 }
  • 相关阅读:
    中文前端UI框架Kit(八)无插件异步文件上传组件源码解析
    中文前端UI框架Kit(十三)使用RequireJs托管你的类库和js代码
    中文前端UI框架Kit(九)IE下实现W3C标准的range对象所有api,支持通过xpath跨浏览器实现特定选区高亮,书签标记功能
    中文前端UI框架Kit(十四)超酷的瀑布流特效动画
    不知道大家知道不知道,iOS开发,web页面的链接的active属性无效,但是今天发现一个hack办法可以让Css的active有效
    中文前端UI框架Kit(十二)整合Mustache做kitjs模板引擎,基本写法${varname}
    中文前端UI框架Kit(七)无插件异步文件上传组件,带进度,支持文件拖拽
    中文前端UI框架Kit(十一)摇头动画?让你的页面元素嗑药嗑起来??
    中文前端UI框架Kit(六)javascript动画代码实现原理和一些小技巧
    中文前端UI框架Kit(十)Javascript多线程工作模型的实现
  • 原文地址:https://www.cnblogs.com/FCoding/p/2579683.html
Copyright © 2011-2022 走看看