Example #1
0
bool dbgsymengine::get_line_from_addr (HANDLE hProc, unsigned addr, unsigned * pdisplacement, IMAGEHLP_LINE * pLine)
{	 
	#ifdef WORK_AROUND_SRCLINE_BUG

	// "Debugging Applications" John Robbins
    // The problem is that the symbol engine finds only those source
    // line addresses (after the first lookup) that fall exactly on
    // a zero displacement. I'll walk backward 100 bytes to
    // find the line and return the proper displacement.
    DWORD displacement = 0 ;
    while (!SymGetLineFromAddr (hProc, addr - displacement, (DWORD*)pdisplacement, pLine))
    {        
        if (100 == ++displacement)
            return false;        
    }

	// "Debugging Applications" John Robbins
    // I found the line, and the source line information is correct, so
    // change the displacement if I had to search backward to find the source line.
    if (displacement)    
        *pdisplacement = displacement;    
    return true;

	#else 
    return 0 != SymGetLineFromAddr (hProc, addr, (DWORD *) pdisplacement, pLine);
	#endif
}
Example #2
0
/***********************************************************************
 *           print_address
 *
 * Print an 16- or 32-bit address, with the nearest symbol if any.
 */
void print_address(const ADDRESS64* addr, BOOLEAN with_line)
{
    char                buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*        si = (SYMBOL_INFO*)buffer;
    void*               lin = memory_to_linear_addr(addr);
    DWORD64             disp64;
    DWORD               disp;

    print_bare_address(addr);

    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen   = 256;
    if (!SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si)) return;
    dbg_printf(" %s", si->Name);
    if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64);
    if (with_line)
    {
        IMAGEHLP_LINE               il;
        IMAGEHLP_MODULE             im;

        il.SizeOfStruct = sizeof(il);
        if (SymGetLineFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il))
            dbg_printf(" [%s:%lu]", il.FileName, il.LineNumber);
        im.SizeOfStruct = sizeof(im);
        if (SymGetModuleInfo(dbg_curr_process->handle, (DWORD_PTR)lin, &im))
            dbg_printf(" in %s", im.ModuleName);
    }
}
Example #3
0
bool CBDTWxFrame::FilterTest(uint32_t eip, IMAGEHLP_LINE& info, bool& getAddrSuccess)
{
    DWORD displacement = 0;
    getAddrSuccess = SymGetLineFromAddr(GetCurrentProcess(), eip, &displacement, &info) == TRUE;
    //TODO: Try to catch a mystery crash.
    bool bLineNumberMayOverFlow = getAddrSuccess && info.LineNumber > 100000;
    bool bFileNameMayBroken = getAddrSuccess && (uint32_t)info.FileName < 10;
    if (bLineNumberMayOverFlow || bFileNameMayBroken)
    {
        BEATS_ASSERT(false);
    }
    bool filter = false;
    if (getAddrSuccess)
    {
        for (uint32_t i = 0; i < m_pFilterTextComboBox->GetCount(); ++i)
        {
            if (strstr(info.FileName, m_pFilterTextComboBox->GetString(i).c_str().AsChar()) != 0)
            {
                filter = true;
                break;
            }
        }
    }
    return filter;
}
Example #4
0
void CBDTWxFrame::OnGridCellSelected( wxGridEvent& event )
{
    if ( m_memoryViewType == eMVT_Addr || m_memoryViewType == eMVT_Size || m_memoryViewType == eMVT_AllocTime)
    {
        m_pCallStackListBox->Clear();
        long value = 0;
        uint32_t addressValueColIndex = m_memoryViewType == eMVT_Addr ? 0 : 1;//it's hard code here.
        wxString cellStr = m_pMemoryDataGrid->GetCellValue(event.GetRow(), addressValueColIndex);
        if (cellStr.IsEmpty() == false)
        {
            cellStr.ToLong(&value, 16);
            std::vector<uint32_t> callStack;
            CMemoryDetector::GetInstance()->GetCallStack(value, callStack);
            DWORD displacement = 0;
            IMAGEHLP_LINE info;
            char temp[256];
            for (uint32_t i = 0; i < callStack.size(); ++i)
            {
                bool getAddrSuccess = SymGetLineFromAddr(GetCurrentProcess(), callStack[i], &displacement, &info) == TRUE;
                if (getAddrSuccess)
                {
                    sprintf_s(temp, "%s line:%d", info.FileName, info.LineNumber);
                    m_pCallStackListBox->Append(temp);
                }
                else
                {
                    m_pCallStackListBox->Append("未知!");
                }
            }
        }
    }
}
Example #5
0
size_t GetFileLineFromAddress(void* address, char* fileName, size_t size,
                              size_t* lineNumber, size_t* offsetBytes)
{
    if (size) *fileName = 0;
    if (lineNumber) *lineNumber = 0;
    if (offsetBytes) *offsetBytes = 0;
    {
        char* sourceName;
        IMAGEHLP_LINE line = { sizeof (line) };
        GC_ULONG_PTR dwOffset = 0;
        if (!SymGetLineFromAddr(GetSymHandle(), CheckAddress(address), &dwOffset,
                                &line)) {
            return 0;
        }
        if (lineNumber) {
            *lineNumber = line.LineNumber;
        }
        if (offsetBytes) {
            *offsetBytes = dwOffset;
        }
        sourceName = line.FileName;
        /* TODO: resolve relative filenames, found in 'source directories'  */
        /* registered with MSVC IDE.                                        */
        if (size) {
            strncpy(fileName, sourceName, size)[size - 1] = 0;
        }
        return strlen(sourceName);
    }
}
Example #6
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);
	}
}
void P_APIENTRY pDebugPrintStack(pint32 skip)
{
    typedef USHORT (WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG);
    CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(LoadLibrary(TEXT("kernel32.dll")), 
                "RtlCaptureStackBackTrace"));

    if (func == NULL)
    {
        return ; 
    }

    // Quote from Microsoft Documentation:
    // ## Windows Server 2003 and Windows XP:  
    // ## The sum of the FramesToSkip and FramesToCapture parameters must be less than 63.
    const int kMaxCallers = 62; 

    HANDLE hProcess = GetCurrentProcess();
    SymInitialize(hProcess, NULL, TRUE);

    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)malloc(sizeof(SYMBOL_INFO) + 256);
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = 255;
    
    void* callers[kMaxCallers];
    int count = (func)(0, kMaxCallers, callers, NULL);

    // To skip the pDebugPrintStack function frame, we start from 1 instead of 0.
    for(int i = skip; i < count; i++)
    {
        //PLOG_INFO("*** %d called from %016I64LX\n", i, callers[i]);

        DWORD addr = (DWORD)(callers[i]);
        DWORD64 symDisplacement = 0;
        if (SymFromAddr(hProcess, addr, 0, pSymbol))
        {
            IMAGEHLP_LINE lineInfo = {sizeof(IMAGEHLP_LINE)};
            DWORD dwLineDisplacement;

            if (SymGetLineFromAddr(hProcess, addr, &dwLineDisplacement, &lineInfo))
            {
                PLOG_INFO("%s:%s(),Line %u", lineInfo.FileName, pSymbol->Name, lineInfo.LineNumber); 
            }
            
            // Stop the walk at main function. 
            if (pstrcmp(pSymbol->Name, "main") == 0)
            {
                break;
            }
        }
    }
    
    SymCleanup(GetCurrentProcess());
}
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;
}
Example #9
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
}
Example #10
0
const std::string PXL_stack_trace(int num_traces) {
#if defined(_DEBUG)
    uint32 i;
    DWORD* stacks = new DWORD[num_traces];
    uint16 frames_captured;
    SYMBOL_INFO* symbol;
    HANDLE process;

    process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);
    frames_captured = CaptureStackBackTrace(0, num_traces, (PVOID*)stacks, NULL);

    //needs to be allocated on heap
    symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
    symbol->MaxNameLen = 192;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

    IMAGEHLP_LINE line;
    DWORD disp;

    std::string output = "";
    char* char_output = new char[255];
    for (i = 0; i < frames_captured; i++) {
        SymFromAddr(process, stacks[i], NULL, symbol);
        SymGetLineFromAddr(process, stacks[i], &disp, &line);

        //convert file name to string and remove everything in the string before src or include
        std::string file_name = line.FileName;
        int id;
        if ((id = file_name.rfind("src")) != -1) {
            file_name = file_name.substr(id + 4, file_name.length());
        } else if ((id = file_name.rfind("include")) != -1) {
            file_name = file_name.substr(id, file_name.length());
        }

        if (id != -1) {
            sprintf(char_output, "%i: %s (%s, line %i)\n", frames_captured - i - 1, symbol->Name, file_name.c_str(), line.LineNumber);
            output += char_output;
        }
    }

    delete symbol;
    delete[] stacks;

    return output;
#endif

    return "";
}
Example #11
0
/***********************************************************************
 *           symbol_get_function_line_status
 *
 * Find the symbol nearest to a given address.
 */
enum dbg_line_status symbol_get_function_line_status(const ADDRESS64* addr)
{
    IMAGEHLP_LINE       il;
    DWORD               disp;
    ULONG64             disp64, start;
    DWORD               lin = (DWORD)memory_to_linear_addr(addr);
    char                buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*        sym = (SYMBOL_INFO*)buffer;
    struct dbg_type     func;

    il.SizeOfStruct = sizeof(il);
    sym->SizeOfStruct = sizeof(SYMBOL_INFO);
    sym->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);

    /* do we have some info for lin address ? */
    if (!SymFromAddr(dbg_curr_process->handle, lin, &disp64, sym))
        return dbg_no_line_info;

    switch (sym->Tag)
    {
    case SymTagThunk:
        /* FIXME: so far dbghelp doesn't return the 16 <=> 32 thunks
         * and furthermore, we no longer take care of them !!!
         */
        return dbg_in_a_thunk;
    case SymTagFunction:
    case SymTagPublicSymbol: break;
    default:
        WINE_FIXME("Unexpected sym-tag 0x%08x\n", sym->Tag);
    case SymTagData:
        return dbg_no_line_info;
    }
    /* we should have a function now */
    if (!SymGetLineFromAddr(dbg_curr_process->handle, lin, &disp, &il))
        return dbg_no_line_info;

    func.module = sym->ModBase;
    func.id     = sym->info;

    if (symbol_get_debug_start(&func, &start) && lin < start)
        return dbg_not_on_a_line_number;

    if (!sym->Size) sym->Size = 0x100000;
    if (il.FileName && il.FileName[0] && disp < sym->Size)
        return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number;

    return dbg_no_line_info;
}
Example #12
0
/* static */
BOOL
wxDbgHelpDLL::CallSymGetLineFromAddr(HANDLE hProcess,
                                     DWORD64 dwAddr,
                                     wxString* fileName,
                                     size_t* line)
{
    DWORD dwDisplacement;

#ifdef UNICODE
    if ( SymGetLineFromAddrW64 )
    {
        SizedStruct<IMAGEHLP_LINEW64> lineW64;
        if ( SymGetLineFromAddrW64(hProcess, dwAddr, &dwDisplacement, &lineW64) )
        {
            *fileName = lineW64.FileName;
            *line = lineW64.LineNumber;
            return TRUE;
        }
    }
#endif // UNICODE

    if ( SymGetLineFromAddr64 )
    {
        SizedStruct<IMAGEHLP_LINE64> line64;
        if ( SymGetLineFromAddr64(hProcess, dwAddr, &dwDisplacement, &line64) )
        {
            *fileName = line64.FileName;
            *line = line64.LineNumber;
            return TRUE;
        }
    }

    if ( SymGetLineFromAddr )
    {
        SizedStruct<IMAGEHLP_LINE> line32;
        if ( SymGetLineFromAddr(hProcess, dwAddr, &dwDisplacement, &line32) )
        {
            *fileName = line32.FileName;
            *line = line32.LineNumber;
            return TRUE;
        }
    }

    return FALSE;
}
Example #13
0
void source_list_from_addr(const ADDRESS64* addr, int nlines)
{
    IMAGEHLP_LINE       il;
    ADDRESS64           la;
    DWORD               disp;

    if (!addr)
    {
        memory_get_current_pc(&la);
        addr = &la;
    }

    il.SizeOfStruct = sizeof(il);
    if (SymGetLineFromAddr(dbg_curr_process->handle,
                           (unsigned long)memory_to_linear_addr(addr),
                           &disp, &il))
        source_list(&il, NULL, nlines);
}
Example #14
0
BOOL CallStack::symSourceInfoFromAddress(UINT address, TCHAR* lpszSourceInfo, UINT BufSizeTCHARs)
{
    BOOL           ret = FALSE;
    IMAGEHLP_LINE  lineInfo;
    DWORD          dwDisp;
    TCHAR          lpModuleInfo[MLD_MAX_NAME_LENGTH] = MLD_TRACEINFO_EMPTY;

    _tcscpy_s(lpszSourceInfo, BufSizeTCHARs, MLD_TRACEINFO_NOSYMBOL);

    memset( &lineInfo, NULL, sizeof( IMAGEHLP_LINE ) );
    lineInfo.SizeOfStruct = sizeof( IMAGEHLP_LINE );

    if ( SymGetLineFromAddr( m_hProcess, address, &dwDisp, &lineInfo ) )
    {
        // Using the "sourcefile(linenumber)" format
#ifdef UNICODE
        wchar_t dest[1024] ;
        int len = strlen((char *)lineInfo.FileName) + 1 ;
        MultiByteToWideChar(CP_ACP, 0, (char *)lineInfo.FileName, len, dest, len) ;
        _stprintf_s(lpszSourceInfo, BufSizeTCHARs, _T("%s(%d): 0x%08X"), dest, lineInfo.LineNumber, address );//    <--- Size of the char thing.
#else
        _stprintf_s(lpszSourceInfo, BufSizeTCHARs, _T("%s(%d): 0x%08X"), lineInfo.FileName, lineInfo.LineNumber, address );//   <--- Size of the char thing.
#endif
        ret = TRUE;
    }
    else
    {
        // Using the "modulename!address" format
        symModuleNameFromAddress( address, lpModuleInfo, MLD_MAX_NAME_LENGTH);

        if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0'))
        {
            // Using the "address" format
            _stprintf_s(lpszSourceInfo, BufSizeTCHARs, _T("0x%08X"), lpModuleInfo, address );
        }
        else
        {
            _stprintf_s(lpszSourceInfo, BufSizeTCHARs, _T("%sdll! 0x%08X"), lpModuleInfo, address );
        }
        ret = FALSE;
    }
    //
    return ret;
}
Example #15
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);
}
Example #16
0
	xgc_void DumpStackFrame()
	{
		StackFrameSequence FrameSequence;
		GetStackTrace( FrameSequence );

		xgc_char szSymbol[sizeof( SYMBOL_INFO ) + 1024];
		SYS_TIP( "---------------stack frame begin--------------" );

		for( UINT nCur = 0; nCur < FrameSequence.Count && FrameSequence.Frame[nCur]; ++nCur )
		{
			ZeroMemory( szSymbol, sizeof( szSymbol ) );
			PSYMBOL_INFO pSymInfo = (PSYMBOL_INFO) &szSymbol;

			pSymInfo->SizeOfStruct = sizeof( SYMBOL_INFO );
			pSymInfo->MaxNameLen = sizeof( szSymbol ) - sizeof( SYMBOL_INFO );

			// Get the function.
			DWORD64 dwDisp = 0;
			if( SymFromAddr( hProcess, (UINT_PTR)FrameSequence.Frame[nCur], &dwDisp, pSymInfo ) )
			{
				// If I got a symbol, give the source and line a whirl.
				IMAGEHLP_LINE lineInfo;
				lineInfo.SizeOfStruct = sizeof( lineInfo );

				DWORD dwDisplacement = 0;
				if( SymGetLineFromAddr( hProcess, (UINT_PTR)FrameSequence.Frame[nCur], &dwDisplacement, &lineInfo ) )
				{
					// Put this on the next line and indented a bit.
					LOG_EXT_FORMAT( SYS, lineInfo.FileName, pSymInfo->Name, lineInfo.LineNumber, "stack", "stack frame %p : %s", FrameSequence.Frame[nCur], pSymInfo->Name );
				}
				else
				{
					LOG_TAG_FORMAT( SYS, "stack", "LastError:[%u], stack frame %p", GetLastError(), FrameSequence.Frame[nCur], pSymInfo->Name );
				}
			}
			else
			{
				LOG_TAG_FORMAT( SYS, "stack", "stack frame %p", FrameSequence.Frame[nCur] );
			}
		}
		SYS_TIP( "---------------stack frame end--------------" );
	}
Example #17
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);
	}
}
Example #18
0
// Get source file name and line number from IP address
// The output format is: "sourcefile(linenumber)" or
//                       "modulename!address" or
//                       "address"
static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo )
{
	BOOL           ret = FALSE;
	IMAGEHLP_LINE  lineInfo;
	DWORD          dwDisp;
	TCHAR          lpszFileName[BUFFERSIZE] = _T("");
	TCHAR          lpModuleInfo[BUFFERSIZE] = _T("");

	_tcscpy( lpszSourceInfo, _T("?(?)") );

	::ZeroMemory( &lineInfo, sizeof( lineInfo ) );
	lineInfo.SizeOfStruct = sizeof( lineInfo );

	if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) )
	{
		// Got it. Let's use "sourcefile(linenumber)" format
		PCSTR2LPTSTR( lineInfo.FileName, lpszFileName );
		TCHAR fname[_MAX_FNAME];
		TCHAR ext[_MAX_EXT];
		_tsplitpath(lpszFileName, nullptr, nullptr, fname, ext);
		_stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber );
		ret = TRUE;
	}
	else
	{
		// There is no source file information. :(
		// Let's use the "modulename!address" format
		GetModuleNameFromAddress( address, lpModuleInfo );

		if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0'))
			// There is no modulename information. :((
			// Let's use the "address" format
			_stprintf( lpszSourceInfo, _T("0x%08X"), address );
		else
			_stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address );

		ret = FALSE;
	}

	return ret;
}
Example #19
0
void StackTree::printCallstack(StackNode* node)
{
	while (node)
	{
		HANDLE process = GetCurrentProcess();
		uint8 symbol_mem[sizeof(SYMBOL_INFO) + 256 * sizeof(char)];
		SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(symbol_mem);
		memset(symbol_mem, 0, sizeof(symbol_mem));
		symbol->MaxNameLen = 255;
		symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
		BOOL success = SymFromAddr(process, (DWORD64)(node->m_instruction), 0, symbol);
		if (success)
		{
			IMAGEHLP_LINE line;
			DWORD offset;
			if (SymGetLineFromAddr(process, (DWORD64)(node->m_instruction), &offset, &line))
			{
				OutputDebugString("\t");
				OutputDebugString(line.FileName);
				OutputDebugString("(");
				char tmp[20];
				toCString((uint32)line.LineNumber, tmp, sizeof(tmp));
				OutputDebugString(tmp);
				OutputDebugString("):");
			}
			OutputDebugString("\t");
			OutputDebugString(symbol->Name);
			OutputDebugString("\n");
		}
		else
		{
			OutputDebugString("\tN/A\n");
		}
		node = node->m_parent;
	}
}
Example #20
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
	
}
Example #21
0
/***********************************************************************
 *           symbol_get_lvalue
 *
 * Get the address of a named symbol.
 * Return values:
 *      sglv_found:   if the symbol is found
 *      sglv_unknown: if the symbol isn't found
 *      sglv_aborted: some error occurred (likely, many symbols of same name exist,
 *          and user didn't pick one of them)
 */
enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
                                    struct dbg_lvalue* rtn, BOOL bp_disp)
{
    struct sgv_data             sgv;
    int		                i;
    char                        buffer[512];
    DWORD                       opt;
    IMAGEHLP_STACK_FRAME        ihsf;

    if (strlen(name) + 4 > sizeof(buffer))
    {
        WINE_WARN("Too long symbol (%s)\n", name);
        return sglv_unknown;
    }

    sgv.num        = 0;
    sgv.num_thunks = 0;
    sgv.name       = &buffer[2];
    sgv.do_thunks  = DBG_IVAR(AlwaysShowThunks);

    if (strchr(name, '!'))
    {
        strcpy(buffer, name);
    }
    else
    {
        buffer[0] = '*';
        buffer[1] = '!';
        strcpy(&buffer[2], name);
    }

    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv);

    if (!sgv.num)
    {
        const char*   ptr = strchr(name, '!');
        if ((ptr && ptr[1] != '_') || (!ptr && *name != '_'))
        {
            if (ptr)
            {
                int offset = ptr - name;
                memcpy(buffer, name, offset + 1);
                buffer[offset + 1] = '_';
                strcpy(&buffer[offset + 2], ptr + 1);
            }
            else
            {
                buffer[0] = '*';
                buffer[1] = '!';
                buffer[2] = '_';
                strcpy(&buffer[3], name);
            }
            SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv);
        }
    }
    SymSetOptions(opt);

    /* now grab local symbols */
    if (stack_get_current_frame(&ihsf) && sgv.num < NUMDBGV)
    {
        sgv.frame_offset = ihsf.FrameOffset;
        SymEnumSymbols(dbg_curr_process->handle, 0, name, sgv_cb, (void*)&sgv);
    }

    if (!sgv.num)
    {
        dbg_printf("No symbols found for %s\n", name);
        return sglv_unknown;
    }

    /* recompute potential offsets for functions (linenumber, skip prolog) */
    for (i = 0; i < sgv.num; i++)
    {
        if (sgv.syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL|SYMFLAG_LOCAL|SYMFLAG_THUNK))
            continue;

        if (lineno == -1)
        {
            struct dbg_type     type;
            ULONG64             addr;

            type.module = sgv.syms[i].lvalue.type.module;
            type.id     = sgv.syms[i].sym_info;
            if (bp_disp && symbol_get_debug_start(&type, &addr))
                sgv.syms[i].lvalue.addr.Offset = addr;
        }
        else
        {
            DWORD               disp;
            IMAGEHLP_LINE       il;
            BOOL                found = FALSE;

            il.SizeOfStruct = sizeof(il);
            SymGetLineFromAddr(dbg_curr_process->handle,
                               (DWORD)memory_to_linear_addr(&sgv.syms[i].lvalue.addr),
                               &disp, &il);
            do
            {
                if (lineno == il.LineNumber)
                {
                    sgv.syms[i].lvalue.addr.Offset = il.Address;
                    found = TRUE;
                    break;
                }
            } while (SymGetLineNext(dbg_curr_process->handle, &il));
            if (!found)
                WINE_FIXME("No line (%d) found for %s (setting to symbol start)\n",
                           lineno, name);
        }
    }

    i = 0;
    if (dbg_interactiveP)
    {
        if (sgv.num - sgv.num_thunks > 1 || /* many symbols non thunks (and showing only non thunks) */
            (sgv.num > 1 && DBG_IVAR(AlwaysShowThunks)) || /* many symbols (showing symbols & thunks) */
            (sgv.num == sgv.num_thunks && sgv.num_thunks > 1))
        {
            dbg_printf("Many symbols with name '%s', "
                       "choose the one you want (<cr> to abort):\n", name);
            for (i = 0; i < sgv.num; i++) 
            {
                if (sgv.num - sgv.num_thunks > 1 && (sgv.syms[i].flags & SYMFLAG_THUNK) && !DBG_IVAR(AlwaysShowThunks))
                    continue;
                dbg_printf("[%d]: ", i + 1);
                if (sgv.syms[i].flags & SYMFLAG_LOCAL)
                {
                    dbg_printf("%s %sof %s\n",
                               sgv.syms[i].flags & SYMFLAG_PARAMETER ? "Parameter" : "Local variable",
                               sgv.syms[i].flags & (SYMFLAG_REGISTER|SYMFLAG_REGREL) ? "(in a register) " : "",
                               name);
                }
                else if (sgv.syms[i].flags & SYMFLAG_THUNK) 
                {
                    print_address(&sgv.syms[i].lvalue.addr, TRUE);
                    /* FIXME: should display where the thunks points to */
                    dbg_printf(" thunk %s\n", name);
                }
                else
                {
                    print_address(&sgv.syms[i].lvalue.addr, TRUE);
                    dbg_printf("\n");
                }
            }
            do
            {
                i = 0;
                if (input_read_line("=> ", buffer, sizeof(buffer)))
                {
                    if (buffer[0] == '\0') return sglv_aborted;
                    i = atoi(buffer);
                    if (i < 1 || i > sgv.num)
                        dbg_printf("Invalid choice %d\n", i);
                }
                else return sglv_aborted;
            } while (i < 1 || i > sgv.num);

            /* The array is 0-based, but the choices are 1..n, 
             * so we have to subtract one before returning.
             */
            i--;
        }
    }
    else
    {
        /* FIXME: could display the list of non-picked up symbols */
        if (sgv.num > 1)
            dbg_printf("More than one symbol named %s, picking the first one\n", name);
    }
    *rtn = sgv.syms[i].lvalue;
    return sglv_found;
}
Example #22
0
void printTrace()
{
	SymInitialize(GetCurrentProcess(), NULL, TRUE);

	UINT32 maxframes = 62;
	UINT_PTR myFrames[62];

	ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes);
	ULONG BackTraceHash;
	maxframes = CaptureStackBackTrace(0, maxframes, reinterpret_cast<PVOID*>(myFrames), &BackTraceHash);

	const UINT_PTR* pFrame = myFrames;
	const size_t frameSize = maxframes;

	UINT32  startIndex = 0;

	int unresolvedFunctionsCount = 0;
	IMAGEHLP_LINE  sourceInfo = { 0 };
	sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE);

	// Use static here to increase performance, and avoid heap allocs.
	// It's thread safe because of g_heapMapLock lock.
	static char stack_line[1024] = "";
	bool isPrevFrameInternal = false;
	DWORD NumChars = 0;

	const size_t max_line_length = 512;
	const int resolvedCapacity = 62 * max_line_length;
	const size_t allocedBytes = resolvedCapacity * sizeof(char);
	char resolved[resolvedCapacity];
	if (resolved) {
		ZeroMemory(resolved, allocedBytes);
	}
	HANDLE hProcess = GetCurrentProcess();
	int resolvedLength = 0;
	// Iterate through each frame in the call stack.
	for (UINT32 frame = 0; frame < frameSize; frame++)
	{
		if (pFrame[frame] == 0)
			break;
		// Try to get the source file and line number associated with
		// this program counter address.
		SIZE_T programCounter = pFrame[frame];

		DWORD64 displacement64;
		BYTE symbolBuffer[sizeof(SYMBOL_INFO) + 256 * sizeof(char)];
		LPCSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer);

		// It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here
		// in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns.
		// When that happens there is nothing we can do except crash.
		DWORD            displacement = 0;

		BOOL foundline = SymGetLineFromAddr(hProcess, programCounter, &displacement, &sourceInfo);

		bool isFrameInternal = false;

		// show one allocation function for context
		if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) {
			resolvedLength += NumChars;
			if (resolved) {
				strncat_s(resolved, resolvedCapacity, stack_line, NumChars);
			}
		}
		isPrevFrameInternal = isFrameInternal;

		if (!foundline)
			displacement = (DWORD)displacement64;
		NumChars = resolveFunction(programCounter, foundline ? &sourceInfo : NULL,
			displacement, functionName, stack_line, _countof(stack_line));

		if (NumChars > 0 && !isFrameInternal) {
			resolvedLength += NumChars;
			if (resolved) {
				strncat_s(resolved, resolvedCapacity, stack_line, NumChars);
			}
		}
	} // end for loop
	printLog(resolved);

	SymCleanup(GetCurrentProcess());
	return;
}
void DumpStackStak(HANDLE hLogFile, PEXCEPTION_POINTERS lpExcetion)
{
	STACKFRAME stackFrame;
#ifdef _X86_
	stackFrame.AddrPC.Offset = lpExcetion->ContextRecord->Eip;
	stackFrame.AddrPC.Mode = AddrModeFlat;
	stackFrame.AddrStack.Offset = lpExcetion->ContextRecord->Esp;
	stackFrame.AddrStack.Mode = AddrModeFlat;
	stackFrame.AddrFrame.Offset = lpExcetion->ContextRecord->Ebp;
	stackFrame.AddrFrame.Mode = AddrModeFlat;
#else
	stackFrame.AddrPC.Offset       = (DWORD)lpExcetion->ContextRecord->Fir ;
	stackFrame.AddrPC.Mode         = AddrModeFlat ;
	stackFrame.AddrReturn.Offset   = (DWORD)lpExcetion->ContextRecord->IntRa;
	stackFrame.AddrReturn.Mode     = AddrModeFlat ;
	stackFrame.AddrStack.Offset    = (DWORD)lpExcetion->ContextRecord->IntSp;
	stackFrame.AddrStack.Mode      = AddrModeFlat ;
	stackFrame.AddrFrame.Offset    = (DWORD)lpExcetion->ContextRecord->IntFp;
	stackFrame.AddrFrame.Mode      = AddrModeFlat ;
#endif

	//set up symbol engine
	DWORD dwOpts = SymGetOptions();
	SymSetOptions(dwOpts|SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES);
	SymInitialize(GetCurrentProcess(), NULL, TRUE);

#ifdef _WIN64
#define CH_MACHINE IMAGE_FILE_MACHINE_IA64
#else
#define CH_MACHINE IMAGE_FILE_MACHINE_I386
#endif

	WriteLogFile(hLogFile, "\r\n\r\nStack trace list:\r\n");
	do 
	{
		BOOL bRet = StackWalk(CH_MACHINE, GetCurrentProcess(), GetCurrentThread(), &stackFrame, lpExcetion->ContextRecord,
			(PREAD_PROCESS_MEMORY_ROUTINE)ReadProcessMemory, SymFunctionTableAccess, SymGetModuleBase, NULL);
		if (bRet == FALSE || stackFrame.AddrFrame.Offset == 0)
			break;

		DWORD dwModuleBase = SymGetModuleBase(GetCurrentProcess(), stackFrame.AddrPC.Offset);
		if (dwModuleBase == 0)
			break;

		//module name of call
		TCHAR szModuleName[MAX_PATH] = {0};
		GetModuleFileName((HMODULE)dwModuleBase, szModuleName, MAX_PATH);

		//funtion name
		DWORD dwDisp = 0;
		TCHAR szFuntionName[MAX_PATH+sizeof(IMAGEHLP_SYMBOL)] = {0};
		PIMAGEHLP_SYMBOL lpSymb = (PIMAGEHLP_SYMBOL)szFuntionName;
		lpSymb->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
		lpSymb->MaxNameLength = MAX_PATH;
		SymGetSymFromAddr(GetCurrentProcess(), stackFrame.AddrPC.Offset, &dwDisp, lpSymb);

		//line number and filename
		IMAGEHLP_LINE hlpLine;
		SymGetLineFromAddr(GetCurrentProcess(), (DWORD)stackFrame.AddrPC.Offset, &dwDisp, &hlpLine);
		WriteLogFile(hLogFile, "%s-%s %s::%d\r\n", lpSymb->Name, GetFilePart(szModuleName), hlpLine.FileName, hlpLine.LineNumber);
	} while (1);
}
Example #24
0
void write_stack_trace(PCONTEXT pContext, TextOutputStream& outputStream)
{
  HANDLE m_hProcess = GetCurrentProcess();
  DWORD dwMachineType = 0;

  CONTEXT context = *pContext;

  // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
  if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) )
  {
    return;
  }

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

#ifdef _M_IX86
  // Initialize the STACKFRAME structure for the first call.  This is only
  // necessary for Intel CPUs, and isn't mentioned in the documentation.
  sf.AddrPC.Offset       = context.Eip;
  sf.AddrPC.Mode         = AddrModeFlat;
  sf.AddrStack.Offset    = context.Esp;
  sf.AddrStack.Mode      = AddrModeFlat;
  sf.AddrFrame.Offset    = context.Ebp;
  sf.AddrFrame.Mode      = AddrModeFlat;

  dwMachineType = IMAGE_FILE_MACHINE_I386;
#endif

  while ( 1 )
  {
    // Get the next stack frame
    if ( ! StackWalk(  dwMachineType,
                        m_hProcess,
                        GetCurrentThread(),
                        &sf,
                        &context,
                        0,
                        SymFunctionTableAccess,
                        SymGetModuleBase,
                        0 ) )
        break;

    if ( 0 == sf.AddrFrame.Offset ) // Basic sanity check to make sure
      break;                      // the frame is OK.  Bail if not.

    // Get the name of the function for this stack frame entry
    BYTE symbolBuffer[ sizeof(SYMBOL_INFO) + MAX_SYM_NAME ];
    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = MAX_SYM_NAME;
                    
    DWORD64 symDisplacement = 0;    // Displacement of the input address,
                                    // relative to the start of the symbol

    IMAGEHLP_MODULE module = { sizeof(IMAGEHLP_MODULE) };
    if(SymGetModuleInfo(m_hProcess, sf.AddrPC.Offset, &module))
    {
      outputStream << module.ModuleName << "!";

      if ( SymFromAddr(m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol))
      {
        char undecoratedName[MAX_SYM_NAME];
        UnDecorateSymbolName(pSymbol->Name, undecoratedName, MAX_SYM_NAME, UNDNAME_COMPLETE);

        outputStream << undecoratedName;

        outputStream << "(";
        // Use SymSetContext to get just the locals/params for this frame
        IMAGEHLP_STACK_FRAME imagehlpStackFrame;
        imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
        SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );

        // Enumerate the locals/parameters
        EnumerateSymbolsContext context(sf, outputStream);
        SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context );
        outputStream << ")";

        outputStream << " + " << Offset(reinterpret_cast<void*>(symDisplacement));

        // Get the source line for this stack frame entry
        IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
        DWORD dwLineDisplacement;
        if ( SymGetLineFromAddr( m_hProcess, sf.AddrPC.Offset,
                                &dwLineDisplacement, &lineInfo ) )
        {
          outputStream << " " << lineInfo.FileName << " line " << Unsigned(lineInfo.LineNumber); 
        }
      }
      else
      {
        outputStream << Address(reinterpret_cast<void*>(sf.AddrPC.Offset));
      }
    }

    outputStream << "\n";
  }

  SymCleanup(m_hProcess);

  return;
}
Example #25
0
static void dumpBacktrace( unsigned int depth )
{
  if ( depth == 0 )
    depth = 20;

#if ((defined(linux) || defined(__linux__)) && !defined(ANDROID)) || defined(__FreeBSD__)
  int stderr_fd = -1;
  if ( access( "/usr/bin/c++filt", X_OK ) < 0 )
  {
    myPrint( "Stacktrace (c++filt NOT FOUND):\n" );
  }
  else
  {
    int fd[2];

    if ( pipe( fd ) == 0 && fork() == 0 )
    {
      close( STDIN_FILENO ); // close stdin

      // stdin from pipe
      if ( dup( fd[0] ) != STDIN_FILENO )
      {
        QgsDebugMsg( "dup to stdin failed" );
      }

      close( fd[1] );        // close writing end
      execl( "/usr/bin/c++filt", "c++filt", static_cast< char * >( nullptr ) );
      perror( "could not start c++filt" );
      exit( 1 );
    }

    myPrint( "Stacktrace (piped through c++filt):\n" );
    stderr_fd = dup( STDERR_FILENO );
    close( fd[0] );          // close reading end
    close( STDERR_FILENO );  // close stderr

    // stderr to pipe
    int stderr_new = dup( fd[1] );
    if ( stderr_new != STDERR_FILENO )
    {
      if ( stderr_new >= 0 )
        close( stderr_new );
      QgsDebugMsg( "dup to stderr failed" );
    }

    close( fd[1] );  // close duped pipe
  }

  void **buffer = new void *[ depth ];
  int nptrs = backtrace( buffer, depth );
  backtrace_symbols_fd( buffer, nptrs, STDERR_FILENO );
  delete [] buffer;
  if ( stderr_fd >= 0 )
  {
    int status;
    close( STDERR_FILENO );
    int dup_stderr = dup( stderr_fd );
    if ( dup_stderr != STDERR_FILENO )
    {
      close( dup_stderr );
      QgsDebugMsg( "dup to stderr failed" );
    }
    close( stderr_fd );
    wait( &status );
  }
#elif defined(Q_OS_WIN)
  void **buffer = new void *[ depth ];

  SymSetOptions( SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_UNDNAME );
  SymInitialize( GetCurrentProcess(), "http://msdl.microsoft.com/download/symbols;http://download.osgeo.org/osgeo4w/symstore", TRUE );

  unsigned short nFrames = CaptureStackBackTrace( 1, depth, buffer, nullptr );
  SYMBOL_INFO *symbol = ( SYMBOL_INFO * ) qgsMalloc( sizeof( SYMBOL_INFO ) + 256 );
  symbol->MaxNameLen = 255;
  symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
  IMAGEHLP_LINE *line = ( IMAGEHLP_LINE * ) qgsMalloc( sizeof( IMAGEHLP_LINE ) );
  line->SizeOfStruct = sizeof( IMAGEHLP_LINE );

  for ( int i = 0; i < nFrames; i++ )
  {
    DWORD dwDisplacement;
    SymFromAddr( GetCurrentProcess(), ( DWORD64 )( buffer[ i ] ), 0, symbol );
    symbol->Name[ 255 ] = 0;
    if ( SymGetLineFromAddr( GetCurrentProcess(), ( DWORD64 )( buffer[i] ), &dwDisplacement, line ) )
    {
      myPrint( "%s(%d) : (%s) frame %d, address %x\n", line->FileName, line->LineNumber, symbol->Name, i, symbol->Address );
    }
    else
    {
      myPrint( "%s(%d) : (%s) unknown source location, frame %d, address %x [GetLastError()=%d]\n", __FILE__, __LINE__, symbol->Name, i, symbol->Address, GetLastError() );
    }
  }

  qgsFree( symbol );
  qgsFree( line );
#else
  Q_UNUSED( depth );
#endif
}
Example #26
0
/* Runs a stack trace 
 * Parameters:
 *  e - The exception information
 * Returns:
 *  The stack trace with function and line number information
 */
__inline char *StackTrace(EXCEPTION_POINTERS *e) 
{
	static char buffer[5000];
	char curmodule[32];
	DWORD symOptions, dwDisp, frame;
	HANDLE hProcess = GetCurrentProcess();
	IMAGEHLP_SYMBOL *pSym = MyMallocEx(sizeof(IMAGEHLP_SYMBOL)+500);
	IMAGEHLP_LINE pLine;
	IMAGEHLP_MODULE pMod;
	STACKFRAME Stack;

	/* Load the stack information */
	memset(&Stack, 0, sizeof(Stack));
	Stack.AddrPC.Offset = e->ContextRecord->Eip;
	Stack.AddrPC.Mode = AddrModeFlat;
	Stack.AddrFrame.Offset = e->ContextRecord->Ebp;
	Stack.AddrFrame.Mode = AddrModeFlat;
	Stack.AddrStack.Offset = e->ContextRecord->Esp;
	Stack.AddrStack.Mode = AddrModeFlat;
	if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
		hProcess = (HANDLE)GetCurrentProcessId();
	else
		hProcess = GetCurrentProcess();	

	/* Initialize symbol retrieval system */
	SymInitialize(hProcess, NULL, TRUE);
	SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_UNDNAME);
	bzero(pSym, sizeof(IMAGEHLP_SYMBOL)+500);
	pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	pSym->MaxNameLength = 500;
	bzero(&pLine, sizeof(IMAGEHLP_LINE));
	pLine.SizeOfStruct = sizeof(IMAGEHLP_LINE);
	bzero(&pMod, sizeof(IMAGEHLP_MODULE));
	pMod.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	/* Retrieve the first module name */
	SymGetModuleInfo(hProcess, Stack.AddrPC.Offset, &pMod);
	strcpy(curmodule, pMod.ModuleName);
	sprintf(buffer, "\tModule: %s\n", pMod.ModuleName);

	/* Walk through the stack */
	for (frame = 0; ; frame++) 
	{
		char buf[500];
		if (!StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(),
			&Stack, NULL, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL))
			break;
		SymGetModuleInfo(hProcess, Stack.AddrPC.Offset, &pMod);
		if (strcmp(curmodule, pMod.ModuleName)) 
		{
			strcpy(curmodule, pMod.ModuleName);
			sprintf(buf, "\tModule: %s\n", pMod.ModuleName);
			strcat(buffer, buf);
		}
		SymGetLineFromAddr(hProcess, Stack.AddrPC.Offset, &dwDisp, &pLine);
		SymGetSymFromAddr(hProcess, Stack.AddrPC.Offset, &dwDisp, pSym);
		sprintf(buf, "\t\t#%d %s:%d: %s\n", frame, pLine.FileName, pLine.LineNumber, 
		        pSym->Name);
		strcat(buffer, buf);
	}
	return buffer;

}
Example #27
0
/***********************************************************************
 *              dbg_exception_prolog
 *
 * Examine exception and decide if interactive mode is entered(return TRUE)
 * or exception is silently continued(return FALSE)
 * is_debug means the exception is a breakpoint or single step exception
 */
static unsigned dbg_exception_prolog(BOOL is_debug, BOOL first_chance, const EXCEPTION_RECORD* rec)
{
    ADDRESS64   addr;
    BOOL        is_break;
    char        hexbuf[MAX_OFFSET_TO_STR_LEN];

    memory_get_current_pc(&addr);
    break_suspend_execution();
    dbg_curr_thread->excpt_record = *rec;
    dbg_curr_thread->in_exception = TRUE;

    if (!is_debug)
    {
        switch (addr.Mode)
        {
        case AddrModeFlat:
            dbg_printf(" in 32-bit code (%s)",
                       memory_offset_to_string(hexbuf, addr.Offset, 0));
            break;
        case AddrModeReal:
            dbg_printf(" in vm86 code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset);
            break;
        case AddrMode1616:
            dbg_printf(" in 16-bit code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset);
            break;
        case AddrMode1632:
            dbg_printf(" in 32-bit code (%04x:%08lx)", addr.Segment, (unsigned long) addr.Offset);
            break;
        default:
            dbg_printf(" bad address");
        }
        dbg_printf(".\n");
    }

    /* this will resynchronize builtin dbghelp's internal ELF module list */
    SymLoadModule(dbg_curr_process->handle, 0, 0, 0, 0, 0);

    if (is_debug) break_adjust_pc(&addr, rec->ExceptionCode, first_chance, &is_break);
    /*
     * Do a quiet backtrace so that we have an idea of what the situation
     * is WRT the source files.
     */
    stack_fetch_frames();

    if (is_debug && !is_break && break_should_continue(&addr, rec->ExceptionCode))
        return FALSE;

    if (addr.Mode != dbg_curr_thread->addr_mode)
    {
        const char* name = NULL;

        switch (addr.Mode)
        {
        case AddrMode1616:
            name = "16 bit";
            break;
        case AddrMode1632:
            name = "32 bit";
            break;
        case AddrModeReal:
            name = "vm86";
            break;
        case AddrModeFlat:
            name = "32 bit";
            break;
        }

        dbg_printf("In %s mode.\n", name);
        dbg_curr_thread->addr_mode = addr.Mode;
    }
    display_print();

    if (!is_debug)
    {
        /* This is a real crash, dump some info */
        be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0);
        stack_info();
        be_cpu->print_segment_info(dbg_curr_thread->handle, &dbg_context);
        stack_backtrace(dbg_curr_tid);
    }
    else
    {
        static char*        last_name;
        static char*        last_file;

        char                buffer[sizeof(SYMBOL_INFO) + 256];
        SYMBOL_INFO*        si = (SYMBOL_INFO*)buffer;
        void*               lin = memory_to_linear_addr(&addr);
        DWORD64             disp64;
        IMAGEHLP_LINE       il;
        DWORD               disp;

        si->SizeOfStruct = sizeof(*si);
        si->MaxNameLen   = 256;
        il.SizeOfStruct = sizeof(il);
        if (SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si) &&
                SymGetLineFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il))
        {
            if ((!last_name || strcmp(last_name, si->Name)) ||
                    (!last_file || strcmp(last_file, il.FileName)))
            {
                HeapFree(GetProcessHeap(), 0, last_name);
                HeapFree(GetProcessHeap(), 0, last_file);
                last_name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(si->Name) + 1), si->Name);
                last_file = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(il.FileName) + 1), il.FileName);
                dbg_printf("%s () at %s:%u\n", last_name, last_file, il.LineNumber);
            }
        }
    }
    if (!is_debug || is_break ||
            dbg_curr_thread->exec_mode == dbg_exec_step_over_insn ||
            dbg_curr_thread->exec_mode == dbg_exec_step_into_insn)
    {
        ADDRESS64 tmp = addr;
        /* Show where we crashed */
        memory_disasm_one_insn(&tmp);
    }
    source_list_from_addr(&addr, 0);

    return TRUE;
}
static void JKG_WriteStackCrawl( fileHandle_t *f, DWORD *stackCrawl )
{
	int i, dmod, gotsource, sourcedisp;
	HANDLE proc, thread;
	IMAGEHLP_LINE line;
	DWORD disp;
	char ModName[260];
	static char SymPath[4096];
	static char basepath[260];
	static char fspath[260];
	PIMAGEHLP_SYMBOL sym = (PIMAGEHLP_SYMBOL)malloc(1024);

	proc = GetCurrentProcess();
	thread = GetCurrentThread();

	SymPath[0] = 0;
	basepath[0] = 0;
	fspath[0] = 0;

	InitSymbolPath(SymPath, NULL);
	SymInitialize(proc, SymPath, TRUE);

	memset(sym, 0, 1024);
	sym->MaxNameLength = 800;
	sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);

	for(i = 0; i < MAX_JKG_ASSERT_STACK_CRAWL; i++)
	{
		if(stackCrawl[i] == 0)
			continue;
		
		// Grab the base address of the module that's the problem atm
		dmod = SymGetModuleBase(proc, stackCrawl[i]);
		if (!dmod) {
			strcpy(ModName,"Unknown");
		} else {
			GetModuleBaseName(proc,(HMODULE)dmod, ModName, 260);
		}
		
		if (SymGetLineFromAddr(proc, stackCrawl[i], (PDWORD)&sourcedisp, &line)) {
			gotsource = 1;
		} else {
			gotsource = 0;
		}

		if (SymGetSymFromAddr(proc, stackCrawl[i], &disp, sym)) {
			if (gotsource) {
				JKG_WriteToAssertLogEasy(va("%s::%s(+0x%X) [0x%08X] - (%s:%i)\r\n", ModName, sym->Name, disp, stackCrawl[i], line.FileName, line.LineNumber), f);
			} else {
				JKG_WriteToAssertLogEasy(va("%s::%s(+0x%X) [0x%08X]\r\n", ModName, sym->Name, disp, stackCrawl[i]), f);
			}
		} else {
			if (gotsource) {
				// Not likely...
				JKG_WriteToAssertLogEasy(va("%s [0x%08X] - (%s:%i)\r\n", ModName, stackCrawl[i], line.FileName, line.LineNumber), f);
			} else {
				JKG_WriteToAssertLogEasy(va("%s [0x%08X]\r\n", ModName, stackCrawl[i]), f);
			}
		}

	}
	free(sym);

	JKG_WriteToAssertLogEasy("\r\n", f);
}
Example #29
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;
    }
Example #30
0
/***********************************************************************
 *           symbol_get_line
 *
 * Find the symbol nearest to a given address.
 * Returns sourcefile name and line number in a format that the listing
 * handler can deal with.
 */
BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line)
{
    struct sgv_data     sgv;
    char                buffer[512];
    DWORD               opt, disp, linear;
    unsigned            i, found = FALSE;
    IMAGEHLP_LINE       il;

    sgv.num        = 0;
    sgv.num_thunks = 0;
    sgv.name       = &buffer[2];
    sgv.do_thunks  = FALSE;

    buffer[0] = '*';
    buffer[1] = '!';
    strcpy(&buffer[2], name);

    /* this is a wine specific options to return also ELF modules in the
     * enumeration
     */
    SymSetOptions((opt = SymGetOptions()) | 0x40000000);
    if (!SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv))
    {
        SymSetOptions(opt);
        return FALSE;
    }

    if (!sgv.num && (name[0] != '_'))
    {
        buffer[2] = '_';
        strcpy(&buffer[3], name);
        if (!SymEnumSymbols(dbg_curr_process->handle, 0, buffer, sgv_cb, (void*)&sgv))
        {
            SymSetOptions(opt);
            return FALSE;
        }
    }
    SymSetOptions(opt);

    for (i = 0; i < sgv.num; i++)
    {
        linear = (DWORD)memory_to_linear_addr(&sgv.syms[i].lvalue.addr);

        il.SizeOfStruct = sizeof(il);
        if (!SymGetLineFromAddr(dbg_curr_process->handle, linear, &disp, &il))
            continue;
        if (filename && strcmp(line->FileName, filename)) continue;
        if (found)
        {
            WINE_FIXME("Several found, returning first (may not be what you want)...\n");
            break;
        }
        found = TRUE;
        *line = il;
    }
    if (!found)
    {
        if (filename)   dbg_printf("No such function %s in %s\n", name, filename);
	else            dbg_printf("No such function %s\n", name);
        return FALSE;
    }
    return TRUE;
}