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

📄 crash_handler.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
// values.
//////////////////////////////////////////////////////////////////////////////
BOOL FormatSymbolValue(
            PSYMBOL_INFO pSym,
            STACKFRAME * sf,
            char * pszBuffer,
            unsigned cbBuffer )
{
    char * pszCurrBuffer = pszBuffer;
    DWORD_PTR pVariable = 0;    // Will point to the variable's data in memory
	BOOL bHandled;
	BasicType basicType;

    // Indicate if the variable is a local or parameter
    if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER )
        pszCurrBuffer += sprintf( pszCurrBuffer, "Parameter " );
    else if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL )
        pszCurrBuffer += sprintf( pszCurrBuffer, "Local " );

    // If it's a function, don't do anything.
    if ( pSym->Tag == 5 )   // SymTagFunction from CVCONST.H from the DIA SDK
        return 0;

    // Emit the variable name
    pszCurrBuffer += sprintf( pszCurrBuffer, "\'%s\'", pSym->Name );

    if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE )
    {
        // if ( pSym->Register == 8 )   // EBP is the value 8 (in DBGHELP 5.1)
        {                               //  This may change!!!
            pVariable = sf->AddrFrame.Offset;
            pVariable += (DWORD_PTR)pSym->Address;
        }
        // else
        //  return false;
    }
    else if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER )
    {
        return 0;   // Don't try to report register variable
    }
    else
    {
        pVariable = (DWORD_PTR)pSym->Address;   // It must be a global variable
    }

    // Determine if the variable is a user defined type (UDT).  IF so, bHandled
    // will return true.
    pszCurrBuffer = DumpTypeIndex(pszCurrBuffer,pSym->ModBase, pSym->TypeIndex,
                                    0, pVariable, &bHandled );

    if ( !bHandled )
    {
        // The symbol wasn't a UDT, so do basic, stupid formatting of the
        // variable.  Based on the size, we're assuming it's a char, WORD, or
        // DWORD.
        basicType = GetBasicType( pSym->TypeIndex, pSym->ModBase );
        
        pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType, pSym->Size,
                                            (PVOID)pVariable ); 
    }


    return 1;
}

BOOL CALLBACK
EnumerateSymbolsCallback(
    PSYMBOL_INFO  pSymInfo,
    ULONG         SymbolSize,
    PVOID         UserContext )
{

    char szBuffer[2048];

    __try
    {
        if ( FormatSymbolValue( pSymInfo, (STACKFRAME*)UserContext,
                                szBuffer, sizeof(szBuffer) ) )  
            fprintf(fh, "\t%s\r\n", szBuffer );
    }
    __except( 1 )
    {
        fprintf(fh, "punting on symbol %s\r\n", pSymInfo->Name );
    }

    return TRUE;
}

void WriteStackDetails(PCONTEXT pContext, int writevars)
{
	DWORD dwMachineType = 0;
	STACKFRAME sf;
	unsigned char symbolBuffer[ sizeof(SYMBOL_INFO) + 1024 ];
	PSYMBOL_INFO pSymbol;
	DWORD64 symDisplacement = 0;
	char fModule[MAX_PATH];
	DWORD section = 0, offset = 0;
	IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
	DWORD dwLineDisplacement;
	IMAGEHLP_STACK_FRAME imagehlpStackFrame;

	fprintf(fh, "\nCall stack:\n");
	fprintf(fh, "Address    Frame    Function                    Source File\n");
	fprintf(fh, "===============================================================\n");

	memset(&sf, 0x00, sizeof(sf));

#ifdef _M_IX86
	sf.AddrPC.Offset = pContext->Eip;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrStack.Offset = pContext->Esp;
	sf.AddrStack.Mode = AddrModeFlat;
	sf.AddrFrame.Offset = pContext->Ebp;

	dwMachineType = IMAGE_FILE_MACHINE_I386;
#endif

	while (1)
	{
		if (!StackWalk( dwMachineType, m_hProcess, GetCurrentThread(), &sf, pContext,
			0, SymFunctionTableAccess, SymGetModuleBase, 0))
			break;

		if ( 0 == sf.AddrFrame.Offset)
			break;

		fprintf(fh, "%08X  %08X  ", sf.AddrPC.Offset, sf.AddrFrame.Offset);

		pSymbol = (PSYMBOL_INFO)symbolBuffer;
		pSymbol->SizeOfStruct = sizeof(symbolBuffer);
		pSymbol->MaxNameLen = 1024;

		symDisplacement = 0;

		if (SymFromAddr(m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol))
		{
			fprintf(fh, "%hs+%I64X", pSymbol->Name, symDisplacement);
		}
		else
		{
			GetLogicalAddress( (PVOID)sf.AddrPC.Offset, fModule, sizeof(fModule), &section, &offset);

			fprintf(fh, "%04X:%08X %s", section, offset, fModule);
		}

		if (SymGetLineFromAddr( m_hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
		{
			fprintf(fh, "  %s line %u", lineInfo.FileName, lineInfo.LineNumber);
		}
		fprintf(fh, "\n");

		// Consider adding the stuff below at a later date, if it makes sense.
		if (writevars == 1)
		{
			imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
			SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );

			SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &sf );

			fprintf(fh, "\n");
		}
	}
}

/**
 * \brief Dump extra details not included in the minidump to a dump log text
 *        file.
 **/
void GenerateTextDump(PEXCEPTION_POINTERS pExceptionInfo)
{
	EXCEPTION_RECORD *pExceptionRecord = NULL;
	char *temp = NULL;
	char faultingModule[MAX_PATH];
	DWORD section, offset;
	PCONTEXT pCtx = NULL;
	CONTEXT trashableContext;

	temp = (char *)malloc(strlen(dumploc)+10);
	if (temp == NULL) return;   // ACK!  Can't do anything!
	strcpy(temp, dumploc);
	strcat(temp, ".log");

	fh = fopen(temp, "w");
	if (fh == NULL)
	{
		free(temp);
		return;  // Nothing we can do.
	}

	free(temp);
	temp = NULL;

	pExceptionRecord = pExceptionInfo->ExceptionRecord;

	temp = GetExceptionString(pExceptionRecord->ExceptionCode);

	fprintf(fh, "Exception code : %08X -- %s\n", pExceptionRecord->ExceptionCode,
		temp);

	free(temp);
	temp = NULL;

	GetLogicalAddress( pExceptionRecord->ExceptionAddress,
		faultingModule, sizeof(faultingModule), &section, &offset);

	fprintf(fh, "Fault Address: %08X %02X:%08X %s\n", pExceptionRecord->ExceptionAddress,
		section, offset, faultingModule);

	pCtx = pExceptionInfo->ContextRecord;

#ifdef _M_IX86   // Only do this if we are running in an X86 machine.
	fprintf(fh, "\nRegisters :\n");

	fprintf(fh, "EAX:%08X\n", pCtx->Eax);
	fprintf(fh, "EBX:%08X\n", pCtx->Ebx);
	fprintf(fh, "ECX:%08X\n", pCtx->Ecx);
	fprintf(fh, "EDX:%08X\n", pCtx->Edx);
	fprintf(fh, "ESI:%08X\n", pCtx->Esi);
	fprintf(fh, "EDI:%08X\n", pCtx->Edi);

	fprintf(fh, "CS:EIP:%04X:%08X\n", pCtx->SegCs, pCtx->Eip);
	fprintf(fh, "SS:ESP:%04X:%08X  EBP:%08X\n", pCtx->SegSs, pCtx->Esp,
		pCtx->Ebp);
	fprintf(fh, "DS:%04X  ES:%04X  FS:%04X  GS:%04X\n", pCtx->SegDs, pCtx->SegEs,
		pCtx->SegFs, pCtx->SegGs);
	fprintf(fh, "Flags:%08X\n", pCtx->EFlags);
#endif

	SymSetOptions( SYMOPT_DEFERRED_LOADS );

	if (!SymInitialize( GetCurrentProcess(), 0, TRUE ))
	{
		fclose(fh);
		return;
	}

	trashableContext = *pCtx;

	WriteStackDetails(&trashableContext, 0 );

    #ifdef _M_IX86  // X86 Only!

    fprintf(fh, "========================\r\n");
    fprintf(fh, "Local Variables And Parameters\r\n");

    trashableContext = *pCtx;
    WriteStackDetails( &trashableContext, 1 );

#if 0
    fprintf(fh, "========================\r\n");
    fprintf(fh, "Global Variables\r\n");

    SymEnumSymbols( GetCurrentProcess(),
                    (DWORD64)GetModuleHandle(faultingModule),
                    0, EnumerateSymbolsCallback, 0 );
#endif
    #endif      // X86 Only!

    SymCleanup( GetCurrentProcess() );

	fclose(fh);
}

/**
 * \brief The callback that is processed when we experience a crash.
 *
 * @param[in] pExceptionInfo   Information related to the crash, and used to generate the crash information.
 *
 * \retval LONG  A value that tells the windows handler what to do next.
 **/
LONG WINAPI crash_handler_callback(PEXCEPTION_POINTERS pExceptionInfo)
{
	HANDLE hFile;
	MINIDUMP_EXCEPTION_INFORMATION eInfo;

	// Note: BUILDNUM is a quoted string.
	hFile = CreateFileA( dumploc, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		m_hProcess = GetCurrentProcess();
		eInfo.ThreadId = GetCurrentThreadId();
		eInfo.ClientPointers = FALSE;
		eInfo.ExceptionPointers = pExceptionInfo;

		GenerateTextDump(pExceptionInfo);

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

	CloseHandle(hFile);

	crashdump_gather_files();

	if (previousFilter)
		return previousFilter( pExceptionInfo );
	else
		return EXCEPTION_CONTINUE_SEARCH;
}

/**
 * \brief Called at the point that we want to start the crash handler.  (Which is probably the first thing
 *        we want to do.)
 **/
void crash_handler_install(char *dumpname)
{
	dumploc = strdup(dumpname);
	previousFilter = SetUnhandledExceptionFilter(crash_handler_callback);
}

/**
 * \brief Clean up any memory the crash handler was using so that we don't leave droppings.
 **/
void crash_handler_cleanup()
{
	free(dumploc);
}

⌨️ 快捷键说明

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