Exemple #1
0
static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
#ifdef _WIN32
	static HANDLE stack_process_handle = NULL;
	DWORD64 index;
	IMAGEHLP_LINEW64 line;
	struct {
		SYMBOL_INFOW sym;
		uchar buffer[256];
	} data;
	data.sym.SizeOfStruct = sizeof(data.sym);
	data.sym.MaxNameLen = 255;
	if( !stack_process_handle ) {
		stack_process_handle = GetCurrentProcess();
		SymSetOptions(SYMOPT_LOAD_LINES);
		SymInitialize(stack_process_handle,NULL,TRUE);
	}
	if( SymFromAddrW(stack_process_handle,(DWORD64)(int_val)addr,&index,&data.sym) ) {
		DWORD offset = 0;
		line.SizeOfStruct = sizeof(line);
		line.FileName = USTR("\\?");
		line.LineNumber = 0;
		SymGetLineFromAddrW64(stack_process_handle, (DWORD64)(int_val)addr, &offset, &line);
		*outSize = usprintf(out,*outSize,USTR("%s(%s:%d)"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber);
		return out;
	}
#endif
	return NULL;
}
const Symbol * const SymEngine::GetSymbol(DWORD64 dwAddress)
{
	if (dwAddress == 0)
		return nullptr;

	Symbol& symbol = cache[dwAddress];

	if (symbol.address != 0)
		return &symbol;

	if (!isInitialized)
		return nullptr;

	symbol.address = dwAddress;

	// Module Name
	IMAGEHLP_MODULEW64 moduleInfo;
	memset(&moduleInfo, 0, sizeof(IMAGEHLP_MODULEW64));
	moduleInfo.SizeOfStruct = sizeof(moduleInfo);
	if (SymGetModuleInfoW64(hProcess, dwAddress, &moduleInfo))
	{
		symbol.module = moduleInfo.ImageName;
	}


	// FileName and Line
	IMAGEHLP_LINEW64 lineInfo;
	memset(&lineInfo, 0, sizeof(IMAGEHLP_LINEW64));
	lineInfo.SizeOfStruct = sizeof(lineInfo);
	DWORD dwDisp;
	if (SymGetLineFromAddrW64(hProcess, dwAddress, &dwDisp, &lineInfo))
	{
		symbol.file = lineInfo.FileName;
		symbol.line = lineInfo.LineNumber;
	}

	const size_t length = (sizeof(SYMBOL_INFOW) + MAX_SYM_NAME*sizeof(WCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64) + 1;

	// Function Name
	ULONG64 buffer[length];
	PSYMBOL_INFOW dbgSymbol = (PSYMBOL_INFOW)buffer;
	memset(dbgSymbol, 0, sizeof(buffer));
	dbgSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
	dbgSymbol->MaxNameLen = MAX_SYM_NAME;
	if (SymFromAddrW(hProcess, dwAddress, &symbol.offset, dbgSymbol))
	{
		symbol.function.resize(dbgSymbol->NameLen);
		memcpy(&symbol.function[0], &dbgSymbol->Name[0], sizeof(WCHAR) * dbgSymbol->NameLen);
	}

	return &symbol;
}
bool SymGetSourceLine(uint Cip, char* FileName, int* Line)
{
    IMAGEHLP_LINEW64 lineInfo;
    memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64));

    lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    // Perform a symbol lookup from a specific address
    DWORD displacement;

    if(!SymGetLineFromAddrW64(fdProcessInfo->hProcess, Cip, &displacement, &lineInfo))
        return false;

    String NewFile = StringUtils::Utf16ToUtf8(lineInfo.FileName);

    // Copy line number if requested
    if(Line)
        *Line = lineInfo.LineNumber;

    // Copy file name if requested
    if(FileName)
    {
        // Check if it was a full path
        if(NewFile[1] == ':' && NewFile[2] == '\\')
        {
            // Success: no more parsing
            strcpy_s(FileName, MAX_STRING_SIZE, NewFile.c_str());
            return true;
        }

        // Construct full path from pdb path
        IMAGEHLP_MODULE64 modInfo;
        memset(&modInfo, 0, sizeof(IMAGEHLP_MODULE64));
        modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

        if(!SafeSymGetModuleInfo64(fdProcessInfo->hProcess, Cip, &modInfo))
            return false;

        // Strip the name, leaving only the file directory
        char* pdbFileName = strrchr(modInfo.LoadedPdbName, '\\');

        if(pdbFileName)
            pdbFileName[1] = '\0';

        // Copy back to the caller's buffer
        strcpy_s(FileName, MAX_STRING_SIZE, modInfo.LoadedPdbName);
        strcat_s(FileName, MAX_STRING_SIZE, NewFile.c_str());
    }

    return true;
}
Exemple #4
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;
}
void __addr2sym(IN tt_uintptr_t addr, IN tt_char_t *buf, IN tt_u32_t len)
{
    HANDLE proc;
    tt_u8_t tmp[sizeof(SYMBOL_INFO) + __SYM_SIZE + 1];
    PSYMBOL_INFO sym = (PSYMBOL_INFO)tmp;
    IMAGEHLP_LINEW64 line;
    DWORD64 addr_disp;
    DWORD disp2;
    tt_char_t *fname;

    proc = GetCurrentProcess();

    sym->SizeOfStruct = sizeof(SYMBOL_INFO);
    sym->MaxNameLen = __SYM_SIZE;
    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    if (!SymFromAddr(proc, addr, &addr_disp, sym)) {
        tt_snprintf(buf, len - 1, "%p", addr);
    } else if (!SymGetLineFromAddrW64(proc, addr, &disp2, &line) ||
               ((fname = tt_utf8_create(line.FileName, 0, NULL)) == NULL)) {
        tt_snprintf(buf,
                    len - 1,
                    "%p in %s(+0x%x)",
                    addr,
                    sym->Name,
                    addr_disp);
    } else {
        tt_snprintf(buf,
                    len - 1,
                    "%p in %s() at [%s:%d]",
                    addr,
                    sym->Name,
                    fname,
                    line.LineNumber);
        tt_free(fname);
    }
}
// Resolve - Creates a nicely formatted rendition of the CallStack, including
//   symbolic information (function names and line numbers) if available. and 
//   saves it for later retrieval. This is almost identical to Callstack::dump above.
//
//   Note: The symbol handler must be initialized prior to calling this
//     function.
//
//  - showInternalFrames (IN): If true, then all frames in the CallStack will be
//      dumped. Otherwise, frames internal to the heap will not be dumped.
//
//  Return Value:
//
//    None.
//
void CallStack::resolve(BOOL showInternalFrames)
{
    if (m_resolved)
    {
        // already resolved, no need to do it again
        // resolving twice may report an incorrect module for the stack frames
        // if the memory was leaked in a dynamic library that was already unloaded.
        return;
    }
    if (m_status & CALLSTACK_STATUS_INCOMPLETE) {
        // This call stack appears to be incomplete. Using StackWalk64 may be
        // more reliable.
        Report(L"    HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n"
            L"      in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n"
            L"      complete stack trace.\n");
    }

    IMAGEHLP_LINE64  sourceInfo = { 0 };
    sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 };
    
    WCHAR callingModuleName [MAX_PATH] = L"";
    WCHAR lowerCaseName [MAX_PATH];

    const size_t max_line_length = MAXREPORTLENGTH + 1;
    m_resolvedCapacity = m_size * max_line_length;
    m_resolved = new WCHAR[m_resolvedCapacity];
    const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR);
    ZeroMemory(m_resolved, allocedBytes);
    
    // Iterate through each frame in the call stack.
    for (UINT32 frame = 0; frame < m_size; frame++)
    {
        // Try to get the source file and line number associated with
        // this program counter address.
        SIZE_T programCounter = (*this)[frame];
        g_symbolLock.Enter();
        BOOL             foundline = FALSE;
        DWORD            displacement = 0;

        // 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.
        DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId());
        foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo);
        assert(m_resolved != NULL);

        if (foundline && !showInternalFrames) {
            wcscpy_s(lowerCaseName, sourceInfo.FileName);
            _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1);
            if (isInternalModule(lowerCaseName)) {
                // Don't show frames in files internal to the heap.
                g_symbolLock.Leave();
                continue;
            }
        }

        // Initialize structures passed to the symbol handler.
        SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer;
        functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
        functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH;

        // Try to get the name of the function containing this program
        // counter address.
        DWORD64          displacement64 = 0;
        LPWSTR           functionName;
        DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId());
        if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) {
            functionName = functionInfo->Name;
        }
        else {
            // GetFormattedMessage( GetLastError() );
            functionName = L"(Function name unavailable)";
            displacement64 = 0;
        }
        g_symbolLock.Leave();

        HMODULE hCallingModule = GetCallingModule(programCounter);
        LPWSTR moduleName = L"(Module name unavailable)";
        if (hCallingModule && 
            GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0)
        {
            moduleName = wcsrchr(callingModuleName, L'\\');
            if (moduleName == NULL)
                moduleName = wcsrchr(callingModuleName, L'/');
            if (moduleName != NULL)
                moduleName++;
            else
                moduleName = callingModuleName;
        }

        // Use static here to increase performance, and avoid heap allocs. Hopefully this won't
        // prove to be an issue in thread safety. If it does, it will have to be simply non-static.
        static WCHAR stack_line[max_line_length] = L"";
        int NumChars = -1;
        // Display the current stack frame's information.
        if (foundline) {
            // Just truncate anything that is too long.
            if (displacement == 0)
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    %s (%d): %s!%s\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    %s (%d): %s!%s + 0x%X bytes\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement);
        }
        else {
            if (displacement64 == 0)
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", 
                programCounter, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_line_length, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", 
                programCounter, moduleName, functionName, (DWORD)displacement64);
        }

        if (NumChars >= 0) {
            assert(m_resolved != NULL);
            m_resolvedLength += NumChars;
            wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars);
        }
    } // end for loop
}
// dump - Dumps a nicely formatted rendition of the CallStack, including
//   symbolic information (function names and line numbers) if available.
//
//   Note: The symbol handler must be initialized prior to calling this
//     function.
//
//  - showinternalframes (IN): If true, then all frames in the CallStack will be
//      dumped. Otherwise, frames internal to the heap will not be dumped.
//
//  Return Value:
//
//    None.
//
void CallStack::dump(BOOL showInternalFrames, UINT start_frame) const
{
    // The stack was dumped already
    if (m_resolved)
    {
        dumpResolved();
        return;
    }

    if (m_status & CALLSTACK_STATUS_INCOMPLETE) {
        // This call stack appears to be incomplete. Using StackWalk64 may be
        // more reliable.
        Report(L"    HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n"
            L"      in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n"
            L"      complete stack trace.\n");
    }

    IMAGEHLP_LINE64  sourceInfo = { 0 };
    sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    BYTE symbolBuffer [sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE] = { 0 };

    WCHAR lowerCaseName [MAX_PATH];
    WCHAR callingModuleName [MAX_PATH];

    const size_t max_size = MAXREPORTLENGTH + 1;

    // Iterate through each frame in the call stack.
    for (UINT32 frame = start_frame; frame < m_size; frame++)
    {
        // Try to get the source file and line number associated with
        // this program counter address.
        SIZE_T programCounter = (*this)[frame];
        g_symbolLock.Enter();
        BOOL             foundline = FALSE;
        DWORD            displacement = 0;
        DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId());
        foundline = SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo);
        if (foundline && !showInternalFrames) {
            wcscpy_s(lowerCaseName, sourceInfo.FileName);
            _wcslwr_s(lowerCaseName, wcslen(lowerCaseName) + 1);
            if (isInternalModule(lowerCaseName)) {
                // Don't show frames in files internal to the heap.
                g_symbolLock.Leave();
                continue;
            }
        }

        // Initialize structures passed to the symbol handler.
        SYMBOL_INFO* functionInfo = (SYMBOL_INFO*)&symbolBuffer;
        functionInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
        functionInfo->MaxNameLen = MAX_SYMBOL_NAME_LENGTH;

        // Try to get the name of the function containing this program
        // counter address.
        DWORD64          displacement64 = 0;
        LPWSTR           functionName;
        DbgTrace(L"dbghelp32.dll %i: SymFromAddrW\n", GetCurrentThreadId());
        if (SymFromAddrW(g_currentProcess, programCounter, &displacement64, functionInfo)) {
            functionName = functionInfo->Name;
        }
        else {
            // GetFormattedMessage( GetLastError() );
            functionName = L"(Function name unavailable)";
            displacement64 = 0;
        }
        g_symbolLock.Leave();

        HMODULE hCallingModule = GetCallingModule(programCounter);
        LPWSTR moduleName = L"(Module name unavailable)";
        if (hCallingModule && 
            GetModuleFileName(hCallingModule, callingModuleName, _countof(callingModuleName)) > 0)
        {
            moduleName = wcsrchr(callingModuleName, L'\\');
            if (moduleName == NULL)
                moduleName = wcsrchr(callingModuleName, L'/');
            if (moduleName != NULL)
                moduleName++;
            else
                moduleName = callingModuleName;
        }

        // Use static here to increase performance, and avoid heap allocs. Hopefully this won't
        // prove to be an issue in thread safety. If it does, it will have to be simply non-static.
        static WCHAR stack_line[MAXREPORTLENGTH + 1] = L"";
        int NumChars = -1;
        // Display the current stack frame's information.
        if (foundline) {
            if (displacement == 0)
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    %s (%d): %s!%s\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    %s (%d): %s!%s + 0x%X bytes\n", 
                sourceInfo.FileName, sourceInfo.LineNumber, moduleName, functionName, displacement);
        }
        else {
            if (displacement64 == 0)
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s\n", 
                programCounter, moduleName, functionName);
            else
                NumChars = _snwprintf_s(stack_line, max_size, _TRUNCATE, L"    " ADDRESSFORMAT L" (File and line number not available): %s!%s + 0x%X bytes\n", 
                programCounter, moduleName, functionName, (DWORD)displacement64);	
        }

        Print(stack_line);
    }
}
void qtDLGCallstack::ShowCallStack()
{
	clsDebugger *pDebugger = qtDLGNanomite::GetInstance()->coreDebugger;
	
	HANDLE	hProc = pDebugger->GetCurrentProcessHandle(),
			hThread = OpenThread(THREAD_GETSET_CONTEXT,false,pDebugger->GetCurrentTID());
	PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
	DWORD dwMaschineMode = NULL;
	LPVOID pContext;
	STACKFRAME64 stackFr = {0};
	stackFr.AddrPC.Mode = AddrModeFlat;
	stackFr.AddrFrame.Mode = AddrModeFlat;
	stackFr.AddrStack.Mode = AddrModeFlat;

	QString sFuncName,
		sFuncMod,
		sReturnToFunc,
		sReturnToMod;
	quint64 dwStackAddr,
		dwReturnTo,
		dwEIP,
		dwDisplacement;
	IMAGEHLP_LINEW64 imgSource = {0};
	IMAGEHLP_MODULEW64 imgMod = {0};

#ifdef _AMD64_
	BOOL bIsWOW64 = false;

	if(clsAPIImport::pIsWow64Process)
		clsAPIImport::pIsWow64Process(hProc,&bIsWOW64);

	if(bIsWOW64)
	{
		dwMaschineMode = IMAGE_FILE_MACHINE_I386;
		WOW64_CONTEXT cTT = pDebugger->wowProcessContext;
		pContext = &cTT;

		stackFr.AddrPC.Offset = cTT.Eip;
		stackFr.AddrFrame.Offset = cTT.Ebp;
		stackFr.AddrStack.Offset = cTT.Esp;	
	}
	else
	{
		dwMaschineMode = IMAGE_FILE_MACHINE_AMD64;
		CONTEXT cTT = pDebugger->ProcessContext;
		pContext = &cTT;

		stackFr.AddrPC.Offset = cTT.Rip;
		stackFr.AddrFrame.Offset = cTT.Rbp;
		stackFr.AddrStack.Offset = cTT.Rsp;	
	}
#else
	dwMaschineMode = IMAGE_FILE_MACHINE_I386;
	CONTEXT cTT = pDebugger->ProcessContext;
	pContext = &cTT;

	stackFr.AddrPC.Offset = cTT.Eip;
	stackFr.AddrFrame.Offset = cTT.Ebp;
	stackFr.AddrStack.Offset = cTT.Esp;	

#endif

	tblCallstack->setRowCount(0);

	do
	{
		if(!StackWalk64(dwMaschineMode,hProc,hThread,&stackFr,pContext,NULL,SymFunctionTableAccess64,SymGetModuleBase64,0))        
			break;

		memset(&imgSource,0,sizeof(IMAGEHLP_LINEW64));
		imgSource.SizeOfStruct = sizeof(IMAGEHLP_LINEW64);

		dwStackAddr = stackFr.AddrStack.Offset;
		dwEIP = stackFr.AddrPC.Offset;
		dwReturnTo = stackFr.AddrReturn.Offset;


		memset(&imgMod,0,sizeof(IMAGEHLP_MODULEW64));
		imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
		memset(pSymbol,0,sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
		pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
		pSymbol->MaxNameLen = MAX_PATH;

		SymGetModuleInfoW64(hProc,dwEIP,&imgMod);
		SymFromAddrW(hProc,dwEIP,&dwDisplacement,pSymbol);
		sFuncName = QString::fromWCharArray(pSymbol->Name);
		sFuncMod = QString::fromWCharArray(imgMod.ModuleName);


		memset(&imgMod,0,sizeof(IMAGEHLP_MODULEW64));
		imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
		memset(pSymbol,0,sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
		pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
		pSymbol->MaxNameLen = MAX_PATH;

		SymGetModuleInfoW64(hProc,dwReturnTo,&imgMod);
		SymFromAddrW(hProc,dwReturnTo,&dwDisplacement,pSymbol);
		sReturnToMod = QString::fromWCharArray(imgMod.ModuleName);
		sReturnToFunc = QString::fromWCharArray(pSymbol->Name);

		if(SymGetLineFromAddrW64(hProc,dwEIP,(PDWORD)&dwDisplacement,&imgSource))
		{
			OnCallStack(dwStackAddr,
				dwReturnTo,sReturnToFunc,sReturnToMod,
				dwEIP,sFuncName,sFuncMod,
				QString::fromWCharArray(imgSource.FileName),imgSource.LineNumber);
		}
		else
		{
			OnCallStack(dwStackAddr,
				dwReturnTo,sReturnToFunc,sReturnToMod,
				dwEIP,sFuncName,sFuncMod,
				QString(""),0);
		}

	}while(stackFr.AddrReturn.Offset != 0);

	free(pSymbol);
	CloseHandle(hThread);
}
void clsCallstackWorker::run()
{
    HANDLE hThread = OpenThread(THREAD_GETSET_CONTEXT, false, m_processingData.threadID);
    PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)malloc(sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
    DWORD dwMaschineMode = NULL;
    quint64 dwDisplacement = NULL;
    LPVOID pContext;
    QList<callstackDisplay> callstackDisplayData;
    callstackDisplay newDisplayData = { 0 };
    STACKFRAME64 stackFr = { 0 };
    IMAGEHLP_LINEW64 imgSource = { 0 };
    IMAGEHLP_MODULEW64 imgMod = { 0 };

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

#ifdef _AMD64_
    if(m_processingData.isWOW64)
    {
        dwMaschineMode = IMAGE_FILE_MACHINE_I386;
        WOW64_CONTEXT cTT = m_processingData.wowProcessContext;
        pContext = &cTT;

        stackFr.AddrPC.Offset = cTT.Eip;
        stackFr.AddrFrame.Offset = cTT.Ebp;
        stackFr.AddrStack.Offset = cTT.Esp;
    }
    else
    {
        dwMaschineMode = IMAGE_FILE_MACHINE_AMD64;
        CONTEXT cTT = m_processingData.processContext;
        pContext = &cTT;

        stackFr.AddrPC.Offset = cTT.Rip;
        stackFr.AddrFrame.Offset = cTT.Rbp;
        stackFr.AddrStack.Offset = cTT.Rsp;
    }
#else
    dwMaschineMode = IMAGE_FILE_MACHINE_I386;
    CONTEXT cTT = m_processingData.processContext;
    pContext = &cTT;

    stackFr.AddrPC.Offset = cTT.Eip;
    stackFr.AddrFrame.Offset = cTT.Ebp;
    stackFr.AddrStack.Offset = cTT.Esp;

#endif

    do
    {
        if(!StackWalk64(dwMaschineMode, m_processingData.processHandle, hThread, &stackFr, pContext, NULL, SymFunctionTableAccess64, SymGetModuleBase64, 0))
            break;

        memset(&imgSource, 0, sizeof(IMAGEHLP_LINEW64));
        imgSource.SizeOfStruct = sizeof(IMAGEHLP_LINEW64);

        newDisplayData.stackAddress		= stackFr.AddrStack.Offset;
        newDisplayData.currentOffset	= stackFr.AddrPC.Offset;
        newDisplayData.returnOffset		= stackFr.AddrReturn.Offset;


        memset(&imgMod, 0, sizeof(IMAGEHLP_MODULEW64));
        imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
        memset(pSymbol, 0, sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
        pSymbol->MaxNameLen = MAX_PATH;

        SymGetModuleInfoW64(m_processingData.processHandle, newDisplayData.currentOffset, &imgMod);
        SymFromAddrW(m_processingData.processHandle, newDisplayData.currentOffset, &dwDisplacement, pSymbol);
        newDisplayData.currentFunctionName = QString::fromWCharArray(pSymbol->Name);
        newDisplayData.currentModuleName = QString::fromWCharArray(imgMod.ModuleName);


        memset(&imgMod, 0, sizeof(IMAGEHLP_MODULEW64));
        imgMod.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64);
        memset(pSymbol, 0, sizeof(SYMBOL_INFOW) + MAX_PATH * 2);
        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
        pSymbol->MaxNameLen = MAX_PATH;

        SymGetModuleInfoW64(m_processingData.processHandle, newDisplayData.returnOffset, &imgMod);
        SymFromAddrW(m_processingData.processHandle, newDisplayData.returnOffset , &dwDisplacement, pSymbol);
        newDisplayData.returnModuleName = QString::fromWCharArray(imgMod.ModuleName);
        newDisplayData.returnFunctionName = QString::fromWCharArray(pSymbol->Name);

        if(SymGetLineFromAddrW64(m_processingData.processHandle, newDisplayData.currentOffset, (PDWORD)&dwDisplacement, &imgSource))
        {

            newDisplayData.sourceFilePath		= QString::fromWCharArray(imgSource.FileName);
            newDisplayData.sourceLineNumber		= imgSource.LineNumber;
        }
        else
        {
            newDisplayData.sourceFilePath		= "";
            newDisplayData.sourceLineNumber		= 0;
        }

        callstackDisplayData.append(newDisplayData);

    } while(stackFr.AddrReturn.Offset != 0);

    free(pSymbol);
    CloseHandle(hThread);

    emit OnCallstackFinished(callstackDisplayData);
}