⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_dbg.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
}


// --------------------------------------------------------------------------
// What we do here is trivial : open a file, write out the register information
// from the PEXCEPTION_POINTERS structure, then return EXCEPTION_CONTINUE_SEARCH
// whose magic value tells Win32 to proceed with its normal error handling
// mechanism. This is important : an error dialog will popup if possible and
// the debugger will hopefully coexist peacefully with the structured exception
// handler.
// --------------------------------------------------------------------------
int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data, const char *Message, LPSTR lpCmdLine)
{
    PEXCEPTION_RECORD   Exception = data->ExceptionRecord;
    PCONTEXT            Context = data->ContextRecord;
    char                ModuleName[MAX_PATH];
    char                FileName[MAX_PATH] = "Unknown";
    char*               FilePart, *lastperiod;
    char                CrashModulePathName[MAX_PATH];
    char*               CrashModuleFileName = "Unknown";
    MEMORY_BASIC_INFORMATION    MemInfo;
    static int          BeenHere=false;
    HANDLE              fileHandle;
    unsigned char *     code;
    int                 codebyte,i;
    
    if (BeenHere)       // Going recursive! That must mean this routine crashed!
        return EXCEPTION_CONTINUE_SEARCH;
    BeenHere = true;
    
    // Create a filename to record the error information to.
    // Store it in the executable directory.
    if (GetModuleFileName(NULL, ModuleName, sizeof(ModuleName)) <= 0)
        ModuleName[0] = 0;
    FilePart = GetFilePart(ModuleName);
    
    // Extract the file name portion and remove it's file extension. We'll
    // use that name shortly.
    lstrcpy (FileName, FilePart);
    lastperiod = strrchr (FileName, '.');
    if (lastperiod)
        lastperiod[0] = 0;
    // Replace the executable filename with our error log file name.
    lstrcpy (FilePart, "errorlog.txt");
    fileHandle = CreateFile (ModuleName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
    if (fileHandle == INVALID_HANDLE_VALUE)
    {
        OutputDebugString ("Error creating exception report");
        return EXCEPTION_CONTINUE_SEARCH;
    }
    
    // Append to the error log.
    SetFilePointer (fileHandle, 0, 0, FILE_END);
    
    // Print out some blank lines to separate this error log from any previous ones.
    FPrintf (fileHandle, "Email this file to Doom legacy support so we can fix the bugs\r\n");
    FPrintf (fileHandle, "\r\n\r\n\r\n\r\n");
    FPrintf (fileHandle, "Doom Legacy v%d.%d%s -ERROR LOG-\r\n\r\n", VERSION/100, VERSION%100, VERSIONSTRING);
    FPrintf (fileHandle, "Command Line parameters: ");
    for (i = 1;i<myargc;i++)
        FPrintf (fileHandle, "%s ", myargv[i] );

    FPrintf (fileHandle, "\r\n");
    // VirtualQuery can be used to get the allocation base associated with a
    // code address, which is the same as the ModuleHandle. This can be used
    // to get the filename of the module that the crash happened in.
    if ( VirtualQuery ((void*)Context->Eip, &MemInfo, sizeof(MemInfo)) &&
        GetModuleFileName ((HINSTANCE)MemInfo.AllocationBase,
        CrashModulePathName,
        sizeof(CrashModulePathName)) > 0)
        CrashModuleFileName = GetFilePart(CrashModulePathName);
    
    // Print out the beginning of the error log in a Win95 error window
    // compatible format.
    FPrintf (fileHandle, "%s caused an %s in module %s at %04x:%08x.\r\n",
        FileName, GetExceptionDescription(Exception->ExceptionCode),
        CrashModuleFileName, Context->SegCs, Context->Eip);
    FPrintf (fileHandle, "Exception handler called in %s.\r\n", Message);
    
    RecordSystemInformation (fileHandle);
    
    // If the exception was an access violation, print out some additional
    // information, to the error log and the debugger.
    if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION &&
        Exception->NumberParameters >= 2)
    {
        char DebugMessage[1000];
        const char* readwrite = "Read from";
        if (Exception->ExceptionInformation[0])
            readwrite = "Write to";
        wsprintf(DebugMessage, "%s location %08x caused an access violation.\r\n",
            readwrite, Exception->ExceptionInformation[1]);
#ifdef  _DEBUG
        // The VisualC++ debugger doesn't actually tell you whether a read
        // or a write caused the access violation, nor does it tell what
        // address was being read or written. So I fixed that.
        OutputDebugString("Exception handler: ");
        OutputDebugString(DebugMessage);
#endif
        FPrintf(fileHandle, "%s", DebugMessage);
    }
    
    FPrintf(fileHandle, "\r\n");
    
    // Print out the register values in a Win95 error window compatible format.
    if ((Context->ContextFlags & CONTEXT_FULL) == CONTEXT_FULL)
    {
        FPrintf (fileHandle, "Registers:\r\n");
        FPrintf (fileHandle, "EAX=%.8lx CS=%.4x EIP=%.8lx EFLGS=%.8lx\r\n",
            Context->Eax,Context->SegCs,Context->Eip,Context->EFlags);
        FPrintf (fileHandle, "EBX=%.8lx SS=%.4x ESP=%.8lx EBP=%.8lx\r\n",
            Context->Ebx,Context->SegSs,Context->Esp,Context->Ebp);
        FPrintf (fileHandle, "ECX=%.8lx DS=%.4x ESI=%.8lx FS=%.4x\r\n",
            Context->Ecx,Context->SegDs,Context->Esi,Context->SegFs);
        FPrintf (fileHandle, "EDX=%.8lx ES=%.4x EDI=%.8lx GS=%.4x\r\n",
            Context->Edx,Context->SegEs,Context->Edi,Context->SegGs);
    }
    
    FPrintf (fileHandle, "Bytes at CS:EIP:\r\n");
    
    // Print out the bytes of code at the instruction pointer. Since the
    // crash may have been caused by an instruction pointer that was bad,
    // this code needs to be wrapped in an exception handler, in case there
    // is no memory to read. If the dereferencing of code[] fails, the
    // exception handler will print '??'.
    code = (unsigned char*)Context->Eip;
    for (codebyte = 0; codebyte < NumCodeBytes; codebyte++)
    {
        __try
        {
            FPrintf (fileHandle, "%02x ", code[codebyte]);
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            FPrintf (fileHandle, "?? ");
        }
    }
    
    // Time to print part or all of the stack to the error log. This allows
    // us to figure out the call stack, parameters, local variables, etc.
    FPrintf (fileHandle, "\r\n"
        "Stack dump:\r\n");
    __try
    {
        // Esp contains the bottom of the stack, or at least the bottom of
        // the currently used area.
        DWORD* pStack = (DWORD *)Context->Esp;
        DWORD* pStackTop;
        int Count = 0;
        char    buffer[1000] = "";
        const int safetyzone = 50;
        char*   nearend = buffer + sizeof(buffer) - safetyzone;
        char*   output = buffer;
        char *Suffix;
        __asm
        {
            // Load the top (highest address) of the stack from the
            // thread information block. It will be found there in
            // Win9x and Windows NT.
            mov eax, fs:[4]
            mov pStackTop, eax
        }
        if (pStackTop > pStack + MaxStackDump)
            pStackTop = pStack + MaxStackDump;
        // Too many calls to WriteFile can take a long time, causing
        // confusing delays when programs crash. Therefore I implemented
        // simple buffering for the stack dumping code instead of calling
        // FPrintf directly.
        while (pStack + 1 <= pStackTop)
        {
            if ((Count % StackColumns) == 0)
                output += wsprintf(output, "%08x: ", pStack);
            if ((++Count % StackColumns) == 0 || pStack + 2 > pStackTop)
                Suffix = "\r\n";
            else
                Suffix = " ";
            output += wsprintf(output, "%08x%s", *pStack, Suffix);
            pStack++;
            // Check for when the buffer is almost full, and flush it to disk.
            if (output > nearend)
            {
                FPrintf (fileHandle, "%s", buffer);
                buffer[0] = 0;
                output = buffer;
            }
        }
        // Print out any final characters from the cache.
        FPrintf (fileHandle, "%s", buffer);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        FPrintf(fileHandle, "Exception encountered during stack dump.\r\n");
    }
    
    RecordModuleList (fileHandle);
    
    CloseHandle (fileHandle);
    
    // Return the magic value which tells Win32 that this handler didn't
    // actually handle the exception - so that things will proceed as per
    // normal.
    //BP: should put message for end user to send this file to fix any bug
    return EXCEPTION_CONTINUE_SEARCH;
}


    /*
    //
    //FPrintf ("e-mail this file to legacy@newdoom.com , so that we can fix the problem.\r\n\r\n");
    
    FPrintf ("Exception handler called in %s.\r\n", Message);
    
    GetSystemTime (&systemTime);
    FPrintf ("Error occured at %02d/%02d/%04d %02d:%02d:%02d.\r\n",
             systemTime.wMonth, systemTime.wDay, systemTime.wYear,
             systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
    

    FPrintf ("%s\r\n", filename);
    FPrintf ("Cmd-line: %s\r\n", lpCmdLine);

    // Nested exceptions can occur, get info for each one

    nER = 1;
    while (ER)
    {
        if (nER++>1)
            FPrintf ("Exception Record %d.\r\n", nER);

        FPrintf ("application caused an %s", GetExceptionCodeStr(Exception->ExceptionCode));
        
        if (Context->ContextFlags & CONTEXT_CONTROL)
            FPrintf (" at %.4x:%.8x.\r\n", Context->SegCs, Context->Eip);
        
        // in case of..
        if (Context->Eip != (unsigned long)Exception->ExceptionAddress)
            FPrintf ("Exception Address = %.8x\r\n", Exception->ExceptionAddress);

        if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
        {
            FPrintf ("\r\n%s location 0x%x caused an access violation.\r\n", 
                    (Exception->ExceptionInformation[0] ? "Write to" : "Read from"), 
                     Exception->ExceptionInformation[1]);
        }

        ER = Exception->ExceptionRecord;
    }

    
    if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
    {
        FPrintf ("\r\nDebug Registers:\r\n");
        FPrintf ("Dr0=%.8x  Dr1=%.8x  Dr2=%.8x\r\n"
                 "Dr3=%.8x  Dr6=%.8x  Dr7=%.8x\r\n",
                 Context->Dr0, Context->Dr1, Context->Dr2,
                 Context->Dr3, Context->Dr6, Context->Dr7);
    }

    if (Context->ContextFlags & CONTEXT_FLOATING_POINT)
    {
        FPrintf ("\r\nFloating Save Area:\r\n");
        FPrintf ("ControlWord  =%.8x  TagWord      =%.8x  ErrorSelector=%.8x  DataSelector =%.8x\r\n"
                 "StatusWord   =%.8x  ErrorOffset  =%.8x  DataOffset   =%.8x  Cr0NpxState  =%.8x\r\n",
                 Context->FloatSave.ControlWord, Context->FloatSave.TagWord, Context->FloatSave.ErrorSelector, Context->FloatSave.DataSelector,
                 Context->FloatSave.StatusWord, Context->FloatSave.ErrorOffset, Context->FloatSave.DataOffset, Context->FloatSave.Cr0NpxState
                 );

        //BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
    }


    // in case of...
    if ((Context->ContextFlags & CONTEXT_FULL) != CONTEXT_FULL)
    {
        if (!(Context->ContextFlags & CONTEXT_SEGMENTS))
            FPrintf ("Note! GS,FS,ES,DS are unspecified\r\n");
        if (!(Context->ContextFlags & CONTEXT_INTEGER))
            FPrintf ("Note! EDI,ESI,EBX,EDX,ECX,EAX are unspecified\r\n");
        if (!(Context->ContextFlags & CONTEXT_CONTROL))
            FPrintf ("Note! EBP,CS:EIP,EFlags,SS:ESP are unspecified\r\n");
    }

    if (hwdInstance!=NULL)
    {
        FPrintf ("\r\nHWDDriver loaded at %.8x\r\n", hwdInstance);
        FPrintf ("DLL function pointers:\r\n");
        for (loadfunc = hwdFuncTable, i=0; loadfunc->fnName!=NULL; loadfunc++,i++)
        {
            FPrintf ("hwdFuncTable[%d]: %s loaded at %.8x\r\n", i, loadfunc->fnName,
                                                    (unsigned long) *((void**)loadfunc->fnPointer) );
        }

    }

    FPrintf ("\r\nBytes at CS:EIP:\r\n");
    ucptr = (unsigned char*)Context->Eip;
    for (i=0; i<16; i++)
        FPrintf ("%.2x ", *ucptr++);
    
    FPrintf ("\r\n\r\nStack dump:\r\n");
    ulptr = (unsigned long*)Context->Esp;
    for (i=0; i<16; i++)
        FPrintf ("%.8x ", *ulptr++);

    //FPrintf ("Bytes at CS:EIP:\r\n");
    //FPrintf ("%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x ");
             
    for (i=0; i<16; i++)
    {
        FPrintf ("%x
    }
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -