Beispiel #1
0
unsigned dbgsymengine::symbol(char * buf, unsigned len, unsigned * pdisplacement)
{
	if (!len || !buf || 
		IsBadWritePtr(buf, len) ||
		(pdisplacement && IsBadWritePtr(pdisplacement, sizeof(unsigned))))
		return 0;

	if (!check())
		return 0;

	BYTE symbol [ 512 ] ;
	PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)&symbol;
	memset(pSym, 0, sizeof(symbol)) ;
	pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL) ;
    pSym->MaxNameLength = sizeof(symbol) - sizeof(IMAGEHLP_SYMBOL);

	HANDLE hProc = SymGetProcessHandle();
	DWORD displacement = 0;
	int r = SymGetSymFromAddr(hProc, m_address, &displacement, pSym);
	if (!r) return 0;
	if (pdisplacement) 
		*pdisplacement = displacement;

	r = _snprintf(buf, len, "%s()", pSym->Name);
    
	r = r == -1 ? len - 1 : r;
	buf[r] = 0;	
	return r;
}
Beispiel #2
0
LONG CALLBACK MJCore_Exception_Filter(_EXCEPTION_POINTERS *ex) {
	CodeConv::tostringstream dmsg, lmsg;
#ifdef _MSC_VER
	PIMAGEHLP_SYMBOL pSymbol;
#endif
	DWORD disp;
	ErrorInfo *errinf = nullptr;

	lmsg << _T("ハンドルされていない例外 ") <<
	std::hex << std::setw(8) << std::setfill(_T('0')) << ex->ExceptionRecord->ExceptionCode <<
	_T(" が発生したため、強制終了されます。");
	fatal(lmsg.str().c_str()); dmsg << lmsg.str() << std::endl; lmsg.str(_T(""));

	CONTEXT context; memcpy(&context, ex->ContextRecord, sizeof(CONTEXT));
	switch (ex->ExceptionRecord->ExceptionCode) {
	case EXCEPTION_MJCORE_SUBSCRIPT_OUT_OF_RANGE:
	case EXCEPTION_MJCORE_INVALID_ARGUMENT:
	case EXCEPTION_MJCORE_INVALID_DATA:
	case EXCEPTION_MJCORE_OVERFLOW:
	case EXCEPTION_MJCORE_DECOMPRESSION_FAILURE:
	case EXCEPTION_MJCORE_HASH_MISMATCH:
		errinf = (ErrorInfo *)(ex->ExceptionRecord->ExceptionInformation[0]);
		lmsg << _T(">>> ") << errinf->msg;
		fatal(lmsg.str().c_str()); dmsg << lmsg.str() << std::endl; lmsg.str(_T(""));
#if defined(_MSC_VER) && defined(_DEBUG)
		lmsg << _T(">>> ファイル: ") << errinf->file <<
		_T(" 行: ") << errinf->line <<
		_T(" 関数名: ") << errinf->func;
		fatal(lmsg.str().c_str()); dmsg << lmsg.str() << std::endl; lmsg.str(_T(""));

		pSymbol = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);
		pSymbol->SizeOfStruct = 16384; pSymbol->MaxNameLength = 16384 - sizeof(IMAGEHLP_SYMBOL);
		SymInitialize(GetCurrentProcess(), nullptr, TRUE);
		for (unsigned int i = 0; true; i++) {
			if (i >= ADDRBUF) break;
			if (errinf->traceBack[i] == 0) break;
			if (SymGetSymFromAddr(GetCurrentProcess(), errinf->traceBack[i], &disp, pSymbol))
				lmsg << std::hex << std::setw(8) << std::setfill(_T('0')) << errinf->traceBack[i] <<
				_T(" ") << pSymbol->Name << _T("() + ") <<
				std::setfill(_T('0')) << disp;
			else lmsg << std::hex << std::setw(8) << std::setfill(_T('0')) << errinf->traceBack[i] <<
				_T(" Unknown");
			debug(lmsg.str().c_str()); lmsg.str(_T(""));
		}
		SymCleanup(GetCurrentProcess());
		GlobalFree(pSymbol);
#endif
		break;
#ifdef _MSC_VER
	default:
		traceLog(ex->ContextRecord, nullptr, 0);
#endif
	}

#ifdef _MSC_VER
	terminate();
#else
	abort();
#endif
}
static void dumpFrame(void* processId, void* frameAddr)
{
	MEMORY_BASIC_INFORMATION mbi;
	char moduleName[MAX_PATH];
	HMODULE moduleAddr;
	DWORD symDisplacement;
	IMAGEHLP_SYMBOL* pSymbol;

	if (VirtualQuery(frameAddr, &mbi, sizeof(mbi)))
	{
		moduleName[0] = 0;
		moduleAddr = (HMODULE)mbi.AllocationBase;
		
		GetModuleFileName(moduleAddr, moduleName, MAX_PATH);

		printf("%s(", moduleName);

		if (SymGetSymFromAddr(processId, (uint32_t)frameAddr, &symDisplacement, pSymbol))
			printf("%s", pSymbol->Name);
		else
			printf("<unknown>");

		printf("+0x%X) [0x%08X]\n", (uint32_t)frameAddr - (uint32_t)moduleAddr, frameAddr);

		fflush(stdout);
	}
}
BOOL CallStack::symFunctionInfoFromAddresses(ULONG fnAddress, ULONG stackAddress, /*LPTSTR*/TCHAR * lpszSymbol, 
    UINT BufSizeTCHARs)
{
    stackAddress;

    DWORD             dwDisp    = 0;

    ::ZeroMemory(m_pSymbol, m_dwsymBufSize );
    m_pSymbol->SizeOfStruct     = m_dwsymBufSize;
    m_pSymbol->MaxNameLength    = m_dwsymBufSize - sizeof(IMAGEHLP_SYMBOL);
    // Set the default to unknown
    _tcscpy_s( lpszSymbol, BufSizeTCHARs, MLD_TRACEINFO_NOSYMBOL);

    // Get symbol info for IP
    if ( SymGetSymFromAddr( m_hProcess, (ULONG)fnAddress, &dwDisp, m_pSymbol ) )
    {
#ifdef UNICODE
        int len = strlen(m_pSymbol->Name) + 1 ;
        wchar_t dest[1024] = {};
        MultiByteToWideChar(CP_ACP, 0, m_pSymbol->Name, len, dest, len );
        _tcscpy_s(lpszSymbol, BufSizeTCHARs, dest);
#else
        _tcscpy_s(lpszSymbol, BufSizeTCHARs, m_pSymbol->Name);
#endif
        return TRUE;
    }

    //create the symbol using the address because we have no symbol
    _stprintf_s(lpszSymbol, BufSizeTCHARs, _T("0x%08X"), fnAddress);
    return FALSE;
}
Beispiel #5
0
BOOL AddressToName(DWORD Addr, LPTSTR Str, int Max)
{
	DWORD base;
	if (!InitialiseImageHelp())
		return FALSE;
	base = SymGetModuleBase(s_hProcess, Addr);
	if (base)
	{
		struct
		{
			IMAGEHLP_SYMBOL ihs;
			char NameBuf[256];
		} SymInfo;
		DWORD Displacement = 0;
		SymInfo.ihs.SizeOfStruct = sizeof(SymInfo);
		SymInfo.ihs.MaxNameLength = sizeof(SymInfo.NameBuf);
		if (SymGetSymFromAddr(s_hProcess, Addr, &Displacement, &SymInfo.ihs))
		{
			if (Displacement)
				_snprintf(Str, Max-1, "%s+%x", SymInfo.ihs.Name, Displacement);
			else
				_snprintf(Str, Max-1, "%s", SymInfo.ihs.Name);
			return TRUE;
		}
		else
		{
			_snprintf(Str, Max, "SymGetSymFromAddr failed (%d)", GetLastError());
		}
	}
	else
	{
		_snprintf(Str, Max, "SymGetModuleBase failed (%d)", GetLastError());
	}
	return FALSE;
}
Beispiel #6
0
BOOL CMemLeakDetect::symFunctionInfoFromAddresses( ADDR fnAddress, ADDR stackAddress, TCHAR *lpszSymbol,
													UINT BufSizeTCHARs)
{
	ADDR             dwDisp	= 0;
	::ZeroMemory(m_pSymbol, m_dwsymBufSize );
	m_pSymbol->SizeOfStruct		= m_dwsymBufSize;
	m_pSymbol->MaxNameLength =   MLD_MAX_NAME_LENGTH;
	//	= DWORD64 - sizeof(IMAGEHLP_SYMBOL64);
    // Set the default to unknown
	_tcscpy_s( lpszSymbol, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL);
	// Get symbol info for IP
	if ( SymGetSymFromAddr( m_hProcess, (ADDR)fnAddress, &dwDisp, m_pSymbol ) )
	{
#ifdef UNICODE
		int len = (int)strlen(m_pSymbol->Name) + 1 ;
		wchar_t dest[1024] ;
		MultiByteToWideChar(CP_ACP, 0, m_pSymbol->Name, len, dest, len );
		_tcscpy_s(lpszSymbol, BufSizeTCHARs, dest);
#else
		_tcscpy_s(lpszSymbol, BufSizeTCHARs, m_pSymbol->Name);
#endif
		return TRUE;
	}
	//create the symbol using the address because we have no symbol
	_stprintf_s(lpszSymbol, BufSizeTCHARs, _T("0x%08X"), fnAddress);
	return FALSE;
}
void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss)
{
    PIMAGEHLP_SYMBOL pSym;
    STACKFRAME sf;
    HANDLE process, thread;
    ULONG_PTR dwModBase, Disp;
    BOOL more = FALSE;
    DWORD machineType;
    int count = 0;
    char modname[MAX_PATH];
    char symBuffer[sizeof(IMAGEHLP_SYMBOL) + 255];

    pSym = (PIMAGEHLP_SYMBOL)symBuffer;

    ZeroMemory(&sf, sizeof(sf));
#ifdef _WIN64
    sf.AddrPC.Offset = e->ContextRecord->Rip;
    sf.AddrStack.Offset = e->ContextRecord->Rsp;
    sf.AddrFrame.Offset = e->ContextRecord->Rbp;
    machineType = IMAGE_FILE_MACHINE_AMD64;
#else
    sf.AddrPC.Offset = e->ContextRecord->Eip;
    sf.AddrStack.Offset = e->ContextRecord->Esp;
    sf.AddrFrame.Offset = e->ContextRecord->Ebp;
    machineType = IMAGE_FILE_MACHINE_I386;
#endif

    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrStack.Mode = AddrModeFlat;
    sf.AddrFrame.Mode = AddrModeFlat;

    process = GetCurrentProcess();
    thread = GetCurrentThread();

    while(1) {
        more = StackWalk(machineType,  process, thread, &sf, e->ContextRecord, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL);
        if(!more || sf.AddrFrame.Offset == 0)
            break;

        dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset);
        if(dwModBase)
            GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH);
        else
            strcpy(modname, "Unknown");

        Disp = 0;
        pSym->SizeOfStruct = sizeof(symBuffer);
        pSym->MaxNameLength = 254;

        if(SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym))
            ss << stdext::format("    %d: %s(%s+%#0lx) [0x%016lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
        else
            ss << stdext::format("    %d: %s [0x%016lX]\n", count, modname, sf.AddrPC.Offset);
        ++count;
    }
    GlobalFree(pSym);
}
Beispiel #8
0
BOOL
CmdStackTrace(
    LPSTR             CmdBuf,
    HANDLE            hProcess,
    HANDLE            hThread,
    PEXCEPTION_RECORD ExceptionRecord
    )
{
    CONTEXT     Context;
    STACKFRAME  StackFrame = {0};
    BOOL        rVal = FALSE;



    CopyMemory( &Context, &CurrContext, sizeof(CONTEXT) );

#if defined(_M_IX86)
    StackFrame.AddrPC.Offset       = Context.Eip;
    StackFrame.AddrPC.Mode         = AddrModeFlat;
    StackFrame.AddrFrame.Offset    = Context.Ebp;
    StackFrame.AddrFrame.Mode      = AddrModeFlat;
    StackFrame.AddrStack.Offset    = Context.Esp;
    StackFrame.AddrStack.Mode      = AddrModeFlat;
#endif

    printf( "\n" );
    do {
        rVal = StackWalk(
            MACHINE_TYPE,
            hProcess,
            0,
            &StackFrame,
            &Context,
            ReadProcessMemory,
            SymFunctionTableAccess,
            SymGetModuleBase,
            NULL
            );
        if (rVal) {
            ULONG Displacement;
            printf( "%08x %08x ",
                StackFrame.AddrFrame.Offset,
                StackFrame.AddrReturn.Offset
                );
            if (SymGetSymFromAddr( hProcess, StackFrame.AddrPC.Offset, &Displacement, sym )) {
                printf( "%s\n", sym->Name );
            } else {
                printf( "0x%08x\n", StackFrame.AddrPC.Offset );
            }
        }
    } while( rVal );

    printf( "\n" );

    return TRUE;
}
Beispiel #9
0
void stack_walk(CString& strStack, PCONTEXT p_context)
{ 

	CONTEXT * pContext = p_context;

	HANDLE hCurrentProcess = ::GetCurrentProcess();
	HANDLE hCurrentThread  = ::GetCurrentThread();

	STACKFRAME64 sStackFrame;
	memset(&sStackFrame,0,sizeof(STACKFRAME64));

	sStackFrame.AddrPC.Offset	= pContext->Eip;
	sStackFrame.AddrPC.Mode		= AddrModeFlat;
	sStackFrame.AddrStack.Offset= pContext->Esp;
	sStackFrame.AddrStack.Mode	= AddrModeFlat;
	sStackFrame.AddrFrame.Offset= pContext->Ebp;
	sStackFrame.AddrFrame.Mode	= AddrModeFlat;

	USES_CONVERSION;

	//TCHAR atszCallbackBuffer[1024];
	//DWORD dwLen = 0;

	SymInitialize(GetCurrentProcess(),NULL,TRUE);

	while(StackWalk64(IMAGE_FILE_MACHINE_I386,hCurrentProcess,hCurrentThread,&sStackFrame,pContext,0,0,0,0))
	{
		if( sStackFrame.AddrFrame.Offset == 0 )
		{
			break;
		}

		strStack.Format(L"%s[%08X]", strStack,sStackFrame.AddrPC.Offset);

		BYTE sym_buffer[sizeof(IMAGEHLP_SYMBOL) + 512];
		PIMAGEHLP_SYMBOL p_symbol = (PIMAGEHLP_SYMBOL)sym_buffer;
		p_symbol->SizeOfStruct = sizeof(sym_buffer);
		p_symbol->MaxNameLength = 512;

		// Displacement of the input address, relative to the start of the symbol
		DWORD sym_displacement = 0;  
		if (!SymGetSymFromAddr(::GetCurrentProcess(), sStackFrame.AddrPC.Offset, &sym_displacement, p_symbol))
		{
			p_symbol->Name[0] = 0;
		}
		TCHAR sz_module[MAX_PATH] = {0};
		UINT_PTR section = 0, offset = 0;
		get_logical_address((PVOID)(UINT_PTR)sStackFrame.AddrPC.Offset, sz_module, sizeof(sz_module));

		strStack.Format(L"%s\t%s\t%s\r\n",strStack,A2T(p_symbol->Name),sz_module);

	}

	SymCleanup(GetCurrentProcess());
}
Beispiel #10
0
void KImageModule::ShowSysCallTable(const char * tablename, unsigned base)
{
	const IMAGEHLP_SYMBOL * pSymbol = ImageGetSymbol(tablename);

	if ( pSymbol==NULL )
		Output("Unable to locate symbol %s\n", tablename);
	else
	{
		int count = base;

		const unsigned * p = (const unsigned *) Address2ImagePointer(pSymbol->Address);

		while ( ! IsBadReadPtr(p, sizeof(unsigned)) )
		{
			unsigned q = * p;

			if ( q > (unsigned) (m_image.FileHeader->OptionalHeader.ImageBase) )
			{
				DWORD           displacement;
			//	IMAGEHLP_SYMBOL symbol;

			    memset(m_is, 0, sizeof(m_is));
			    m_is[0].SizeOfStruct  = sizeof(IMAGEHLP_SYMBOL);
				m_is[0].MaxNameLength = sizeof(m_is) - sizeof(m_is[0]);
    
				unsigned q1 = q;

				// W2k RC1 imagehlp does not need translation
				if ( m_symbolbase )
					q1 = q1 - m_imagebase_default + m_symbolbase;

        		if ( SymGetSymFromAddr(m_hProcess, q1, & displacement, m_is) )
				{
					IMAGEHLP_LINE line;

					line.SizeOfStruct = sizeof(line);

					if ( SymGetLineFromAddr(m_hProcess, q1, & displacement, & line) )
					{
					}

					Output("syscall(%4x) %s\n", count, m_is[0].Name);
					count ++;
				}
			}
			else
				break;
			p++;
		}

		Output("%d system calls found\n", count - base);
	}
}
DWORD CCallStackTrace::ConvertAddress(HANDLE hProcess, DWORD address, LPSTR output_buffer)
{
	char* current_pointer = output_buffer;
	IMAGEHLP_MODULE imagehlp_module;
	memset(&imagehlp_module, 0, sizeof(imagehlp_module));
	imagehlp_module.SizeOfStruct = sizeof(imagehlp_module);

	if ( SymGetModuleInfo(hProcess, address, &imagehlp_module) != FALSE )
	{
		char * image_name = strrchr(imagehlp_module.ImageName, '\\');

		if ( image_name != NULL )
			image_name += 1;
		else
			image_name = imagehlp_module.ImageName;

		current_pointer += sprintf(current_pointer, "%s : ", image_name);
	}
	else
	{
		current_pointer += sprintf(current_pointer, "<unknown module> : ");
	}

	DWORD displacement;
	char temp[0x11c];
	IMAGEHLP_SYMBOL * imagehlp_symbol = (IMAGEHLP_SYMBOL *)temp;
	memset(imagehlp_symbol, 0, sizeof(temp));
	imagehlp_symbol->SizeOfStruct = 24;
	imagehlp_symbol->Address = address;
	imagehlp_symbol->MaxNameLength = 0x104;

	if ( SymGetSymFromAddr(hProcess, address, &displacement, imagehlp_symbol) != FALSE )
	{
		current_pointer += sprintf(current_pointer, "%s() ", imagehlp_symbol->Name);

		IMAGEHLP_LINE imagehlp_line;
		memset(&imagehlp_line, 0, sizeof(imagehlp_line));
		imagehlp_line.SizeOfStruct = sizeof(IMAGEHLP_LINE);

		if ( SymGetLineFromAddr(hProcess, address, &displacement, &imagehlp_line) != FALSE )
		{
			current_pointer += sprintf(current_pointer, "// %s(%i)", imagehlp_line.FileName, imagehlp_line.LineNumber);
		}
	}
	else
	{
		current_pointer += sprintf(current_pointer, "<unknown symbol>");
	}
	
	current_pointer += sprintf(current_pointer, "\r\n");
	return current_pointer - output_buffer;
}
/*
==================
Sym_GetFuncInfo
==================
*/
void Sym_GetFuncInfo( long addr, idStr &module, idStr &funcName )
{
    MEMORY_BASIC_INFORMATION mbi;

    VirtualQuery( (void*)addr, &mbi, sizeof(mbi) );

    if ( (DWORD) mbi.AllocationBase != lastAllocationBase )
    {
        Sym_Init( addr );
    }

    BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + MAX_STRING_CHARS ];
    PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)&symbolBuffer[0];
    pSymbol->SizeOfStruct = sizeof(symbolBuffer);
    pSymbol->MaxNameLength = 1023;
    pSymbol->Address = 0;
    pSymbol->Flags = 0;
    pSymbol->Size =0;

    DWORD symDisplacement = 0;
    if ( SymGetSymFromAddr( processHandle, addr, &symDisplacement, pSymbol ) )
    {
        // clean up name, throwing away decorations that don't affect uniqueness
        char undName[MAX_STRING_CHARS];
        if ( UnDecorateSymbolName( pSymbol->Name, undName, sizeof(undName), UNDECORATE_FLAGS ) )
        {
            funcName = undName;
        }
        else
        {
            funcName = pSymbol->Name;
        }
        module = lastModule;
    }
    else
    {
        LPVOID lpMsgBuf;
        FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                       NULL,
                       GetLastError(),
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                       (LPTSTR) &lpMsgBuf,
                       0,
                       NULL
                     );
        LocalFree( lpMsgBuf );

        // Couldn't retrieve symbol (no debug info?, can't load dbghelp.dll?)
        sprintf( funcName, "0x%08x", addr );
        module = "";
    }
}
Beispiel #13
0
void CallStack::getFuncInfo(LPVOID dwFunc, FuncInfo& info)
{
    memset(szBuffer, 0, sizeof(szBuffer));
#ifdef WIN32
#ifdef X64
    PIMAGEHLP_SYMBOL64 symbol = (PIMAGEHLP_SYMBOL64)szBuffer;
    symbol->SizeOfStruct  = sizeof(szBuffer);
    symbol->MaxNameLength = sizeof(szBuffer) - sizeof(IMAGEHLP_SYMBOL64);

    DWORD64 dwDisplacement = 0;

    if (SymGetSymFromAddr64(hProcess, (DWORD)dwFunc, &dwDisplacement, symbol))
    {
        strncpy(info.szFuncName, symbol->Name, min(sizeof(info.szFuncName) - 1, strlen(symbol->Name)));
        info.szFuncName[min(sizeof(info.szFuncName) - 1, strlen(symbol->Name))] = 0;
    }

    IMAGEHLP_LINE64 imageHelpLine;
    imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);

    if (SymGetLineFromAddr64(hProcess, (DWORD)dwFunc, (PDWORD)&dwDisplacement, &imageHelpLine))
    {
        strncpy(info.szFilePath, imageHelpLine.FileName, min(sizeof(info.szFilePath) - 1, strlen(imageHelpLine.FileName)));
        info.szFilePath[min(sizeof(info.szFilePath) - 1, strlen(imageHelpLine.FileName))] = 0;
        info.dwLineNumber = imageHelpLine.LineNumber;
    }
#else
    PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL)szBuffer;
    symbol->SizeOfStruct  = sizeof(szBuffer);
    symbol->MaxNameLength = sizeof(szBuffer) - sizeof(IMAGEHLP_SYMBOL);

    DWORD dwDisplacement = 0;

    if (SymGetSymFromAddr(hProcess, (DWORD)dwFunc, &dwDisplacement, symbol))
    {
        strncpy(info.szFuncName, symbol->Name, min(sizeof(info.szFuncName) - 1, strlen(symbol->Name)));
        info.szFuncName[min(sizeof(info.szFuncName) - 1, strlen(symbol->Name))] = 0;
    }

    IMAGEHLP_LINE imageHelpLine;
    imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);

    if (SymGetLineFromAddr(hProcess, (DWORD)dwFunc, &dwDisplacement, &imageHelpLine))
    {
        strncpy(info.szFilePath, imageHelpLine.FileName, min(sizeof(info.szFilePath) - 1, strlen(imageHelpLine.FileName)));
        info.szFilePath[min(sizeof(info.szFilePath) - 1, strlen(imageHelpLine.FileName))] = 0;
        info.dwLineNumber = imageHelpLine.LineNumber;
    }
#endif
#endif
}
Beispiel #14
0
void traceLog(CONTEXT* ex, int* const addrList, int addrListSize) {
#ifdef _DEBUG
#ifdef _M_IX86
	/* スタックトレース(I386専用です) */
	CodeConv::tostringstream lmsg;
	if (addrList != nullptr) memset(addrList, 0, addrListSize);

	HANDLE hProcess = GetCurrentProcess();
	DWORD disp;
	HANDLE hThread = GetCurrentThread();

	PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);
	pSymbol->SizeOfStruct = 16384; pSymbol->MaxNameLength = 16384 - sizeof(IMAGEHLP_SYMBOL);
	SymInitialize(GetCurrentProcess(), nullptr, TRUE);

	STACKFRAME stackFrame; memset(&stackFrame, 0, sizeof(stackFrame));
	stackFrame.AddrPC.Offset = ex->Eip;
	stackFrame.AddrFrame.Offset = ex->Ebp;
	stackFrame.AddrStack.Offset = ex->Esp;
	stackFrame.AddrPC.Mode = stackFrame.AddrFrame.Mode =
		stackFrame.AddrStack.Mode = AddrModeFlat;

	CONTEXT context;
	memcpy(&context,  ex, sizeof(CONTEXT));
	context.ContextFlags = CONTEXT_FULL;

	for (unsigned int i = 0; true; i++) {
		if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread,
			&stackFrame, &context, nullptr, SymFunctionTableAccess, SymGetModuleBase, nullptr)) break;
		if (stackFrame.AddrPC.Offset == 0) break;

		if (addrList != nullptr) {
			addrList[i] = stackFrame.AddrPC.Offset;
			if (i >= (addrListSize / sizeof(int))) break;
		} else {
			if (SymGetSymFromAddr(hProcess, stackFrame.AddrPC.Offset, &disp, pSymbol))
				lmsg << std::hex << std::setw(8) << std::setfill(_T('0')) << stackFrame.AddrPC.Offset <<
				_T(" ") << pSymbol->Name << _T("() + ") <<
				std::setfill(_T('0')) << disp;
			else lmsg << std::hex << std::setw(8) << std::setfill(_T('0')) << stackFrame.AddrPC.Offset <<
				_T(" Unknown");
			debug(lmsg.str().c_str()); lmsg.str(_T(""));
		}
	}
	
	SymCleanup(hProcess);
	GlobalFree(pSymbol);
#endif
#endif
}
void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss)
{
    PIMAGEHLP_SYMBOL pSym;
    STACKFRAME sf;
    HANDLE process, thread;
    DWORD dwModBase, Disp;
    BOOL more = FALSE;
    int count = 0;
    char modname[MAX_PATH];

    pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);

    ZeroMemory(&sf, sizeof(sf));
    sf.AddrPC.Offset = e->ContextRecord->Eip;
    sf.AddrStack.Offset = e->ContextRecord->Esp;
    sf.AddrFrame.Offset = e->ContextRecord->Ebp;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrStack.Mode = AddrModeFlat;
    sf.AddrFrame.Mode = AddrModeFlat;

    process = GetCurrentProcess();
    thread = GetCurrentThread();

    while(1) {
        more = StackWalk(IMAGE_FILE_MACHINE_I386,  process, thread, &sf, e->ContextRecord, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL);
        if(!more || sf.AddrFrame.Offset == 0)
            break;

        dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset);
        if(dwModBase)
            GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH);
        else
            strcpy(modname, "Unknown");

        pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
        pSym->MaxNameLength = MAX_PATH;

        if(SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym))
            ss << stdext::format("    %d: %s(%s+%#0lx) [0x%08lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
        else
            ss << stdext::format("    %d: %s [0x%08lX]\n", count, modname, sf.AddrPC.Offset);
        ++count;
    }
    GlobalFree(pSym);
}
Beispiel #16
0
size_t
DisAddrToSymbol(
    struct DIS  *pdis,
    ULONG       addr,
    char        *buf,
    size_t      bufsize,
    DWORD       *displacement
    )
{
    if (SymGetSymFromAddr( CurrProcess, addr, displacement, sym )) {
        strncpy( buf, sym->Name, bufsize );
    } else {
        *displacement = 0;
        buf[0] = 0;
    }

    return strlen(buf);
}
Beispiel #17
0
void StackTrack_x86(PCSTR dir, DWORD dwEIP, DWORD dwEBP, DWORD dwESP)
{
	HANDLE hHandle = NULL;
	HANDLE hThread = NULL;
	PIMAGEHLP_SYMBOL pSymInfo = NULL;
	CONTEXT context = {0};
	STACKFRAME sf = { 0 };
	DWORD dwDisplament = 0;
	IMAGEHLP_LINE ImageLine = { 0 };

	hHandle = GetCurrentProcess();
	hThread = GetCurrentThread();
	SymInitialize(hHandle, dir, TRUE);

	pSymInfo = (PIMAGEHLP_SYMBOL)malloc(sizeof(IMAGEHLP_SYMBOL) + MAX_PATH);
	if (pSymInfo == NULL)
	{
		return ;
	}
	
	context.Eip = dwEIP;
	context.Ebp = dwEBP;
	context.Esp = dwESP;

	sf.AddrPC.Mode = AddrModeFlat;		//EIP
	sf.AddrFrame.Mode = AddrModeFlat;	//EBP
	sf.AddrStack.Mode = AddrModeFlat;	//ESP

	pSymInfo->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	pSymInfo->MaxNameLength = MAX_PATH;
	ImageLine.SizeOfStruct = sizeof(IMAGEHLP_LINE);

	while (StackWalk(IMAGE_FILE_MACHINE_I386, hHandle, hThread, &sf, &context, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL))
	{
		SymGetSymFromAddr(hHandle, sf.AddrPC.Offset, &dwDisplament, pSymInfo);
		SymGetLineFromAddr(hHandle, sf.AddrPC.Offset, &dwDisplament, &ImageLine);
		printf("%08x %s():%s(%d)\n", pSymInfo->Address, pSymInfo->Name, ImageLine.FileName, ImageLine.LineNumber);
	}
	free(pSymInfo);

	SymCleanup(hHandle);
}
Beispiel #18
0
void StackTraceUtils::Impl::getSymbolName(
		StackTraceHandler &handler, void *address) {
#ifdef _WIN64
	typedef DWORD64 DWORDX;
#else
	typedef DWORD DWORDX;
#endif

	HANDLE process = ::GetCurrentProcess();
	if (!process) {
		handler("", -1);
		return;
	}

	IMAGEHLP_MODULE imageModule = { sizeof(IMAGEHLP_MODULE) };
	IMAGEHLP_LINE line ={ sizeof(IMAGEHLP_LINE) };
	DWORDX dispSym = 0;
	DWORD dispLine = 0;

	char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + MAX_PATH] = {0};
	IMAGEHLP_SYMBOL * imageSymbol = (IMAGEHLP_SYMBOL*) symbolBuffer;
	imageSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	imageSymbol->MaxNameLength = MAX_PATH;

	const DWORDX intAddress =
			static_cast<DWORDX>(reinterpret_cast<uintptr_t>(address));
	if(!SymGetModuleInfo(process, intAddress, &imageModule)) {
		util::detail::RawNumberFormatter formatter;
		handler(formatter(static_cast<uint64_t>(intAddress)), -1);
	}
	else if(!SymGetSymFromAddr(process, intAddress, &dispSym, imageSymbol)) {
		
		util::detail::RawNumberFormatter formatter;
		handler(formatter(static_cast<uint64_t>(intAddress)), -1);
	}
	else if(!SymGetLineFromAddr(process, intAddress, &dispLine, &line)) {
		handler(imageSymbol->Name, -1);
	}
	else {
		handler(imageSymbol->Name, line.LineNumber);
	}
}
Beispiel #19
0
BOOL
CmdListNear(
    LPSTR             CmdBuf,
    HANDLE            hProcess,
    HANDLE            hThread,
    PEXCEPTION_RECORD ExceptionRecord
    )
{
    SKIP_NONWHITE( CmdBuf );
    SKIP_WHITE( CmdBuf );

    ULONG Address;
    GetAddress( CmdBuf, &Address );
    if (Address) {
        ULONG Displacement;
        if (SymGetSymFromAddr( hProcess, Address, &Displacement, sym )) {
            printf( "0x%08x %s\n", sym->Address, sym->Name );
        }
    }
    return TRUE;
}
Beispiel #20
0
size_t GetSymbolNameFromAddress(void* address, char* symbolName, size_t size,
                                size_t* offsetBytes)
{
    if (size) *symbolName = 0;
    if (offsetBytes) *offsetBytes = 0;
    __try {
        ULONG_ADDR dwOffset = 0;
        union {
            IMAGEHLP_SYMBOL sym;
            char symNameBuffer[sizeof(IMAGEHLP_SYMBOL) + MAX_SYM_NAME];
        } u;
        u.sym.SizeOfStruct  = sizeof(u.sym);
        u.sym.MaxNameLength = sizeof(u.symNameBuffer) - sizeof(u.sym);

        if (!SymGetSymFromAddr(GetSymHandle(), CheckAddress(address), &dwOffset,
                               &u.sym)) {
            return 0;
        } else {
            const char* sourceName = u.sym.Name;
            char undName[1024];
            if (UnDecorateSymbolName(u.sym.Name, undName, sizeof(undName),
                                     UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS)) {
                sourceName = undName;
            } else if (SymUnDName(&u.sym, undName, sizeof(undName))) {
                sourceName = undName;
            }
            if (offsetBytes) {
                *offsetBytes = dwOffset;
            }
            if (size) {
                strncpy(symbolName, sourceName, size)[size - 1] = 0;
            }
            return strlen(sourceName);
        }
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        SetLastError(GetExceptionCode());
    }
    return 0;
}
static bool DumpFrame(void *process, DWORD_PTR frameAddress)
{
	const int functionLength = 255;
	IMAGEHLP_SYMBOL *symbol = (IMAGEHLP_SYMBOL*)malloc(sizeof(IMAGEHLP_SYMBOL) + functionLength);
	DWORD_PTR moduleBase = SymGetModuleBase(process, frameAddress);
	const char *moduleName = NULL, *functionName = NULL;
	DWORD_PTR displacement;
	char moduleFilename[MAX_PATH];

	symbol->SizeOfStruct = (sizeof(*symbol)) + functionLength;
	symbol->MaxNameLength = functionLength - 1;

	if (moduleBase && GetModuleFileName((HINSTANCE)moduleBase, moduleFilename, MAX_PATH))
		moduleName = moduleFilename;

	if (SymGetSymFromAddr(process, frameAddress, &displacement, symbol))
		functionName = symbol->Name;

	PrintFunction(moduleName, functionName, frameAddress, displacement);

	free(symbol);
}
Beispiel #22
0
size_t
DisFixupToSymbol(
    struct DIS  *pdis,
    ULONG       addr,
    size_t      fixup,
    char        *buf,
    size_t      bufsize,
    DWORD       *displacement
    )
{
    if (!ReadMemory( CurrProcess, (PVOID)addr, &addr, 4 )) {
        *displacement = 0;
        return 0;
    }

    if (SymGetSymFromAddr( CurrProcess, addr, displacement, sym )) {
        strncpy( buf, sym->Name, bufsize );
    } else {
        *displacement = 0;
        buf[0] = 0;
    }

    return strlen(buf);
}
Beispiel #23
0
	//*************************************************************************
	// Method:		GetStackInfo
	// Description: Gets the call stack for the specified thread
	//
	// Parameters:
	//	hThread - the handle to the target thread
	//	threadContext - the context of the target thread
	//
	// Return Value: (FrameInfo *) An array containing stack trace data
	//*************************************************************************
	SiUtils::SiArray <FrameInfo *> StackWalker::GetStackInfo(HANDLE hThread, CONTEXT &threadContext)
	{
		//Clear the frame array of any previous data
		frameArray.Clear();

		DWORD imageType = IMAGE_FILE_MACHINE_I386;
		HANDLE hProcess = GetCurrentProcess();
		
		int frameNum;						// counts walked frames
		DWORD offsetFromSymbol;				// tells us how far from the symbol we were
		DWORD symOptions;					// symbol handler settings
		IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *) malloc( IMGSYMLEN + MAXNAMELEN );
		char undName[MAXNAMELEN];			// undecorated name
		char undFullName[MAXNAMELEN];		// undecorated name with all shenanigans
		IMAGEHLP_MODULE Module;
		IMAGEHLP_LINE Line;
		std::string symSearchPath;
		char *tt = 0, *p;

		STACKFRAME s;						// in/out stackframe
		memset( &s, '\0', sizeof s );

		tt = new char[TTBUFLEN];
		// build symbol search path from:
		symSearchPath = "";
		// current directory
		if (GetCurrentDirectory(TTBUFLEN, tt ))
			symSearchPath += tt + std::string( ";" );
		
		// dir with executable
		if (GetModuleFileName(0, tt, TTBUFLEN))
		{
			for ( p = tt + strlen( tt ) - 1; p >= tt; -- p )
			{
				// locate the rightmost path separator
				if ( *p == '\\' || *p == '/' || *p == ':' )
					break;
			}
			
			if ( p != tt )
			{
				if ( *p == ':' ) // we leave colons in place
					++ p;
				*p = '\0'; // eliminate the exe name and last path sep
				symSearchPath += tt + std::string( ";" );
			}
		}
		
		// environment variable _NT_SYMBOL_PATH
		if ( GetEnvironmentVariable( "_NT_SYMBOL_PATH", tt, TTBUFLEN ) )
			symSearchPath += tt + std::string( ";" );
		// environment variable _NT_ALTERNATE_SYMBOL_PATH
		if ( GetEnvironmentVariable( "_NT_ALTERNATE_SYMBOL_PATH", tt, TTBUFLEN ) )
			symSearchPath += tt + std::string( ";" );
		// environment variable SYSTEMROOT
		if ( GetEnvironmentVariable( "SYSTEMROOT", tt, TTBUFLEN ) )
			symSearchPath += tt + std::string( ";" );

		if ( symSearchPath.size() > 0 ) // if we added anything, we have a trailing semicolon
			symSearchPath = symSearchPath.substr( 0, symSearchPath.size() - 1 );

		strncpy( tt, symSearchPath.c_str(), TTBUFLEN );
		tt[TTBUFLEN - 1] = '\0'; // if strncpy() overruns, it doesn't add the null terminator

		// init symbol handler stuff (SymInitialize())
		if (!SymInitialize(hProcess, tt, false ))
			goto cleanup;

		// SymGetOptions()
		symOptions = SymGetOptions();
		symOptions |= SYMOPT_LOAD_LINES;
		symOptions &= ~SYMOPT_UNDNAME;
		SymSetOptions( symOptions );

		// Enumerate modules and tell imagehlp.dll about them.
		enumAndLoadModuleSymbols( hProcess, GetCurrentProcessId() );

		// init STACKFRAME for first call
		// Notes: AddrModeFlat is just an assumption. I hate VDM debugging.
		// Notes: will have to be #ifdef-ed for Alphas; MIPSes are dead anyway,
		// and good riddance.
		s.AddrPC.Offset = threadContext.Eip;
		s.AddrPC.Mode = AddrModeFlat;
		s.AddrFrame.Offset = threadContext.Ebp;
		s.AddrFrame.Mode = AddrModeFlat;

		memset( pSym, '\0', IMGSYMLEN + MAXNAMELEN );
		pSym->SizeOfStruct = IMGSYMLEN;
		pSym->MaxNameLength = MAXNAMELEN;

		memset( &Line, '\0', sizeof Line );
		Line.SizeOfStruct = sizeof Line;

		memset( &Module, '\0', sizeof Module );
		Module.SizeOfStruct = sizeof Module;

		offsetFromSymbol = 0;

		for ( frameNum = 0; ; ++ frameNum )
		{
			FrameInfo * frameInfo = new FrameInfo();

			if (!StackWalk( imageType, hProcess, hThread, &s, &threadContext, NULL,
				SymFunctionTableAccess, SymGetModuleBase, NULL ) )
				break;

			frameInfo->frameNumber = frameNum;
			frameInfo->IsWOWFarCall = s.Far;
			frameInfo->IsVirtualFrame = s.Virtual;
			frameInfo->Eip = s.AddrPC.Offset;				//if 0, the no symbols
			frameInfo->ReturnAddr = s.AddrReturn.Offset;
			frameInfo->FramePtr = s.AddrFrame.Offset;
			frameInfo->StackPtr = s.AddrStack.Offset;

			if (s.AddrPC.Offset == 0)
			{
				//printf( "(-nosymbols- PC == 0)\n" );
			}
			else
			{ // we seem to have a valid PC
				// show procedure info (SymGetSymFromAddr())
				if ( ! SymGetSymFromAddr( hProcess, s.AddrPC.Offset, &offsetFromSymbol, pSym ) )
				{
					/*if ( GetLastError() != 487 )
						printf( "SymGetSymFromAddr(): GetLastError() = %lu\n", GetLastError() );*/
				}
				else
				{
					// UnDecorateSymbolName()
					UnDecorateSymbolName( pSym->Name, undName, MAXNAMELEN, UNDNAME_NAME_ONLY );
					UnDecorateSymbolName( pSym->Name, undFullName, MAXNAMELEN, UNDNAME_COMPLETE );

					strcpy (frameInfo->undecoratedName, undName);
					strcpy (frameInfo->undecoratedFullName, undFullName);
					strcpy (frameInfo->signature, pSym->Name );
					frameInfo->offsetFromSymbol = offsetFromSymbol;
				}

				// show module info (SymGetModuleInfo())
				if (SymGetModuleInfo( hProcess, s.AddrPC.Offset, &Module ) )
				{	
					strcpy (frameInfo->ModuleName, Module.ModuleName);
					strcpy (frameInfo->ImageName, Module.ImageName);
					frameInfo->BaseOfImage = Module.BaseOfImage;

				}

			} // we seem to have a valid PC

			// no return address means no deeper stackframe
			if ( s.AddrReturn.Offset == 0 )
			{
				// avoid misunderstandings in the printf() following the loop
				SetLastError( 0 );
				break;
			}
			
			this->frameArray.Add (frameInfo);

		} // for ( frameNum )

	cleanup:
		// de-init symbol handler etc. (SymCleanup())
		SymCleanup( hProcess );
		free( pSym );
		delete [] tt;
		return frameArray;
	}
/** Print out a stacktrace. */
static void Stacktrace(const char *threadName, LPEXCEPTION_POINTERS e, HANDLE hThread = INVALID_HANDLE_VALUE)
{
	PIMAGEHLP_SYMBOL pSym;
	STACKFRAME sf;
	HANDLE process, thread;
	DWORD dwModBase, Disp, dwModAddrToPrint;
	BOOL more = FALSE;
	int count = 0;
	char modname[MAX_PATH];

	process = GetCurrentProcess();

	if(threadName)
		PRINT("Stacktrace (%s):", threadName);
	else
		PRINT("Stacktrace:");

	bool suspended = false;
	CONTEXT c;
	if (e) {
		c = *e->ContextRecord;
		thread = GetCurrentThread();
	} else {
		SuspendThread(hThread);
		suspended = true;
		memset(&c, 0, sizeof(CONTEXT));
		c.ContextFlags = CONTEXT_FULL;
		// FIXME: This does not work if you want to dump the current thread's stack
		if (!GetThreadContext(hThread, &c)) {
			ResumeThread(hThread);
			return;
		}
		thread = hThread;
	}
	ZeroMemory(&sf, sizeof(sf));
	sf.AddrPC.Offset = c.Eip;
	sf.AddrStack.Offset = c.Esp;
	sf.AddrFrame.Offset = c.Ebp;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrStack.Mode = AddrModeFlat;
	sf.AddrFrame.Mode = AddrModeFlat;

	// use globalalloc to reduce risk for allocator related deadlock
	pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);
	char* printstrings = (char*)GlobalAlloc(GMEM_FIXED, 0);

	bool containsOglDll = false;
	while (true) {
		more = StackWalk(
			IMAGE_FILE_MACHINE_I386, // TODO: fix this for 64 bit windows?
			process,
			thread,
			&sf,
			&c,
			NULL,
			SymFunctionTableAccess,
			SymGetModuleBase,
			NULL
		);
		if (!more || sf.AddrFrame.Offset == 0 || count > MAX_STACK_DEPTH) {
			break;
		}

		dwModBase = SymGetModuleBase(process, sf.AddrPC.Offset);

		if (dwModBase) {
			GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH);
		} else {
			strcpy(modname, "Unknown");
		}

		pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
		pSym->MaxNameLength = MAX_PATH;

		char* printstringsnew = (char*) GlobalAlloc(GMEM_FIXED, (count + 1) * BUFFER_SIZE);
		memcpy(printstringsnew, printstrings, count * BUFFER_SIZE);
		GlobalFree(printstrings);
		printstrings = printstringsnew;

		if (SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym)) {
			// This is the code path taken on VC if debugging syms are found.
			SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s(%s+%#0lx) [0x%08lX]", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
		} else {
			// This is the code path taken on MinGW, and VC if no debugging syms are found.
			if (strstr(modname, ".exe")) {
				// for the .exe, we need the absolute address
				dwModAddrToPrint = sf.AddrPC.Offset;
			} else {
				// for DLLs, we need the module-internal/relative address
				dwModAddrToPrint = sf.AddrPC.Offset - dwModBase;
			}
			SNPRINTF(printstrings + count * BUFFER_SIZE, BUFFER_SIZE, "(%d) %s [0x%08lX]", count, modname, dwModAddrToPrint);
		}

		// OpenGL lib names (ATI): "atioglxx.dll" "atioglx2.dll"
		containsOglDll = containsOglDll || strstr(modname, "atiogl");
		// OpenGL lib names (Nvidia): "nvoglnt.dll" "nvoglv32.dll" "nvoglv64.dll" (last one is a guess)
		containsOglDll = containsOglDll || strstr(modname, "nvogl");
		// OpenGL lib names (Intel): "ig4dev32.dll" "ig4dev64.dll"
		containsOglDll = containsOglDll || strstr(modname, "ig4dev");

		++count;
	}

	if (suspended) {
		ResumeThread(hThread);
	}

	if (containsOglDll) {
		PRINT("This stack trace indicates a problem with your graphic card driver. "
		      "Please try upgrading or downgrading it. "
		      "Specifically recommended is the latest driver, and one that is as old as your graphic card. "
		      "Make sure to use a driver removal utility, before installing other drivers.");
	}

	for (int i = 0; i < count; ++i) {
		PRINT("%s", printstrings + i * BUFFER_SIZE);
	}

	GlobalFree(printstrings);
	GlobalFree(pSym);
}
Beispiel #25
0
/*
================
Sys_PrintStackTrace

Occurs when we encounter a fatal error.
Prints the stack trace as well as some other data.
================
*/
LONG WINAPI Sys_PrintStackTrace(EXCEPTION_POINTERS* exception)
{
	STACKFRAME frame = {};
#ifdef WIN32
	DWORD machine = IMAGE_FILE_MACHINE_I386;
#else
	DWORD machine = IMAGE_FILE_MACHINE_AMD64;
#endif
	HANDLE process = GetCurrentProcess();
	HANDLE thread = GetCurrentThread();
	int i = 0;

	frame.AddrPC.Mode = AddrModeFlat;
	frame.AddrFrame.Mode = AddrModeFlat;
	frame.AddrStack.Mode = AddrModeFlat;

#ifdef WIN32
	frame.AddrPC.Offset = exception->ContextRecord->Eip;
	frame.AddrFrame.Offset = exception->ContextRecord->Ebp;
	frame.AddrStack.Offset = exception->ContextRecord->Esp;
#else
	frame.AddrPC.Offset = exception->ContextRecord->Rip;
	frame.AddrFrame.Offset = exception->ContextRecord->Rbp;
	frame.AddrStack.Offset = exception->ContextRecord->Rsp;
#endif

	Com_Printf("------------------------\n");
	Com_Printf("Enumerate Modules:\n");
	Com_Printf("------------------------\n");
	SymRefreshModuleList(process);
	SymEnumerateModules(process, Sys_PrintModule, nullptr);

	Com_Printf("\n\n");
	Com_Printf("------------------------\n");
	Com_Printf("Stack trace : \n");
	Com_Printf("------------------------\n");
	while (StackWalk(machine, process, thread, &frame, exception->ContextRecord, nullptr, SymFunctionTableAccess, SymGetModuleBase, nullptr))
	{
		DWORD moduleBase = SymGetModuleBase(process, frame.AddrPC.Offset);
		char moduleName[MAX_PATH];
		char funcName[MAX_PATH];
		char fileName[MAX_PATH];
		DWORD address = frame.AddrPC.Offset;
		char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 255];
		PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL)symbolBuffer;
		IMAGEHLP_LINE line;
		DWORD offset = 0;

		line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
		symbol->SizeOfStruct = (sizeof IMAGEHLP_SYMBOL) + 255;
		symbol->MaxNameLength = 254;

		if (moduleBase && GetModuleFileNameA((HINSTANCE)moduleBase, moduleName, MAX_PATH))
		{
			Sys_CleanModuleName(moduleName, MAX_PATH);
		}
		else
		{
			moduleName[0] = '\0';
		}

		if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &offset, symbol))
		{
			Q_strncpyz(funcName, symbol->Name, MAX_PATH);
		}
		else
		{
			funcName[0] = '\0';
		}

		if (SymGetLineFromAddr(process, frame.AddrPC.Offset, &offset, &line))
		{
			Q_strncpyz(fileName, line.FileName, MAX_PATH);
			Sys_CleanModuleName(fileName, MAX_PATH);
			Com_sprintf(fileName, MAX_PATH, "%s:%i", fileName, line.LineNumber);
		}
		else
		{
			fileName[0] = '\0';
		}

		Com_Printf("%03i %20s 0x%08X | %s (%s)\n", i, moduleName, address, funcName, fileName);
		i++;
	}

	Sys_Error("Unhanded Exception: 0x%08X", exception->ExceptionRecord->ExceptionCode);
#ifdef _DEBUG
	return EXCEPTION_CONTINUE_SEARCH;
#else
	return EXCEPTION_EXECUTE_HANDLER;
#endif
	
}
Beispiel #26
0
static BOOL ResolveSymbol(HANDLE hProcess, DWORD dwAddress,
	SYMBOL_INFO &siSymbol)
{
	BOOL fRetval = TRUE;

	siSymbol.dwAddress = dwAddress;

	union {
		CHAR rgchSymbol[sizeof(IMAGEHLP_SYMBOL) + 255];
		IMAGEHLP_SYMBOL  sym;
	};

	CHAR szUndec[256];
	CHAR szWithOffset[256];
	LPSTR pszSymbol = NULL;
	IMAGEHLP_MODULE mi;

	memset(&siSymbol, 0, sizeof(SYMBOL_INFO));
	mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	if (!SymGetModuleInfo(hProcess, dwAddress, &mi))
		lstrcpyA(siSymbol.szModule, "<no module>");
	else
	{
		LPSTR pszModule = strchr(mi.ImageName, '\\');
		if (pszModule == NULL)
			pszModule = mi.ImageName;
		else
			pszModule++;

		lstrcpynA(siSymbol.szModule, pszModule, _countof(siSymbol.szModule));
	   lstrcatA(siSymbol.szModule, "! ");
	}

	__try
	{
		sym.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
		sym.Address = dwAddress;
		sym.MaxNameLength = 255;

		if (SymGetSymFromAddr(hProcess, dwAddress, &(siSymbol.dwOffset), &sym))
		{
			pszSymbol = sym.Name;

			if (UnDecorateSymbolName(sym.Name, szUndec, _countof(szUndec),
				UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS))
			{
				pszSymbol = szUndec;
			}
			else if (SymUnDName(&sym, szUndec, _countof(szUndec)))
			{
				pszSymbol = szUndec;
			}

			if (siSymbol.dwOffset != 0)
			{
				wsprintfA(szWithOffset, "%s + %d bytes", pszSymbol, siSymbol.dwOffset);
				pszSymbol = szWithOffset;
			}
	  }
	  else
		  pszSymbol = "<no symbol>";
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		pszSymbol = "<EX: no symbol>";
		siSymbol.dwOffset = dwAddress - mi.BaseOfImage;
	}

	lstrcpynA(siSymbol.szSymbol, pszSymbol, _countof(siSymbol.szSymbol));
	return fRetval;
}
Beispiel #27
0
// Get function prototype and parameter info from ip address and stack address
static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol )
{
	BOOL              ret = FALSE;
	DWORD             dwSymSize = 10000;
	TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?");
	CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?";
	LPTSTR            lpszParamSep = nullptr;
	LPTSTR            lpszParsed = lpszUnDSymbol;
	PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize );

	::ZeroMemory( pSym, dwSymSize );
	pSym->SizeOfStruct = dwSymSize;
	pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL);

	// Set the default to unknown
	_tcscpy( lpszSymbol, _T("?") );

	// Get symbol info for IP
	DWORD64           dwDisp = 0;
	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) )
	{
		// Make the symbol readable for humans
		UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,
			UNDNAME_COMPLETE |
			UNDNAME_NO_THISTYPE |
			UNDNAME_NO_SPECIAL_SYMS |
			UNDNAME_NO_MEMBER_TYPE |
			UNDNAME_NO_MS_KEYWORDS |
			UNDNAME_NO_ACCESS_SPECIFIERS );

		// Symbol information is ANSI string
		PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol );

		// I am just smarter than the symbol file :)
		if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 )
			_tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)"));
		else
			if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 )
				_tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)"));
			else
				if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 )
					_tcscpy(lpszUnDSymbol, _T("mainCRTStartup()"));
				else
					if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 )
						_tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)"));
					else
						if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 )
							_tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()"));

		lpszSymbol[0] = _T('\0');

		// Let's go through the stack, and modify the function prototype, and insert the actual
		// parameter values from the stack
		if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == nullptr && _tcsstr( lpszUnDSymbol, _T("()") ) == nullptr)
		{
			ULONG index = 0;
			for ( ; ; index++ )
			{
				lpszParamSep = _tcschr( lpszParsed, _T(',') );
				if ( lpszParamSep == nullptr )
					break;

				*lpszParamSep = _T('\0');

				_tcscat( lpszSymbol, lpszParsed );
				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) );

				lpszParsed = lpszParamSep + 1;
			}

			lpszParamSep = _tcschr( lpszParsed, _T(')') );
			if ( lpszParamSep != nullptr )
			{
				*lpszParamSep = _T('\0');

				_tcscat( lpszSymbol, lpszParsed );
				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) );

				lpszParsed = lpszParamSep + 1;
			}
		}

		_tcscat( lpszSymbol, lpszParsed );

		ret = TRUE;
	}
	GlobalFree( pSym );

	return ret;
}
Beispiel #28
0
LONG WINAPI MyExceptionFilter ( EXCEPTION_POINTERS * lpep) {

	BOOL rVal;
	STACKFRAME StackFrame;
	CONTEXT Context;
	IMAGEHLP_SYMBOL *pImagehlpSymbol;
	ULONG Displacement;
	BOOL fReturn;
	CHAR szUndecoratedName[MAXSYMBOLNAMELENGTH];
	FILE * flog;

	SymSetOptions(0);
	SymInitialize(SYM_HANDLE, NULL, TRUE);

	flog = fopen("c:\\Except.log","a");
	if (!flog)
		return EXCEPTION_CONTINUE_SEARCH;
	printf("\ndumping stack trace\n");
	ZeroMemory(&StackFrame, sizeof(StackFrame));
	Context = *lpep->ContextRecord;

#if defined(_M_IX86)
	StackFrame.AddrPC.Offset = Context.Eip;
	StackFrame.AddrPC.Mode = AddrModeFlat;
	StackFrame.AddrFrame.Offset = Context.Ebp;
	StackFrame.AddrFrame.Mode = AddrModeFlat;
	StackFrame.AddrStack.Offset = Context.Esp;
	StackFrame.AddrStack.Mode = AddrModeFlat;
#endif

	pImagehlpSymbol = (IMAGEHLP_SYMBOL *) xmalloc(sizeof(IMAGEHLP_SYMBOL) +
												MAXSYMBOLNAMELENGTH - 1);
	ZeroMemory(pImagehlpSymbol, sizeof(IMAGEHLP_SYMBOL) + MAXSYMBOLNAMELENGTH -
			   1);
	pImagehlpSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	pImagehlpSymbol->MaxNameLength = MAXSYMBOLNAMELENGTH;

	do {
		rVal = StackWalk ( MACHINE_TYPE,
				SYM_HANDLE,
				0,
				&StackFrame,
				&Context,
				ReadProcessMemory,
				SymFunctionTableAccess,
				SymGetModuleBase,
				NULL);
		if (rVal) {
			pImagehlpSymbol->Address = StackFrame.AddrPC.Offset;
			fReturn = SymGetSymFromAddr ( SYM_HANDLE,
					StackFrame.AddrPC.Offset,
					&Displacement,
					pImagehlpSymbol
				);
			fprintf(flog,"%08x %08x  ", StackFrame.AddrFrame.Offset,
				StackFrame.AddrReturn.Offset);
			printf("%08x %08x  ", StackFrame.AddrFrame.Offset,
				StackFrame.AddrReturn.Offset);
			if (fReturn) {
				fReturn = SymUnDName ( pImagehlpSymbol, szUndecoratedName,		
						 MAXSYMBOLNAMELENGTH);

				if (fReturn) {
					fprintf(flog,"%s", szUndecoratedName);
					printf("%s", szUndecoratedName);
					if (Displacement){
						fprintf(flog,"+%x", Displacement);
						printf("+%x", Displacement);
					}
				}
			} else{
				fprintf(flog,"0x%08x", StackFrame.AddrPC.Offset);
				printf("0x%08x", StackFrame.AddrPC.Offset);
			}
			fprintf(flog,"\n");
			printf("\n");
		}
	}
	while (rVal);

	SymCleanup(SYM_HANDLE);
	fprintf(flog,"----Hit ^c to exit----\n");
	fclose(flog);
	ExitProcess((DWORD)-1);
	return EXCEPTION_CONTINUE_SEARCH;//EXCEPTION_EXECUTE_HANDLER;
}
static void
_backtrace(struct output_buffer *ob, struct bfd_set *set, int depth , LPCONTEXT context)
{
	char procname[MAX_PATH];
	GetModuleFileNameA(NULL, procname, sizeof procname);

	struct bfd_ctx *bc = NULL;

	STACKFRAME frame;
	memset(&frame,0,sizeof(frame));

	frame.AddrPC.Offset = context->Eip;
	frame.AddrPC.Mode = AddrModeFlat;
	frame.AddrStack.Offset = context->Esp;
	frame.AddrStack.Mode = AddrModeFlat;
	frame.AddrFrame.Offset = context->Ebp;
	frame.AddrFrame.Mode = AddrModeFlat;

	HANDLE process = GetCurrentProcess();
	HANDLE thread = GetCurrentThread();

	char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + 255];
	char module_name_raw[MAX_PATH];

	while(StackWalk(IMAGE_FILE_MACHINE_I386,
		process,
		thread,
		&frame,
		context,
		0,
		SymFunctionTableAccess,
		SymGetModuleBase, 0)) {

		--depth;
		if (depth < 0)
			break;

		IMAGEHLP_SYMBOL *symbol = (IMAGEHLP_SYMBOL *)symbol_buffer;
		symbol->SizeOfStruct = (sizeof *symbol) + 255;
		symbol->MaxNameLength = 254;

		DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset);

		const char * module_name = "[unknown module]";
		if (module_base &&
			GetModuleFileNameA((HINSTANCE)module_base, module_name_raw, MAX_PATH)) {
			module_name = module_name_raw;
			bc = get_bc(ob, set, module_name);
		}

		const char * file = NULL;
		const char * func = NULL;
		unsigned line = 0;

		if (bc) {
			find(bc,frame.AddrPC.Offset,&file,&func,&line);
		}

		if (file == NULL) {
			DWORD dummy = 0;
			if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol)) {
				file = symbol->Name;
			}
			else {
				file = "[unknown file]";
			}
		}
		if (func == NULL) {
			output_print(ob,"0x%x : %s : %s \n",
				frame.AddrPC.Offset,
				module_name,
				file);
		}
		else {
			output_print(ob,"0x%x : %s : %s (%d) : in function (%s) \n",
				frame.AddrPC.Offset,
				module_name,
				file,
				line,
				func);
		}
	}
}
Beispiel #30
0
    void
    backtrace() {
        static struct sym_t {
            HANDLE proc;
            sym_t() {
                proc = GetCurrentProcess();
                SymSetOptions(
                    SYMOPT_DEFERRED_LOADS | // シンボルを参照する必要があるときまで読み込まない
                    SYMOPT_LOAD_LINES |     // 行番号情報を読み込む
                    SYMOPT_UNDNAME          // すべてのシンボルを装飾されていない形式で表します
                    );
                if(!SymInitialize(proc, 0, true)){
                    throw exception("error : SymInitialize");
                }
                // cout << "<SymInitialize>" << endl;
            }
            ~sym_t() {
                SymCleanup(proc);
                // cout << "<SymCleanup>" << endl;
            }
        } s_sym;

        array<void*,8> addr;
        int count = RtlCaptureStackBackTrace(0, addr.size(), &addr[0], 0);
        cout << "---- BEGIN BACKTRACE ----" << endl;
        for(int Li = 1; Li < count; ++Li){
            auto p = reinterpret_cast<uintptr_t>(addr[Li]);

            IMAGEHLP_MODULE module;
            ::memset(&module, 0, sizeof(module));
            module.SizeOfStruct = sizeof(module);
            if(!SymGetModuleInfo(s_sym.proc, p, &module)){
                throw exception("error : SymGetModuleInfo");
            }

            char buffer[sizeof(IMAGEHLP_SYMBOL) + MAX_PATH];
            ::memset(buffer, 0, sizeof(buffer));
            auto symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(buffer);
            symbol->SizeOfStruct = sizeof(*symbol);
            symbol->MaxNameLength = MAX_PATH;

            DWORDx disp = 0;
            if(!SymGetSymFromAddr(s_sym.proc, p, &disp, symbol)){
                throw exception("error : SymGetSymFromAddr");
            }
            if(!strcmp(symbol->Name, "__tmainCRTStartup")){
                break;
            }

            string text = "?";
            IMAGEHLP_LINE line;
            ::memset(&line, 0, sizeof(line));
            line.SizeOfStruct = sizeof(line);
            DWORD disp2 = 0;
            if(!SymGetLineFromAddr(s_sym.proc, p, &disp2, &line)){
                line.FileName = "?";
                line.LineNumber = 0;
                text = "?";
            } else {
                text = getline(line.FileName, line.LineNumber);
            }

            cout << Li
                 << " : 0x" << hex << setw(sizeof(uintptr_t) * 2) << setfill('0') << p
                 << " : " << module.ModuleName
                 << " : " << symbol->Name
                 << " : " << line.FileName << "(" << dec << line.LineNumber << ")"
                 << " : " << text.c_str()
                 << endl;
        }
        cout << "---- END BACKTRACE ----" << endl << endl;
    }