int CMiniDumpReader::ReadModuleListStream()
{
    LPVOID pStreamStart = NULL;
    ULONG uStreamSize = 0;
    MINIDUMP_DIRECTORY* pmd = NULL;
    BOOL bRead = FALSE;
    strconv_t strconv;

    bRead = MiniDumpReadDumpStream(
        m_pMiniDumpStartPtr, 
        ModuleListStream, 
        &pmd, 
        &pStreamStart, 
        &uStreamSize);

    if(bRead)
    {
        MINIDUMP_MODULE_LIST* pModuleStream = (MINIDUMP_MODULE_LIST*)pStreamStart;
        if(pModuleStream!=NULL)
        {
            ULONG32 uNumberOfModules = pModuleStream->NumberOfModules;
            ULONG32 i;
            for(i=0; i<uNumberOfModules; i++)
            {
                MINIDUMP_MODULE* pModule = 
                    (MINIDUMP_MODULE*)((LPBYTE)pModuleStream->Modules+i*sizeof(MINIDUMP_MODULE));

                CString sModuleName = GetMinidumpString(m_pMiniDumpStartPtr, pModule->ModuleNameRva);               
                LPCWSTR szModuleName = strconv.t2w(sModuleName);
                DWORD64 dwBaseAddr = pModule->BaseOfImage;
                DWORD64 dwImageSize = pModule->SizeOfImage;

                CString sShortModuleName = sModuleName;
                int pos = -1;
                pos = sModuleName.ReverseFind('\\');
                if(pos>=0)
                    sShortModuleName = sShortModuleName.Mid(pos+1);          

                /*DWORD64 dwLoadResult = */SymLoadModuleExW(
                    m_DumpData.m_hProcess,
                    NULL,
                    (PWSTR)szModuleName,
                    NULL,
                    dwBaseAddr,
                    (DWORD)dwImageSize,
                    NULL,
                    0);         

                IMAGEHLP_MODULE64 modinfo;
                memset(&modinfo, 0, sizeof(IMAGEHLP_MODULE64));
                modinfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
                BOOL bModuleInfo = SymGetModuleInfo64(m_DumpData.m_hProcess,
                    dwBaseAddr, 
                    &modinfo);
                MdmpModule m;
                if(!bModuleInfo)
                {          
                    m.m_bImageUnmatched = TRUE;
                    m.m_bNoSymbolInfo = TRUE;
                    m.m_bPdbUnmatched = TRUE;
                    m.m_pVersionInfo = NULL;
                    m.m_sImageName = sModuleName;
                    m.m_sModuleName = sShortModuleName;
                    m.m_uBaseAddr = dwBaseAddr;
                    m.m_uImageSize = dwImageSize;          
                }
                else
                {          
                    m.m_uBaseAddr = modinfo.BaseOfImage;
                    m.m_uImageSize = modinfo.ImageSize;        
                    m.m_sModuleName = sShortModuleName;
                    m.m_sImageName = modinfo.ImageName;
                    m.m_sLoadedImageName = modinfo.LoadedImageName;
                    m.m_sLoadedPdbName = modinfo.LoadedPdbName;
                    m.m_pVersionInfo = &pModule->VersionInfo;
                    m.m_bPdbUnmatched = modinfo.PdbUnmatched;          
                    BOOL bTimeStampMatched = pModule->TimeDateStamp == modinfo.TimeDateStamp;
                    m.m_bImageUnmatched = !bTimeStampMatched;
                    m.m_bNoSymbolInfo = !modinfo.GlobalSymbols;
                }        

                m_DumpData.m_Modules.push_back(m);
                m_DumpData.m_ModuleIndex[m.m_uBaseAddr] = m_DumpData.m_Modules.size()-1;          

                CString sMsg;
                if(m.m_bImageUnmatched)
                    sMsg.Format(_T("Loaded '*%s'"), sModuleName);
                else
                    sMsg.Format(_T("Loaded '%s'"), m.m_sLoadedImageName);

                if(m.m_bImageUnmatched)
                    sMsg += _T(", No matching binary found.");          
                else if(m.m_bPdbUnmatched)
                    sMsg += _T(", No matching PDB file found.");          
                else
                {
                    if(m.m_bNoSymbolInfo)            
                        sMsg += _T(", No symbols loaded.");          
                    else
                        sMsg += _T(", Symbols loaded.");          
                }
                m_DumpData.m_LoadLog.push_back(sMsg);
            }
        }
    }
    else
    {
        return 1;
    }

    return 0;
}
Example #2
0
/******************************************************************
 *		break_delete_xpoints_from_module
 *
 * Remove all Xpoints from module which base is 'base'
 */
void break_delete_xpoints_from_module(DWORD64 base)
{
    IMAGEHLP_MODULE64           im, im_elf;
    int                         i;
    DWORD_PTR                   linear;
    struct dbg_breakpoint*      bp = dbg_curr_process->bp;

    /* FIXME: should do it also on the ELF sibling if any */
    im.SizeOfStruct = sizeof(im);
    im_elf.SizeOfStruct = sizeof(im_elf);
    if (!SymGetModuleInfo64(dbg_curr_process->handle, base, &im)) return;

    /* try to get in fact the underlying ELF module (if any) */
    if (SymGetModuleInfo64(dbg_curr_process->handle, im.BaseOfImage - 1, &im_elf) &&
        im_elf.BaseOfImage <= im.BaseOfImage &&
        im_elf.BaseOfImage + im_elf.ImageSize >= im.BaseOfImage + im.ImageSize)
        im = im_elf;

    for (i = 0; i < dbg_curr_process->next_bp; i++)
    {
        if (bp[i].refcount && bp[i].enabled)
        {
            linear = (DWORD_PTR)memory_to_linear_addr(&bp[i].addr);
            if (im.BaseOfImage <= linear && linear < im.BaseOfImage + im.ImageSize)
            {
                break_delete_xpoint(i);
            }
        }
    }
}
Example #3
0
            std::string format_address_win32(const void* addr) const
            {
                if (!dbghelp.initialized())
                    return format_address_fallback(addr);

                DWORD64 symbol_info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
                const auto symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buf);
                symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
                symbol_info->MaxNameLen = MAX_SYM_NAME;

                IMAGEHLP_MODULE64 module_info;
                module_info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

                DWORD64 symbol_offset;

                const auto symbol_resolved = SymFromAddr(
                    GetCurrentProcess(),
                    reinterpret_cast<DWORD64>(addr),
                    &symbol_offset,
                    symbol_info);

                if (symbol_resolved)
                {
                    const auto module_resolved = SymGetModuleInfo64(
                        GetCurrentProcess(),
                        symbol_info->ModBase,
                        &module_info);

                    if (module_resolved)
                    {
                        return format_symbol(
                            module_info.ModuleName,
                            symbol_info->Name,
                            reinterpret_cast<const void*>(symbol_offset));
                    }
                    else
                    {
                        return format_symbol(symbol_info->Name, addr);
                    }
                }
                else
                {
                    const auto module_resolved = SymGetModuleInfo64(
                        GetCurrentProcess(),
                        reinterpret_cast<DWORD64>(addr),
                        &module_info);

                    if (module_resolved)
                    {
                        const auto module_offset = reinterpret_cast<const char*>(addr) - module_info.BaseOfImage;
                        return format_module(module_info.ModuleName, module_offset);
                    }
                    else
                    {
                        return format_address_fallback(addr);
                    }
                }
            }
Example #4
0
bool CSymbolEngine::GetModuleInfo( DWORD64 Addr, IMAGEHLP_MODULE64& Info )
{
	// Check preconditions 

	if( m_hProcess == NULL )
	{
		_ASSERTE( !_T("Symbol engine is not yet initialized.") );
		m_LastError = ERROR_INVALID_FUNCTION;
		return false;
	}


	// Obtain module information

	memset( &Info, 0, sizeof(Info) );

	Info.SizeOfStruct = sizeof(Info);

	if( !SymGetModuleInfo64( m_hProcess, Addr, &Info ) )
	{
		m_LastError = GetLastError();
		_ASSERTE( !_T("SymGetModuleInfo64() failed.") );
		return false;
	}

	return true;
}
Example #5
0
void GetSourceFileInfo(DWORD64 dw64Address, FILE * fw) {
    IMAGEHLP_LINE64 il64LineInfo;
	memset(&il64LineInfo, 0, sizeof(IMAGEHLP_LINE64));
	il64LineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    DWORD dwDisplacement = 0;

	if(SymGetLineFromAddr64(GetCurrentProcess(), dw64Address, &dwDisplacement, &il64LineInfo) == TRUE) {
        // We have sourcefile and linenumber info, write it.
        fprintf(fw, "%s(%d): ", il64LineInfo.FileName, il64LineInfo.LineNumber);
	} else {
        // We don't have sourcefile and linenumber info, let's try module name

        IMAGEHLP_MODULE64 im64ModuleInfo;
        memset(&im64ModuleInfo, 0, sizeof(IMAGEHLP_MODULE64));
        im64ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

        if(SymGetModuleInfo64(GetCurrentProcess(), dw64Address, &im64ModuleInfo)) {
            // We found module name, write module name and address
            fprintf(fw, "%s|0x%08I64X: ", im64ModuleInfo.ModuleName, dw64Address);
        } else {
            // We don't found module. Write address, it's better than nothing
            fprintf(fw, "0x%08I64X: ", dw64Address);
        }
	}
}
Example #6
0
static BOOL CALLBACK mod_loader_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
{
    struct mod_loader_info*     mli = ctx;

    if (!strcmp(mod_name, "<wine-loader>"))
    {
        if (SymGetModuleInfo64(mli->handle, base, mli->imh_mod))
            return FALSE; /* stop enum */
    }
    return TRUE;
}
Example #7
0
	void PlatformStack::ProgramAddressToSymbolInfo(uint64 address, SymbolInfo& oSymbolInfo)
	{
		InitSysStack();

		oSymbolInfo.Address = address;

		uint32 lastError = 0;
		HANDLE processHandle = GetCurrentProcess();

		ansichar symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + SymbolInfo::MAX_NAME_LENGHT] = { 0 };
		IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)symbolBuffer;
		symbol->SizeOfStruct = sizeof(symbolBuffer);
		symbol->MaxNameLength = SymbolInfo::MAX_NAME_LENGHT;

		if (SymGetSymFromAddr64(processHandle, address, nullptr, symbol))
		{
			int32 offset = 0;
			while (symbol->Name[offset] < 32 || symbol->Name[offset] > 127)
			{
				offset++;
			}

			strncpy(oSymbolInfo.FunctionName, symbol->Name + offset, SymbolInfo::MAX_NAME_LENGHT);
			strncat(oSymbolInfo.FunctionName, "()", SymbolInfo::MAX_NAME_LENGHT);
		}
		else
		{
			lastError = GetLastError();
		}

		IMAGEHLP_LINE64	imageHelpLine = { 0 };
		imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);
		if (SymGetLineFromAddr64(processHandle, address, (::DWORD *)&oSymbolInfo.SymbolDisplacement, &imageHelpLine))
		{
			strncpy(oSymbolInfo.FileName, imageHelpLine.FileName, SymbolInfo::MAX_NAME_LENGHT);
			oSymbolInfo.LineNumber = imageHelpLine.LineNumber;
		}
		else
		{
			lastError = GetLastError();
		}

		IMAGEHLP_MODULE64 imageHelpModule = { 0 };
		imageHelpModule.SizeOfStruct = sizeof(imageHelpModule);
		if (SymGetModuleInfo64(processHandle, address, &imageHelpModule))
		{
			strncpy(oSymbolInfo.ModuleName, imageHelpModule.ImageName, SymbolInfo::MAX_NAME_LENGHT);
		}
		else
		{
			lastError = GetLastError();
		}
	}
QString AbstractBTGenerator::GetModulePath()
{
    IMAGEHLP_MODULE64 module;
    ZeroMemory(&module, sizeof(module));
    module.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

    if (!SymGetModuleInfo64(m_process.GetHandle(), m_currentFrame.AddrPC.Offset, &module))
    {
        qCritical() << "SymGetModuleInfo64 failed: " << GetLastError();
        return QLatin1String(DEFAULT_MODULE);
    }

    return QString(module.ImageName);
}
void CDebugger::PrintCallStack(DWORD dwThreadId, DWORD dwProcessId) {
    STACKFRAME64 stackFrame = { 0 };
    const DWORD_PTR dwMaxFrames = 50;

    UpdateContext(dwThreadId);

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

    DWORD dwMachineType = IMAGE_FILE_MACHINE_I386;
    stackFrame.AddrPC.Offset = m_context.Eip;
    stackFrame.AddrFrame.Offset = m_context.Ebp;
    stackFrame.AddrStack.Offset = m_context.Esp;

    HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, dwThreadId);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);

    m_pSymbols->RefreshSymbols(hProcess);

    // Print call stack
    stringstream ssCallStack;
    for (int i = 0; i < dwMaxFrames; ++i) {
        bool bSuccess = StackWalk64(dwMachineType, hProcess, hThread, &stackFrame,
            (dwMachineType == IMAGE_FILE_MACHINE_I386 ? nullptr : &m_context), nullptr,
            SymFunctionTableAccess64, SymGetModuleBase64, nullptr);
        if (!bSuccess || stackFrame.AddrPC.Offset == 0) {
            cout <<  "StackWalk64 finished." << endl;
            break;
        }

        IMAGEHLP_MODULE64 module = {0};
        module.SizeOfStruct = sizeof(module);
        SymGetModuleInfo64(hProcess, (DWORD64)stackFrame.AddrPC.Offset, &module);

        //SymLoadModuleEx(hProcess, NULL, module.LoadedImageName, NULL, module.BaseOfImage,  0,  NULL, 0);
        //cout << "modulePath: " << module.LoadedImageName << ", baseofdll: " << module.BaseOfImage << ", symbol: " << module.LoadedPdbName << endl;
        PSYMBOL_INFO pSymInfo = m_pSymbols->SymbolFromAddress(stackFrame.AddrPC.Offset);
        if (pSymInfo) {
            ssCallStack << "#" << dec << i << " " <<  module.ModuleName << "!" << pSymInfo->Name << endl;
        } else {
            ssCallStack << "#" << dec << i << " " <<  module.ModuleName << "!" << "unknown" << endl;
        }

        delete pSymInfo;
    }

    m_pCrash->GetHash(ssCallStack.str());
    m_pCrash->AddLog("\nCall Stack\n" + ssCallStack.str());
}
Example #10
0
char *Pobjname(struct ps_prochandle *P, uintptr_t addr, char *buffer, size_t bufsize)
{
    IMAGEHLP_MODULE64 info;
    info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

    if (SymGetModuleInfo64(P->phandle, (DWORD64) addr, &info) == FALSE) {
        dprintf("SymGetModuleInfo64 failed (%d): %x\n", P->pid, GetLastError());
        buffer[0] = 0;
        return NULL;
    }

    strncpy(buffer, info.ModuleName, bufsize);
    buffer[bufsize-1] = 0;
    return buffer;
}
Example #11
0
 /**
  * Get the display name of the executable module containing the specified address.
  * 
  * @param process               Process handle
  * @param address               Address to find
  * @param returnedModuleName    Returned module name
  */
 static void getModuleName( HANDLE process, DWORD64 address, std::string* returnedModuleName ) {
     IMAGEHLP_MODULE64 module64;
     memset ( &module64, 0, sizeof(module64) );
     module64.SizeOfStruct = sizeof(module64);
     BOOL ret = SymGetModuleInfo64( process, address, &module64 );
     if ( FALSE == ret ) {
         returnedModuleName->clear();
         return;
     }
     char* moduleName = module64.LoadedImageName;
     char* backslash = strrchr( moduleName, '\\' );
     if ( backslash ) {
         moduleName = backslash + 1;
     }
     *returnedModuleName = moduleName;
 }
QString org_blueberry_core_runtime_Activator::getPluginId(void *symbol)
{
  if (symbol == NULL) return QString();

  if (ctk::DebugSymInitialize())
  {
    std::vector<char> moduleBuffer(sizeof(IMAGEHLP_MODULE64));
    PIMAGEHLP_MODULE64 pModuleInfo = (PIMAGEHLP_MODULE64)&moduleBuffer.front();
    pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
    if (SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)symbol, pModuleInfo))
    {
      QString pluginId = pModuleInfo->ModuleName;
      return pluginId.replace('_', '.');
    }
  }
  return QString();
}
Example #13
0
/******************************************************************
 *		SymGetModuleInfoW64 (DBGHELP.@)
 *
 */
BOOL  WINAPI SymGetModuleInfoW64(HANDLE hProcess, DWORD64 dwAddr, 
                                 PIMAGEHLP_MODULEW64 ModuleInfo)
{
    IMAGEHLP_MODULE64   mi;
    IMAGEHLP_MODULEW64  miw;

    if (sizeof(miw) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n");

    mi.SizeOfStruct = sizeof(mi);
    if (!SymGetModuleInfo64(hProcess, dwAddr, &mi)) return FALSE;

    miw.SizeOfStruct  = mi.SizeOfStruct;
    miw.BaseOfImage   = mi.BaseOfImage;
    miw.ImageSize     = mi.ImageSize;
    miw.TimeDateStamp = mi.TimeDateStamp;
    miw.CheckSum      = mi.CheckSum;
    miw.NumSyms       = mi.NumSyms;
    miw.SymType       = mi.SymType;
    MultiByteToWideChar(CP_ACP, 0, mi.ModuleName, -1,   
                        miw.ModuleName, sizeof(miw.ModuleName) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, mi.ImageName, -1,   
                        miw.ImageName, sizeof(miw.ImageName) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, mi.LoadedImageName, -1,   
                        miw.LoadedImageName, sizeof(miw.LoadedImageName) / sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, mi.LoadedPdbName, -1,   
                        miw.LoadedPdbName, sizeof(miw.LoadedPdbName) / sizeof(WCHAR));

    miw.CVSig         = mi.CVSig;
    MultiByteToWideChar(CP_ACP, 0, mi.CVData, -1,   
                        miw.CVData, sizeof(miw.CVData) / sizeof(WCHAR));
    miw.PdbSig        = mi.PdbSig;
    miw.PdbSig70      = mi.PdbSig70;
    miw.PdbAge        = mi.PdbAge;
    miw.PdbUnmatched  = mi.PdbUnmatched;
    miw.DbgUnmatched  = mi.DbgUnmatched;
    miw.LineNumbers   = mi.LineNumbers;
    miw.GlobalSymbols = mi.GlobalSymbols;
    miw.TypeInfo      = mi.TypeInfo;
    miw.SourceIndexed = mi.SourceIndexed;
    miw.Publics       = mi.Publics;

    memcpy(ModuleInfo, &miw, ModuleInfo->SizeOfStruct);

    return TRUE;
}
Example #14
0
// --------------------------------------------------------------------------
std::string ctkBackTracePrivate::getSymbol(void* ptr) const
{
    if(ptr==0)
        return std::string();

    ctk::DebugSymInitialize();
    std::ostringstream ss;
    ss.imbue(std::locale::classic());
    ss << ptr;
    if(syms_ready)
    {
        DWORD64  dwDisplacement = 0;
        DWORD64  dwAddress = (DWORD64)ptr;

        std::vector<char> buffer(sizeof(SYMBOL_INFO) + MAX_SYM_NAME);
        PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)&buffer.front();

        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        pSymbol->MaxNameLen = MAX_SYM_NAME;

        if (SymFromAddr(hProcess, dwAddress, &dwDisplacement, pSymbol))
        {
            ss <<": " << pSymbol->Name << std::hex << " + 0x" << dwDisplacement;
        }
        else
        {
            ss << ": ???";
        }

        std::vector<char> moduleBuffer(sizeof(IMAGEHLP_MODULE64));
        PIMAGEHLP_MODULE64 pModuleInfo = (PIMAGEHLP_MODULE64)&moduleBuffer.front();
        pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
        if (SymGetModuleInfo64(hProcess, pSymbol->ModBase, pModuleInfo))
        {
            ss << " in " << pModuleInfo->LoadedImageName;
        }
    }
    return ss.str();
}
Example #15
0
/*
 * Find Symbol in symbol table
 * To use this, this source must be compiled in debug mode.
 * No solution without /DEBUG option yet.
 */
ACP_EXPORT acp_rc_t acpSymFind(acp_sym_table_t *aSymTable,
                               acp_sym_info_t  *aSymInfo,
                               void            *aAddr)
{
    IMAGEHLP_MODULE64 *sModule = &aSymTable->mModule;
    SYMBOL_INFO       *sSymbol = (SYMBOL_INFO *)aSymTable->mSymbolBuffer;
    BOOL               sRet;

    sRet = SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)aAddr, sModule);

    if (sRet == 0)
    {
        acpStrSetConstCString(&aSymInfo->mFileName, NULL);
        aSymInfo->mFileAddr = NULL;
    }
    else
    {
        acpStrSetConstCString(&aSymInfo->mFileName, sModule->LoadedImageName);
        aSymInfo->mFileAddr = (void *)(acp_ulong_t)sModule->BaseOfImage;
    }

    sRet = SymFromAddr(GetCurrentProcess(), (DWORD64)aAddr, NULL, sSymbol);

    if (sRet == 0)
    {
        acpStrSetConstCString(&aSymInfo->mFuncName, NULL);
        aSymInfo->mFuncAddr = NULL;
    }
    else
    {
        acpStrSetConstCString(&aSymInfo->mFuncName, sSymbol->Name);
        aSymInfo->mFuncAddr = (void *)(acp_ulong_t)sSymbol->Address;
    }

    return ACP_RC_SUCCESS;
}
PRAGMA_ENABLE_OPTIMIZATION

void FWindowsPlatformStackWalk::ProgramCounterToSymbolInfo( uint64 ProgramCounter, FProgramCounterSymbolInfo& out_SymbolInfo )
{
	// Initialize stack walking as it loads up symbol information which we require.
	InitStackWalking();

	// Set the program counter.
	out_SymbolInfo.ProgramCounter = ProgramCounter;

	uint32 LastError = 0;
	HANDLE ProcessHandle = GetCurrentProcess();

	// Initialize symbol.
	ANSICHAR SymbolBuffer[sizeof( IMAGEHLP_SYMBOL64 ) + FProgramCounterSymbolInfo::MAX_NAME_LENGHT] = {0};
	IMAGEHLP_SYMBOL64* Symbol = (IMAGEHLP_SYMBOL64*)SymbolBuffer;
	Symbol->SizeOfStruct = sizeof(SymbolBuffer);
	Symbol->MaxNameLength = FProgramCounterSymbolInfo::MAX_NAME_LENGHT;

	// Get function name.
	if( SymGetSymFromAddr64( ProcessHandle, ProgramCounter, nullptr, Symbol ) )
	{
		// Skip any funky chars in the beginning of a function name.
		int32 Offset = 0;
		while( Symbol->Name[Offset] < 32 || Symbol->Name[Offset] > 127 )
		{
			Offset++;
		}

		// Write out function name.
		FCStringAnsi::Strncpy( out_SymbolInfo.FunctionName, Symbol->Name + Offset, FProgramCounterSymbolInfo::MAX_NAME_LENGHT ); 
		FCStringAnsi::Strncat( out_SymbolInfo.FunctionName, "()", FProgramCounterSymbolInfo::MAX_NAME_LENGHT );
	}
	else
	{
		// No symbol found for this address.
		LastError = GetLastError();
	}

	// Get filename and line number.
	IMAGEHLP_LINE64	ImageHelpLine = {0};
	ImageHelpLine.SizeOfStruct = sizeof( ImageHelpLine );
	if( SymGetLineFromAddr64( ProcessHandle, ProgramCounter, (::DWORD *)&out_SymbolInfo.SymbolDisplacement, &ImageHelpLine ) )
	{
		FCStringAnsi::Strncpy( out_SymbolInfo.Filename, ImageHelpLine.FileName, FProgramCounterSymbolInfo::MAX_NAME_LENGHT );
		out_SymbolInfo.LineNumber = ImageHelpLine.LineNumber;
	}
	else
	{
		LastError = GetLastError();
	}

	// Get module name.
	IMAGEHLP_MODULE64 ImageHelpModule = {0};
	ImageHelpModule.SizeOfStruct = sizeof( ImageHelpModule );
	if( SymGetModuleInfo64( ProcessHandle, ProgramCounter, &ImageHelpModule) )
	{
		// Write out module information.
		FCStringAnsi::Strncpy( out_SymbolInfo.ModuleName, ImageHelpModule.ImageName, FProgramCounterSymbolInfo::MAX_NAME_LENGHT );
	}
	else
	{
		LastError = GetLastError();
	}
}
Example #17
0
void printStackTrace( std::ostream &os ) {
    HANDLE process = GetCurrentProcess();
    BOOL ret = SymInitialize( process, NULL, TRUE );
    if ( ret == FALSE ) {
        DWORD dosError = GetLastError();
        os << "Stack trace failed, SymInitialize failed with error " <<
           std::dec << dosError << std::endl;
        return;
    }
    DWORD options = SymGetOptions();
    options |= SYMOPT_LOAD_LINES | SYMOPT_FAIL_CRITICAL_ERRORS;
    SymSetOptions( options );

    CONTEXT context;
    memset( &context, 0, sizeof(context) );
    context.ContextFlags = CONTEXT_CONTROL;
    RtlCaptureContext( &context );

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

#if defined(_M_AMD64)
    DWORD imageType = IMAGE_FILE_MACHINE_AMD64;
    frame64.AddrPC.Offset = context.Rip;
    frame64.AddrFrame.Offset = context.Rbp;
    frame64.AddrStack.Offset = context.Rsp;
#elif defined(_M_IX86)
    DWORD imageType = IMAGE_FILE_MACHINE_I386;
    frame64.AddrPC.Offset = context.Eip;
    frame64.AddrFrame.Offset = context.Ebp;
    frame64.AddrStack.Offset = context.Esp;
#else
#error Neither _M_IX86 nor _M_AMD64 were defined
#endif
    frame64.AddrPC.Mode = AddrModeFlat;
    frame64.AddrFrame.Mode = AddrModeFlat;
    frame64.AddrStack.Mode = AddrModeFlat;

    const size_t nameSize = 1024;
    const size_t symbolRecordSize = sizeof(SYMBOL_INFO) + nameSize;
    boost::scoped_array<char> symbolBuffer( new char[symbolRecordSize] );
    memset( symbolBuffer.get(), 0, symbolRecordSize );
    SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>( symbolBuffer.get() );
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    symbol->MaxNameLen = nameSize;

    std::vector<TraceItem> traceList;
    TraceItem traceItem;
    size_t moduleWidth = 0;
    size_t fileWidth = 0;
    size_t frameCount = 0;
    for ( size_t i = 0; i < maxBackTraceFrames; ++i ) {
        ret = StackWalk64( imageType,
                           process,
                           GetCurrentThread(),
                           &frame64,
                           &context,
                           NULL,
                           NULL,
                           NULL,
                           NULL );
        if ( ret == FALSE || frame64.AddrReturn.Offset == 0 ) {
            frameCount = i;
            break;
        }

        // module (executable) name
        IMAGEHLP_MODULE64 module;
        memset ( &module, 0, sizeof(module) );
        module.SizeOfStruct = sizeof(module);
        ret = SymGetModuleInfo64( process, frame64.AddrPC.Offset, &module );
        char* moduleName = module.LoadedImageName;
        char* backslash = strrchr( moduleName, '\\' );
        if ( backslash ) {
            moduleName = backslash + 1;
        }
        traceItem.module = moduleName;
        size_t len = traceItem.module.length();
        if ( len > moduleWidth ) {
            moduleWidth = len;
        }

        // source code filename and line number
        IMAGEHLP_LINE64 line;
        memset( &line, 0, sizeof(line) );
        line.SizeOfStruct = sizeof(line);
        DWORD displacement32;
        ret = SymGetLineFromAddr64( process, frame64.AddrPC.Offset, &displacement32, &line );
        if ( ret ) {
            std::string filename( line.FileName );
            std::string::size_type start = filename.find( "\\src\\mongo\\" );
            if ( start == std::string::npos ) {
                start = filename.find( "\\src\\third_party\\" );
            }
            if ( start != std::string::npos ) {
                std::string shorter( "..." );
                shorter += filename.substr( start );
                traceItem.sourceFile.swap( shorter );
            }
            else {
                traceItem.sourceFile.swap( filename );
            }
            len = traceItem.sourceFile.length() + 3;
            traceItem.lineNumber = line.LineNumber;
            if ( traceItem.lineNumber < 10 ) {
                len += 1;
            }
            else if ( traceItem.lineNumber < 100 ) {
                len += 2;
            }
            else if ( traceItem.lineNumber < 1000 ) {
                len += 3;
            }
            else if ( traceItem.lineNumber < 10000 ) {
                len += 4;
            }
            else {
                len += 5;
            }
            traceItem.sourceLength = len;
            if ( len > fileWidth ) {
                fileWidth = len;
            }
        }
        else {
            traceItem.sourceFile.clear();
            traceItem.sourceLength = 0;
        }

        // symbol name and offset from symbol
        DWORD64 displacement;
        ret = SymFromAddr( process, frame64.AddrPC.Offset, &displacement, symbol );
        if ( ret ) {
            traceItem.symbol = symbol->Name;
            traceItem.instructionOffset = displacement;
        }
        else {
            traceItem.symbol = "???";
            traceItem.instructionOffset = 0;
        }

        // add to list
        traceList.push_back( traceItem );
    }
    SymCleanup( process );

    // print list
    ++moduleWidth;
    ++fileWidth;
    for ( size_t i = 0; i < frameCount; ++i ) {
        os << traceList[i].module << " ";
        size_t width = traceList[i].module.length();
        while ( width < moduleWidth ) {
            os << " ";
            ++width;
        }
        if ( traceList[i].sourceFile.length() ) {
            os << traceList[i].sourceFile << "(" << std::dec << traceList[i].lineNumber << ") ";
        }
        width = traceList[i].sourceLength;
        while ( width < fileWidth ) {
            os << " ";
            ++width;
        }
        os << traceList[i].symbol << "+0x" << std::hex << traceList[i].instructionOffset;
        os << std::endl;
    }
}
Example #18
0
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
{
#ifdef _OS_WINDOWS_
    DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer);
    char *fname = 0;
    if (fbase != 0) {
#else
    Dl_info dlinfo;
    const char *fname = 0;
    if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) {
        *fromC = !jl_is_sysimg(dlinfo.dli_fname);
        if (skipC && *fromC)
            return;
        // In case we fail with the debug info lookup, we at least still
        // have the function name, even if we don't have line numbers
        *name = dlinfo.dli_sname;
        *filename = dlinfo.dli_fname;
        uint64_t fbase = (uint64_t)dlinfo.dli_fbase;
#endif
        obfiletype::iterator it = objfilemap.find(fbase);
        llvm::object::ObjectFile *obj = NULL;
        DIContext *context = NULL;
        int64_t slide = 0;
#ifndef _OS_WINDOWS_
        fname = dlinfo.dli_fname;
#else
        IMAGEHLP_MODULE64 ModuleInfo;
        ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
        SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo);
        fname = ModuleInfo.LoadedImageName;
        *fromC = !jl_is_sysimg(fname);
        if (skipC && *fromC)
            return;
#endif
        if (it == objfilemap.end()) {
#ifdef _OS_DARWIN_
           // First find the uuid of the object file (we'll use this to make sure we find the
           // correct debug symbol file).
           uint8_t uuid[16], uuid2[16];
#ifdef LLVM36
	   std::unique_ptr<MemoryBuffer> membuf = MemoryBuffer::getMemBuffer(
                StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false);
	   auto origerrorobj = llvm::object::ObjectFile::createObjectFile(
	        membuf->getMemBufferRef(), sys::fs::file_magic::unknown);
#elif LLVM35
            MemoryBuffer *membuf = MemoryBuffer::getMemBuffer(
                StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false);
            std::unique_ptr<MemoryBuffer> buf(membuf);
            auto origerrorobj = llvm::object::ObjectFile::createObjectFile(
                buf, sys::fs::file_magic::unknown);
#else
            MemoryBuffer *membuf = MemoryBuffer::getMemBuffer(
	        StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false);
            llvm::object::ObjectFile *origerrorobj = llvm::object::ObjectFile::createObjectFile(
                membuf);
#endif
            if (!origerrorobj) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                goto lookup;
            }
#ifdef LLVM36
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get().release();
#elif LLVM35
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get();
#else
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj;
#endif
            if (!getObjUUID(morigobj,uuid)) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                goto lookup;
            }

            // On OS X debug symbols are not contained in the dynamic library and that's why
            // we can't have nice things (easily). For now we only support .dSYM files in the same directory
            // as the shared library. In the future we may use DBGCopyFullDSYMURLForUUID from CoreFoundation to make
            // use of spotlight to find the .dSYM file.
            char dsympath[PATH_MAX];
            strlcpy(dsympath, dlinfo.dli_fname, sizeof(dsympath));
            strlcat(dsympath, ".dSYM/Contents/Resources/DWARF/", sizeof(dsympath));
            strlcat(dsympath, strrchr(dlinfo.dli_fname,'/')+1, sizeof(dsympath));
#ifdef LLVM35
            auto errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#endif
#else
            // On non OS X systems we need to mmap another copy because of the permissions on the mmaped
            // shared library.
#ifdef LLVM35
            auto errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#endif
#endif
#ifdef LLVM36
            if (errorobj) {
                obj = errorobj.get().getBinary().release();
                errorobj.get().getBuffer().release();
#elif LLVM35
            if (errorobj) {
                obj = errorobj.get();
#else
            if (errorobj != NULL) {
                obj = errorobj;
#endif
#ifdef _OS_DARWIN_
                if (getObjUUID(morigobj,uuid2) && memcmp(uuid,uuid2,sizeof(uuid)) == 0) {
#endif
#ifdef LLVM36
                    context = DIContext::getDWARFContext(*obj);
#else
                    context = DIContext::getDWARFContext(obj);
#endif
                    slide = -(uint64_t)fbase;
#ifdef _OS_DARWIN_
                }
#endif
#ifdef _OS_WINDOWS_
                assert(obj->isCOFF());
                llvm::object::COFFObjectFile *coffobj = (llvm::object::COFFObjectFile *)obj;
                const llvm::object::pe32plus_header *pe32plus;
                coffobj->getPE32PlusHeader(pe32plus);
                if (pe32plus != NULL) {
                    slide = pe32plus->ImageBase-fbase;
                }
                else {
                    const llvm::object::pe32_header *pe32;
                    coffobj->getPE32Header(pe32); 
                    if (pe32 == NULL) {
                        obj = NULL;
                        context = NULL;
                    }
                    else {
                        slide = pe32->ImageBase-fbase;
                    }
                }
#endif

            }
            objfileentry_t entry = {obj,context,slide};
            objfilemap[fbase] = entry;
        }
        else {
            obj = it->second.obj;
            context = it->second.ctx;
            slide = it->second.slide;
        }
#ifdef _OS_DARWIN_
    lookup:
#endif
        lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(fname), fromC);
        return;
    }
    *fromC = 1;
    return;
}
#endif

void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
{
    *name = NULL;
    *line = -1;
    *filename = "no file";
    *fromC = 0;

#if USE_MCJIT
// With MCJIT we can get function information directly from the ObjectFile
    std::map<size_t, ObjectInfo, revcomp> &objmap = jl_jit_events->getObjectMap();
    std::map<size_t, ObjectInfo, revcomp>::iterator it = objmap.lower_bound(pointer);

    if (it == objmap.end())
        return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
    if ((pointer - it->first) > it->second.size)
        return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);

#ifdef LLVM36
    DIContext *context = DIContext::getDWARFContext(*it->second.object);
#else
    DIContext *context = DIContext::getDWARFContext(it->second.object);
#endif
    lookup_pointer(context, name, line, filename, pointer, 1, fromC);

#else // !USE_MCJIT

// Without MCJIT we use the FuncInfo structure containing address maps
    std::map<size_t, FuncInfo, revcomp> &info = jl_jit_events->getMap();
    std::map<size_t, FuncInfo, revcomp>::iterator it = info.lower_bound(pointer);
    if (it != info.end() && (size_t)(*it).first + (*it).second.lengthAdr >= pointer) {
        // We do this to hide the jlcall wrappers when getting julia backtraces,
        // but it is still good to have them for regular lookup of C frames.
        if (skipC && (*it).second.lines.empty()) {
            // Technically not true, but we don't want them
            // in julia backtraces, so close enough
            *fromC = 1;
            return;
        }

        *name = (*it).second.name.c_str();
        *filename = (*it).second.filename.c_str();

        if ((*it).second.lines.empty()) {
            *fromC = 1;
            return;
        }

        std::vector<JITEvent_EmittedFunctionDetails::LineStart>::iterator vit =
            (*it).second.lines.begin();
        JITEvent_EmittedFunctionDetails::LineStart prev = *vit;

        if ((*it).second.func) {
            DISubprogram debugscope =
                DISubprogram(prev.Loc.getScope((*it).second.func->getContext()));
            *filename = debugscope.getFilename().data();
            // the DISubprogram has the un-mangled name, so use that if
            // available. However, if the scope need not be the current
            // subprogram.
            if (debugscope.getName().data() != NULL)
                *name = debugscope.getName().data();
            else
                *name = jl_demangle(*name);
        }

        vit++;

        while (vit != (*it).second.lines.end()) {
            if (pointer <= (*vit).Address) {
                *line = prev.Loc.getLine();
                break;
            }
            prev = *vit;
            vit++;
        }
        if (*line == (size_t) -1) {
            *line = prev.Loc.getLine();
        }
    }
    else {
        jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
    }
#endif // USE_MCJIT
}
Example #19
0
void PrintCallStack(const CONTEXT *pContext)
{
    HANDLE hProcess = GetCurrentProcess();
    SymInitialize(hProcess, NULL, TRUE);
    CONTEXT c = *pContext;

    STACKFRAME64 sf;
    memset(&sf, 0, sizeof(STACKFRAME64));
    DWORD dwImageType = IMAGE_FILE_MACHINE_I386;

#ifdef _M_IX86
    sf.AddrPC.Offset = c.Eip;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.Esp;
    sf.AddrStack.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.Ebp;
    sf.AddrFrame.Mode = AddrModeFlat;
#elif _M_X64
    dwImageType = IMAGE_FILE_MACHINE_AMD64;
    sf.AddrPC.Offset = c.Rip;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.Rsp;
    sf.AddrFrame.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.Rsp;
    sf.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
    dwImageType = IMAGE_FILE_MACHINE_IA64;
    sf.AddrPC.Offset = c.StIIP;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.IntSp;
    sf.AddrFrame.Mode = AddrModeFlat;
    sf.AddrBStore.Offset = c.RsBSP;
    sf.AddrBStore.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.IntSp;
    sf.AddrStack.Mode = AddrModeFlat;
#else
    #error "Platform not supported!"
#endif

    HANDLE hThread = GetCurrentThread();

    while (true)
    {
        if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
            break;

        DWORD64 address = sf.AddrPC.Offset;
        if (address == 0)
            break;
       
        // Get symbol name
        char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] = {0};
        PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
        pSymbol->MaxNameLen = MAX_SYM_NAME ;
        pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        SymFromAddr(hProcess, address, NULL, pSymbol);

        // Get module name
        IMAGEHLP_MODULE64 moduleInfo = {0};
        moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
        TCHAR* szModule = _T("");
        // SymGetModuleInfo64 will fail in unicode version
        // http://msdn.microsoft.com/en-us/library/windows/desktop/ms681336(v=vs.85).aspx
        if (SymGetModuleInfo64(hProcess, address, &moduleInfo))
            szModule = moduleInfo.ModuleName;

        // Get file name and line count
        IMAGEHLP_LINE64 lineInfo = {0};
        lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
        DWORD displacement;
        if (SymGetLineFromAddr64(hProcess, address, &displacement, &lineInfo))
        {
            _tprintf(_T("%016llX %s!%s [%s @ %lu]\n"), pSymbol->Address, szModule, pSymbol->Name, lineInfo.FileName, lineInfo.LineNumber);
        }
        else
        {
            _tprintf(_T("%016llX %s!%s\n"), pSymbol->Address, szModule, pSymbol->Name);
        }
    }

    SymCleanup(hProcess);
}
Example #20
0
std::vector<std::string> backtrace_get(int skip) {
     unsigned int   i;
     void         * stack[ 100 ];
     unsigned short frames;
     SYMBOL_INFO  * symbol;
     HANDLE         process;
	 IMAGEHLP_LINE *line = (IMAGEHLP_LINE *)malloc(sizeof(IMAGEHLP_LINE));
	 line->SizeOfStruct = sizeof(IMAGEHLP_LINE);
	 IMAGEHLP_LINE64 *line64 = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
	 line64->SizeOfStruct = sizeof(IMAGEHLP_LINE64);

	 IMAGEHLP_MODULE *mod = (IMAGEHLP_MODULE *)malloc(sizeof(IMAGEHLP_MODULE));
	 mod->SizeOfStruct = sizeof(IMAGEHLP_MODULE);
	 IMAGEHLP_MODULE64 *mod64 = (IMAGEHLP_MODULE64 *)malloc(sizeof(IMAGEHLP_MODULE64));
	 mod->SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

     process = GetCurrentProcess();

     SymSetOptions(SYMOPT_LOAD_LINES);
     SymInitialize( process, NULL, TRUE );

     frames               = CaptureStackBackTrace( 0, 100, stack, NULL );
     symbol               = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
     symbol->MaxNameLen   = 255;
     symbol->SizeOfStruct = sizeof( SYMBOL_INFO );

     char *buf = (char *)malloc(1024);
     std::vector<std::string> vs;

     for( i = skip; i < frames; i++ ){
         SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );

		 bool m64 = false;
		 BOOL mod_status = SymGetModuleInfo(process, symbol->Address, mod);
		 if (!mod_status) {
			 mod_status = SymGetModuleInfo64(process, symbol->Address, mod64);
			 m64 = true;
		 }

		 DWORD dwDisplacement;
		 bool l64 = false;

		 BOOL line_status = SymGetLineFromAddr(process, (ULONG64)stack[i], &dwDisplacement, line);
		 if (!line_status) {
			 line_status = SymGetLineFromAddr64(process, (ULONG64)stack[i], &dwDisplacement, line64);
			 l64 = true;
		 }

		 sprintf(buf, "%-3d %*p %s(%s +  0x%I64x)",
			 frames - i - 1, 
			 int(2 + sizeof(void*) * 2), stack[i],
			 mod_status ? (m64 ? mod64->ModuleName : mod->ModuleName) : "<unknown dll>",
			 symbol->Name,
			 symbol->Address);

		 vs.push_back(std::string(buf));

		 if (line_status) {
			 sprintf(buf, "\t\t%s:%d", l64 ? line64->FileName : line->FileName, l64 ? line64->LineNumber : line->LineNumber);
			 vs.push_back(std::string(buf));
		 }

     }

     free(buf);
     free(symbol);
	 SymCleanup(process);
     return vs;
}
Example #21
0
int StackTrace::GetSymbolInfo(Address address, char* symbol, int maxSymbolLen)
{
    if (!InitSymbols())
        return 0;

    // Start with address.
    int charsAdded = 
        _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, "%p ", address);
    symbol += charsAdded;
    maxSymbolLen -= charsAdded;
    if (maxSymbolLen < 0)
        return charsAdded;

    const DWORD64 address64 = (DWORD64)address;
    // Module name
    IMAGEHLP_MODULE64 moduleInfo;
    ZeroMemory(&moduleInfo, sizeof(moduleInfo));
    moduleInfo.SizeOfStruct = sizeof(moduleInfo);
    const HANDLE hCurrentProcess = GetCurrentProcess();
    if (SymGetModuleInfo64(hCurrentProcess, address64, &moduleInfo))
    {
        char moduleName[_MAX_PATH + 1];
        GetFileFromPath(moduleInfo.ImageName, moduleName, _MAX_PATH);
        const int moduleLen = (int)strlen(moduleName);
        strncpy_s(symbol, maxSymbolLen, moduleName, _TRUNCATE);
        symbol += moduleLen;
        charsAdded += moduleLen;
        maxSymbolLen -= moduleLen;
    }
    if (maxSymbolLen <= 0)
        return charsAdded;

    // Symbol name
    ULONG64 symbolBuffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME*sizeof(TCHAR) +
            sizeof(ULONG64) - 1) / sizeof(ULONG64)] = { 0 };
    IMAGEHLP_SYMBOL64* symbolInfo = reinterpret_cast<IMAGEHLP_SYMBOL64*>(symbolBuffer);
    symbolInfo->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
    symbolInfo->MaxNameLength = MAX_SYM_NAME;
    DWORD64 disp(0);
    if (SymGetSymFromAddr64(hCurrentProcess, address64, &disp, symbolInfo))
    {
        const int symbolChars =
            _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, " %s + 0x%X", symbolInfo->Name, disp);
        symbol += symbolChars;
        maxSymbolLen -= symbolChars;
        charsAdded += symbolChars;
    }
    if (maxSymbolLen <= 0)
        return charsAdded;

    // File + line
    DWORD displacementLine;
    IMAGEHLP_LINE64 lineInfo;
    ZeroMemory(&lineInfo, sizeof(lineInfo));
    lineInfo.SizeOfStruct = sizeof(lineInfo);
    if (SymGetLineFromAddr64(hCurrentProcess, address64, &displacementLine, &lineInfo))
    {
        char fileName[_MAX_PATH + 1];
        GetFileFromPath(lineInfo.FileName, fileName, _MAX_PATH);
        int fileLineChars(0);
        if (displacementLine > 0)
        {
            fileLineChars = _snprintf_s(symbol, maxSymbolLen, _TRUNCATE, 
                " %s(%d+%04d byte(s))", fileName, lineInfo.LineNumber, displacementLine);
        }
        else
        {
            fileLineChars = _snprintf_s(symbol, maxSymbolLen, _TRUNCATE,
                " %s(%d)", fileName, lineInfo.LineNumber);
        }
        symbol += fileLineChars;
        maxSymbolLen -= fileLineChars;
        charsAdded += fileLineChars;
    }
    return charsAdded;
}
Example #22
0
//----------------------------------------------------------------------------//
static void dumpBacktrace(size_t frames)
{
#if defined(_DEBUG) || defined(DEBUG)
#if defined(_MSC_VER)
    SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES);

    if (!SymInitialize(GetCurrentProcess(), 0, TRUE))
        return;

    HANDLE thread = GetCurrentThread();

    CONTEXT context;
    RtlCaptureContext(&context);

    STACKFRAME64 stackframe;
    ZeroMemory(&stackframe, sizeof(stackframe));
    stackframe.AddrPC.Mode = AddrModeFlat;
    stackframe.AddrStack.Mode = AddrModeFlat;
    stackframe.AddrFrame.Mode = AddrModeFlat;

#if _M_IX86
    stackframe.AddrPC.Offset = context.Eip;
    stackframe.AddrStack.Offset = context.Esp;
    stackframe.AddrFrame.Offset = context.Ebp;
    DWORD machine_arch = IMAGE_FILE_MACHINE_I386;
#elif _M_X64
    stackframe.AddrPC.Offset = context.Rip;
    stackframe.AddrStack.Offset = context.Rsp;
    stackframe.AddrFrame.Offset = context.Rbp;
    DWORD machine_arch = IMAGE_FILE_MACHINE_AMD64;
#endif

    char symbol_buffer[1024];
    ZeroMemory(symbol_buffer, sizeof(symbol_buffer));
    PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(symbol_buffer);
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    symbol->MaxNameLen = sizeof(symbol_buffer) - sizeof(SYMBOL_INFO);

    Logger& logger(Logger::getSingleton());
    logger.logEvent("========== Start of Backtrace ==========", Errors);

    size_t frame_no = 0;
    while (StackWalk64(machine_arch, GetCurrentProcess(), thread, &stackframe,
                       &context, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0) &&
           stackframe.AddrPC.Offset)
    {
        symbol->Address = stackframe.AddrPC.Offset;
        DWORD64 displacement = 0;
        char signature[256];

        if (SymFromAddr(GetCurrentProcess(), symbol->Address, &displacement, symbol))
            UnDecorateSymbolName(symbol->Name, signature, sizeof(signature), UNDNAME_COMPLETE);
        else
            sprintf_s(signature, sizeof(signature), "%p", symbol->Address);
 
        IMAGEHLP_MODULE64 modinfo;
        modinfo.SizeOfStruct = sizeof(modinfo);

        const BOOL have_image_name =
            SymGetModuleInfo64(GetCurrentProcess(), symbol->Address, &modinfo);

        char outstr[512];
        sprintf_s(outstr, sizeof(outstr), "#%d %s +%#llx (%s)",
                  frame_no, signature, displacement,
                  (have_image_name ? modinfo.LoadedImageName : "????"));

        logger.logEvent(outstr, Errors);

        if (++frame_no >= frames)
            break;

        if (!stackframe.AddrReturn.Offset)
            break;
    }

    logger.logEvent("==========  End of Backtrace  ==========", Errors);

    SymCleanup(GetCurrentProcess());
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
    void* buffer[frames];
    const int received = backtrace(&buffer[0], frames);

    Logger& logger(Logger::getSingleton());

    logger.logEvent("========== Start of Backtrace ==========", Errors);

    for (int i = 0; i < received; ++i)
    {
        char outstr[512];
        Dl_info info;
        if (dladdr(buffer[i], &info))
        {
            if (!info.dli_sname)
                snprintf(outstr, 512, "#%d %p (%s)", i, buffer[i], info.dli_fname);
            else
            {
                ptrdiff_t offset = static_cast<char*>(buffer[i]) -
                                   static_cast<char*>(info.dli_saddr);

                int demangle_result = 0;
                char* demangle_name = abi::__cxa_demangle(info.dli_sname, 0, 0, &demangle_result);
                snprintf(outstr, 512, "#%d %s +%#tx (%s)",
                         i, demangle_name ? demangle_name : info.dli_sname, offset, info.dli_fname);
                std::free(demangle_name);
            }
        }
        else
            snprintf(outstr, 512, "#%d --- error ---", i);

        logger.logEvent(outstr, Errors);
    }

    logger.logEvent("==========  End of Backtrace  ==========", Errors);
#endif
#endif
}
Example #23
0
void jl_getDylibFunctionInfo(const char **name, int *line, const char **filename, size_t pointer, int skipC)
{
#ifdef _OS_WINDOWS_
    DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer);
    if (fbase != 0) {
#else
    Dl_info dlinfo;
    if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) {
        if (skipC && !jl_is_sysimg(dlinfo.dli_fname))
            return;
        uint64_t fbase = (uint64_t)dlinfo.dli_fbase;
#endif
        obfiletype::iterator it = objfilemap.find(fbase);
        llvm::object::ObjectFile *obj = NULL;
        DIContext *context = NULL;
        int64_t slide = 0;
        if (it == objfilemap.end()) {
#ifdef _OS_DARWIN_
            // First find the uuid of the object file (we'll use this to make sure we find the
            // correct debug symbol file).
            uint8_t uuid[16], uuid2[16];
#ifdef LLVM35
            ErrorOr<llvm::object::ObjectFile*> origerrorobj = llvm::object::ObjectFile::createObjectFile(
#else
            llvm::object::ObjectFile *origerrorobj = llvm::object::ObjectFile::createObjectFile(
#endif
                    MemoryBuffer::getMemBuffer(
                    StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false)
#ifdef LLVM35
                    ,false, sys::fs::file_magic::unknown
#endif
            );
            if (!origerrorobj) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                return;
            }
#ifdef LLVM35
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get();
#else
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj;
#endif
            if (!getObjUUID(morigobj,uuid)) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                return;
            }

            // On OS X debug symbols are not contained in the dynamic library and that's why
            // we can't have nice things (easily). For now we only support .dSYM files in the same directory
            // as the shared library. In the future we may use DBGCopyFullDSYMURLForUUID from CoreFoundation to make
            // use of spotlight to find the .dSYM file.
            char dsympath[PATH_MAX];
            strlcpy(dsympath, dlinfo.dli_fname, sizeof(dsympath));
            strlcat(dsympath, ".dSYM/Contents/Resources/DWARF/", sizeof(dsympath));
            strlcat(dsympath, strrchr(dlinfo.dli_fname,'/')+1, sizeof(dsympath));
#ifdef LLVM35
            ErrorOr<llvm::object::ObjectFile*> errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#endif
#else
#ifndef _OS_WINDOWS_
            const char *fname = dlinfo.dli_fname;
#else
            IMAGEHLP_MODULE64 ModuleInfo;
            ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
            SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo);
            char *fname = ModuleInfo.LoadedImageName;
            JL_PRINTF(JL_STDOUT,fname);
#endif
            // On non OS X systems we need to mmap another copy because of the permissions on the mmaped
            // shared library.
#ifdef LLVM35
            ErrorOr<llvm::object::ObjectFile*> errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#endif
#endif
#ifdef LLVM35
            if (errorobj) {
                obj = errorobj.get();
#else
            if (errorobj != NULL) {
                obj = errorobj;
#endif
#ifdef _OS_DARWIN_
                if (getObjUUID(morigobj,uuid2) && memcmp(uuid,uuid2,sizeof(uuid)) == 0) {
#endif
                    context = DIContext::getDWARFContext(obj);
                    slide = -(uint64_t)fbase;
#ifdef _OS_DARWIN_
                }
#endif
#ifdef _OS_WINDOWS_
                assert(obj->isCOFF());
                llvm::object::COFFObjectFile *coffobj = (llvm::object::COFFObjectFile *)obj;
                const llvm::object::pe32plus_header *pe32plus;
                coffobj->getPE32PlusHeader(pe32plus);
                if (pe32plus != NULL) {
                    slide = pe32plus->ImageBase-fbase;
                }
                else {
                    const llvm::object::pe32_header *pe32;
                    coffobj->getPE32Header(pe32); 
                    if (pe32 == NULL) {
                        obj = NULL;
                        context = NULL;
                    }
                    else {
                        slide = pe32->ImageBase-fbase;
                    }
                }
#endif

            }
            objfileentry_t entry = {obj,context,slide};
            objfilemap[fbase] = entry;
        }
        else {
            obj = it->second.obj;
            context = it->second.ctx;
            slide = it->second.slide;
        }

        lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(dlinfo.dli_fname));
    }
    return;
}
Example #24
0
static void ShowSymbolInfo(HANDLE process, ULONG64 module_base) {
  /* Get module information. */
  IMAGEHLP_MODULE64 module_info;
  BOOL getmoduleinfo_rv;
  printf("Load Address: %I64x\n", module_base);
  memset(&module_info, 0, sizeof(module_info));
  module_info.SizeOfStruct = sizeof(module_info);
  getmoduleinfo_rv = SymGetModuleInfo64(process, module_base, &module_info);
  if (!getmoduleinfo_rv)  {
    printf("Error: SymGetModuleInfo64() failed. Error code: %u\n",
           GetLastError());
    return;
  }
  /* Display information about symbols, based on kind of symbol. */
  switch (module_info.SymType)  {
    case SymNone:
      printf(("No symbols available for the module.\n"));
      break;
    case SymExport:
      printf(("Loaded symbols: Exports\n"));
      break;
    case SymCoff:
      printf(("Loaded symbols: COFF\n"));
      break;
    case SymCv:
      printf(("Loaded symbols: CodeView\n"));
      break;
    case SymSym:
      printf(("Loaded symbols: SYM\n"));
      break;
    case SymVirtual:
      printf(("Loaded symbols: Virtual\n"));
      break;
    case SymPdb:
      printf(("Loaded symbols: PDB\n"));
      break;
    case SymDia:
      printf(("Loaded symbols: DIA\n"));
      break;
    case SymDeferred:
      printf(("Loaded symbols: Deferred\n"));  /* not actually loaded */
      break;
    default:
      printf(("Loaded symbols: Unknown format.\n"));
      break;
  }

  MaybePrint("Image name", module_info.ImageName);
  MaybePrint("Loaded image name", module_info.LoadedImageName);
#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */
  MaybePrint("PDB file name", module_info.LoadedPdbName);
  if (module_info.PdbUnmatched || module_info.DbgUnmatched)  {
    /* This can only happen if the debug information is contained in a
     * separate file (.DBG or .PDB)
     */
    printf(("Warning: Unmatched symbols.\n"));
  }
#endif

  /* Contents */
#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */
  PrintAvailability("Line numbers", module_info.LineNumbers);
  PrintAvailability("Global symbols", module_info.GlobalSymbols);
  PrintAvailability("Type information", module_info.TypeInfo);
#endif
}
Example #25
0
std::vector<CallStackInfo> GetCallStack(const CONTEXT* pContext)
{
	HANDLE hProcess = GetCurrentProcess();
	SymInitialize(hProcess, NULL, TRUE);
	vector<CallStackInfo> arrCallStackInfo;
	CONTEXT c = *pContext;

	STACKFRAME64 sf;
	memset(&sf, 0, sizeof(STACKFRAME64));
	DWORD dwImageType = IMAGE_FILE_MACHINE_I386;
#ifdef _M_IX86
	sf.AddrPC.Offset = c.Eip;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrStack.Offset = c.Esp;
	sf.AddrStack.Mode = AddrModeFlat;
	sf.AddrFrame.Offset = c.Ebp;
	sf.AddrFrame.Mode = AddrModeFlat;
#elif _M_X64
	dwImageType = IMAGE_FILE_MACHINE_AMD64;
	sf.AddrPC.Offset = c.Rip;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrFrame.Offset = c.Rsp;
	sf.AddrFrame.Mode = AddrModeFlat;
	sf.AddrStack.Offset = c.Rsp;
	sf.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
	dwImageType = IMAGE_FILE_MACHINE_IA64;
	sf.AddrPC.Offset = c.StIIP;
	sf.AddrPC.Mode = AddrModeFlat;
	sf.AddrFrame.Offset = c.IntSp;
	sf.AddrFrame.Mode = AddrModeFlat;
	sf.AddrBStore.Offset = c.RsBSP;
	sf.AddrBStore.Mode = AddrModeFlat;
	sf.AddrStack.Offset = c.IntSp;
	sf.AddrStack.Mode = AddrModeFlat;
#else
#error "Platform not supported!"
#endif

	HANDLE hThread = GetCurrentThread();
	while (true)
	{
		if (!StackWalk64(dwImageType, hProcess, hThread, &sf, &c,
			NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
			break;
		if (sf.AddrFrame.Offset == 0)
			break;

		CallStackInfo callstackinfo;
		strcpy_s(callstackinfo.MethodName, MAX_NAME_LENGTH, "N/A");
		strcpy_s(callstackinfo.FileName, MAX_NAME_LENGTH, "N/A");
		strcpy_s(callstackinfo.ModuleName, MAX_NAME_LENGTH, "N/A");
		strcpy_s(callstackinfo.LineNumber, MAX_NAME_LENGTH, "N/A");

		BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_NAME_LENGTH];
		IMAGEHLP_SYMBOL64 *pSymbol = (IMAGEHLP_SYMBOL64*)symbolBuffer;
		memset(pSymbol, 0, sizeof(IMAGEHLP_SYMBOL64) + MAX_NAME_LENGTH);

		pSymbol->SizeOfStruct = sizeof(symbolBuffer);
		pSymbol->MaxNameLength = MAX_NAME_LENGTH;

		DWORD symDisplacement = 0;

		// 得到函数名  
		if (SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, NULL, pSymbol))  
			strcpy_s(callstackinfo.MethodName, MAX_NAME_LENGTH, pSymbol->Name);  

		IMAGEHLP_LINE64 lineInfo;
		memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64));
		lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

		DWORD dwLineDisplacement;

		// 得到文件名和所在的代码行
		if (SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
		{
			strcpy_s(callstackinfo.FileName, MAX_NAME_LENGTH, lineInfo.FileName);
			sprintf_s(callstackinfo.LineNumber, "%d", lineInfo.LineNumber);
		}

		IMAGEHLP_MODULE64 moduleInfo;
		memset(&moduleInfo, 0, sizeof(IMAGEHLP_MODULE64));

		moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);

		// 得到模块名
		if (SymGetModuleInfo64(hProcess, sf.AddrPC.Offset, &moduleInfo))
		{
			strcpy_s(callstackinfo.ModuleName, MAX_NAME_LENGTH, moduleInfo.ModuleName);
		}

		arrCallStackInfo.push_back(callstackinfo);
	}

	SymCleanup(hProcess);
	return arrCallStackInfo;
}
Example #26
0
int CMiniDumpReader::StackWalk(DWORD dwThreadId)
{ 
    int nThreadIndex = GetThreadRowIdByThreadId(dwThreadId);
    if(m_DumpData.m_Threads[nThreadIndex].m_bStackWalk == TRUE)
        return 0; // Already done

    CONTEXT* pThreadContext = NULL;

    if(m_DumpData.m_Threads[nThreadIndex].m_dwThreadId==m_DumpData.m_uExceptionThreadId)
        pThreadContext = m_DumpData.m_pExceptionThreadContext;
    else
        pThreadContext = m_DumpData.m_Threads[nThreadIndex].m_pThreadContext;  

    if(pThreadContext==NULL)
        return 1;

    // Make modifiable context
    CONTEXT Context;
    memcpy(&Context, pThreadContext, sizeof(CONTEXT));

    g_pMiniDumpReader = this;

    // Init stack frame with correct initial values
    // See this:
    // http://www.codeproject.com/KB/threads/StackWalker.aspx
    //
    // Given a current dbghelp, your code should:
    //  1. Always use StackWalk64
    //  2. Always set AddrPC to the current instruction pointer (Eip on x86, Rip on x64 and StIIP on IA64)
    //  3. Always set AddrStack to the current stack pointer (Esp on x86, Rsp on x64 and IntSp on IA64)
    //  4. Set AddrFrame to the current frame pointer when meaningful. On x86 this is Ebp, on x64 you 
    //     can use Rbp (but is not used by VC2005B2; instead it uses Rdi!) and on IA64 you can use RsBSP. 
    //     StackWalk64 will ignore the value when it isn't needed for unwinding.
    //  5. Set AddrBStore to RsBSP for IA64. 

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

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

    DWORD dwMachineType = 0;
    switch(m_DumpData.m_uProcessorArchitecture)
    {
#ifdef _X86_
  case PROCESSOR_ARCHITECTURE_INTEL: 
      dwMachineType = IMAGE_FILE_MACHINE_I386;
      sf.AddrPC.Offset = pThreadContext->Eip;    
      sf.AddrStack.Offset = pThreadContext->Esp;
      sf.AddrFrame.Offset = pThreadContext->Ebp;
      break;
#endif
#ifdef _AMD64_
  case PROCESSOR_ARCHITECTURE_AMD64:
      dwMachineType = IMAGE_FILE_MACHINE_AMD64;
      sf.AddrPC.Offset = pThreadContext->Rip;    
      sf.AddrStack.Offset = pThreadContext->Rsp;
      sf.AddrFrame.Offset = pThreadContext->Rbp;
      break;
#endif
#ifdef _IA64_
  case PROCESSOR_ARCHITECTURE_AMD64:
      dwMachineType = IMAGE_FILE_MACHINE_IA64;
      sf.AddrPC.Offset = pThreadContext->StIIP;
      sf.AddrStack.Offset = pThreadContext->IntSp;
      sf.AddrFrame.Offset = pThreadContext->RsBSP;    
      sf.AddrBStore.Offset = pThreadContext->RsBSP;
      break;
#endif 
  default:
      {
          assert(0);
          return 1; // Unsupported architecture
      }
    }

    for(;;)
    {    
        BOOL bWalk = ::StackWalk64(
            dwMachineType,               // machine type
            m_DumpData.m_hProcess,       // our process handle
            (HANDLE)dwThreadId,          // thread ID
            &sf,                         // stack frame
            dwMachineType==IMAGE_FILE_MACHINE_I386?NULL:(&Context), // used for non-I386 machines 
            ReadProcessMemoryProc64,     // our routine
            FunctionTableAccessProc64,   // our routine
            GetModuleBaseProc64,         // our routine
            NULL                         // safe to be NULL
            );

        if(!bWalk)
            break;      

        MdmpStackFrame stack_frame;
        stack_frame.m_dwAddrPCOffset = sf.AddrPC.Offset;

        // Get module info
        IMAGEHLP_MODULE64 mi;
        memset(&mi, 0, sizeof(IMAGEHLP_MODULE64));
        mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
        BOOL bGetModuleInfo = SymGetModuleInfo64(m_DumpData.m_hProcess, sf.AddrPC.Offset, &mi);     
        if(bGetModuleInfo)
        {
            stack_frame.m_nModuleRowID = GetModuleRowIdByBaseAddr(mi.BaseOfImage);      
        }

        // Get symbol info
        DWORD64 dwDisp64;
        BYTE buffer[4096];
        SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
        sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
        sym_info->MaxNameLen = 4096-sizeof(SYMBOL_INFO)-1;
        BOOL bGetSym = SymFromAddr(
            m_DumpData.m_hProcess, 
            sf.AddrPC.Offset, 
            &dwDisp64, 
            sym_info);

        if(bGetSym)
        {
            stack_frame.m_sSymbolName = CString(sym_info->Name, sym_info->NameLen);
            stack_frame.m_dw64OffsInSymbol = dwDisp64;
        }

        // Get source filename and line
        DWORD dwDisplacement;
        IMAGEHLP_LINE64 line;
        BOOL bGetLine = SymGetLineFromAddr64(
            m_DumpData.m_hProcess, 
            sf.AddrPC.Offset,
            &dwDisplacement,
            &line);

        if(bGetLine)
        {
            stack_frame.m_sSrcFileName = line.FileName;
            stack_frame.m_nSrcLineNumber = line.LineNumber;
        }

        m_DumpData.m_Threads[nThreadIndex].m_StackTrace.push_back(stack_frame);
    }


    CString sStackTrace;
    UINT i;
    for(i=0; i<m_DumpData.m_Threads[nThreadIndex].m_StackTrace.size(); i++)
    {
        MdmpStackFrame& frame = m_DumpData.m_Threads[nThreadIndex].m_StackTrace[i];

        if(frame.m_sSymbolName.IsEmpty())
            continue;

        CString sModuleName;
        CString sAddrPCOffset;
        CString sSymbolName;            
        CString sOffsInSymbol;
        CString sSourceFile;
        CString sSourceLine;

        if(frame.m_nModuleRowID>=0)
        {
            sModuleName = m_DumpData.m_Modules[frame.m_nModuleRowID].m_sModuleName;
        }           

        sSymbolName = frame.m_sSymbolName;
        sAddrPCOffset.Format(_T("0x%I64x"), frame.m_dwAddrPCOffset);
        sSourceFile = frame.m_sSrcFileName;
        sSourceLine.Format(_T("%d"), frame.m_nSrcLineNumber);
        sOffsInSymbol.Format(_T("0x%I64x"), frame.m_dw64OffsInSymbol);

        CString str;
        str = sModuleName;
        if(!str.IsEmpty())
            str += _T("!");

        if(sSymbolName.IsEmpty())
            str += sAddrPCOffset;  
        else
        {
            str += sSymbolName;
            str += _T("+");
            str += sOffsInSymbol;
        }

        if(!sSourceFile.IsEmpty())
        {
            size_t pos = sSourceFile.ReverseFind('\\');
            if(pos>=0)
                sSourceFile = sSourceFile.Mid((int)pos+1);
            str += _T(" [ ");
            str += sSourceFile;
            str += _T(": ");
            str += sSourceLine;
            str += _T(" ] ");
        } 

        sStackTrace += str; 
        sStackTrace += _T("\n");
    }

    if(!sStackTrace.IsEmpty())
    {
        strconv_t strconv;
        LPCSTR szStackTrace = strconv.t2utf8(sStackTrace);
        MD5 md5;
        MD5_CTX md5_ctx;
        unsigned char md5_hash[16];
        md5.MD5Init(&md5_ctx);  
        md5.MD5Update(&md5_ctx, (unsigned char*)szStackTrace, (unsigned int)strlen(szStackTrace));  
        md5.MD5Final(md5_hash, &md5_ctx);

        for(i=0; i<16; i++)
        {
            CString number;
            number.Format(_T("%02x"), md5_hash[i]);
            m_DumpData.m_Threads[nThreadIndex].m_sStackTraceMD5 += number;
        }
    }

    m_DumpData.m_Threads[nThreadIndex].m_bStackWalk = TRUE;


    return 0;
}
Example #27
0
static std::list<stack_info> get_stack_list(
  void* bp, void* sp, void* ip,
  size_t max_depth, size_t offset, bool module, bool symbol, bool brief
)
{
  QWORD trace[33];
  CONTEXT context;

  ZeroMemory(&context, sizeof(context));
  context.ContextFlags = CONTEXT_FULL;
#ifdef _WIN64
  context.Rbp = (DWORD64)bp;
  context.Rsp = (DWORD64)sp;
  context.Rip = (DWORD64)ip;
#else
  context.Ebp = (DWORD)bp;
  context.Esp = (DWORD)sp;
  context.Eip = (DWORD)ip;
#endif
  size_t depths = stack_walk(trace, max_depth, &context);

  std::list<stack_info> image_list;
  HANDLE hProcess = GetCurrentProcess();
  for (size_t i = offset; i < depths; i++)
  {
    stack_info stack_result(brief);

    {
      DWORD symbolDisplacement = 0;
      IMAGEHLP_LINE64 imageHelpLine;
      imageHelpLine.SizeOfStruct = sizeof(imageHelpLine);

      if (SymGetLineFromAddr64(hProcess, trace[i], &symbolDisplacement, &imageHelpLine))
      {
        stack_result.file_ = std::string(imageHelpLine.FileName, check_file_name(imageHelpLine.FileName));
        std::memset(imageHelpLine.FileName, 0, stack_result.file_.size() + 1);
        stack_result.line_ = (int)imageHelpLine.LineNumber;
      }
      else
      {
        stack_result.line_ = -1;
      }
    }
    if (symbol)
    {
      static const int max_name_length = 1024;
      char symbolBf[sizeof(IMAGEHLP_SYMBOL64) + max_name_length] = { 0 };
      PIMAGEHLP_SYMBOL64 symbol;
      DWORD64 symbolDisplacement64 = 0;

      symbol = (PIMAGEHLP_SYMBOL64)symbolBf;
      symbol->SizeOfStruct = sizeof(symbolBf);
      symbol->MaxNameLength = max_name_length;

      if (SymGetSymFromAddr64(
        hProcess,
        trace[i],
        &symbolDisplacement64,
        symbol)
        )
      {
        stack_result.symbol_ = symbol->Name;
      }
      else
      {
        stack_result.symbol_ = "unknow...";
      }
    }
    if (module)
    {
      IMAGEHLP_MODULE64 imageHelpModule;
      imageHelpModule.SizeOfStruct = sizeof(imageHelpModule);

      if (SymGetModuleInfo64(hProcess, trace[i], &imageHelpModule))
      {
        stack_result.module_ = std::string(imageHelpModule.ImageName, check_file_name(imageHelpModule.ImageName));
        std::memset(imageHelpModule.ImageName, 0, stack_result.module_.size() + 1);
      }
    }
    image_list.push_back(std::move(stack_result));
  }
  return image_list;
}
Example #28
0
void WINAPI CConsumer::ProcessEvent(PEVENT_TRACE pEvent)
{
	WCHAR ClassGuid[50];
	IWbemClassObject *pEventCategoryClass = NULL;
	IWbemClassObject *pEventClass = NULL;
	PBYTE pEventData = NULL;
	PBYTE pEndOfEventData = NULL;
	PROPERTY_LIST *pProperties = NULL;
	DWORD PropertyCount = 0;
	LONG *pProPertyIndex = NULL;
	ULONGLONG TimeStamp = 0;
	SYSTEMTIME st;
	SYSTEMTIME stLocal;
	FILETIME ft;
	ULONG diskReadTransfer = 0;
	UINT64 highResResponseTime = 0; 
	DWORD threadId = 0;

	if(!m_isContinueTrace && !IsEqualGUID(pEvent->Header.Guid, FileIoGuid))
		return ;

	UINT32 instrumentPointer = 0;

	if(IsEqualGUID(pEvent->Header.Guid, EventTraceGuid) && EVENT_TRACE_TYPE_INFO == pEvent->Header.Class.Type )
	{
		;	// Skip this Event.
	}

	else
	{
		StringFromGUID2(pEvent->Header.Guid, ClassGuid, sizeof(ClassGuid));
		TimeStamp = pEvent->Header.TimeStamp.QuadPart;

		pEventData = (PBYTE) pEvent->MofData;
		UCHAR eventType = pEvent->Header.Class.Type;

		if(IsEqualGUID(pEvent->Header.Guid,ProcessGuid) && pEvent->MofLength > 0)
		{
			if(eventType == EVENT_TRACE_TYPE_START)
			{
				UINT32 processID;
				CopyMemory(&processID, pEventData+MOF_POINTERSIZE, sizeof(UINT32));
				if(processID == m_processId)
					m_processStartSamp.QuadPart = TimeStamp;
			}
		}

		if(IsEqualGUID(pEvent->Header.Guid, PageFaultGuid) && pEvent->MofData > 0)
		{
			if(32 == eventType)				// hard faults
			{
				CopyMemory(&threadId, pEventData+16+2*MOF_POINTERSIZE, sizeof(UINT32));
				for(std::vector<DWORD>::iterator ite = m_vecThreadId.begin(); ite != m_vecThreadId.end(); ++ite)
				{
					if(*ite == threadId )
					{
						UINT64 readOffset, vtAddr, fileObject,initTimeStamp;
						UINT32 byteCount = 0;
						CopyMemory(&initTimeStamp, pEventData, 8);
						CopyMemory(&readOffset, pEventData+8, 8);
						CopyMemory(&vtAddr, pEventData + 16, MOF_POINTERSIZE);
						CopyMemory(&fileObject, pEventData +16+MOF_POINTERSIZE, MOF_POINTERSIZE);
						CopyMemory(&byteCount, pEventData+20+2*MOF_POINTERSIZE, sizeof(UINT32));
						CHardFaults hardFaultsTemp;
						hardFaultsTemp.initTime = initTimeStamp;
						hardFaultsTemp.fileObj = fileObject;
						hardFaultsTemp.fileOffset = readOffset;
						hardFaultsTemp.vtAddress = vtAddr;
						hardFaultsTemp.byteCount = byteCount;

						MAP_FILEOBJ_ITE mapIte = m_mapFileObjectToFileName.begin();
						for(; mapIte != m_mapFileObjectToFileName.end() ; ++mapIte)
						{
							if(mapIte->first == hardFaultsTemp.fileObj)
								break;
						}
						if(mapIte == m_mapFileObjectToFileName.end())
						{
							m_vecHardFaults.push_back(hardFaultsTemp);
						}
						else
						{
							VEC_FILEFAULTS_ITE iteFaults;
							for(iteFaults = m_vecFileFaults.begin(); iteFaults != m_vecFileFaults.end(); ++iteFaults)
							{
								if(wcscmp(iteFaults->fileName.c_str(), mapIte->second.c_str()) == 0 )
									break;
							}
							if(iteFaults != m_vecFileFaults.end())
							{
								iteFaults->faultCount += 1;
								iteFaults->readSize += hardFaultsTemp.byteCount;
								iteFaults->vec_Fault.push_back(hardFaultsTemp);
							}
							else
							{
								CFileHardFaults fileHardFaults;
								fileHardFaults.fileObj = mapIte->first;
								fileHardFaults.faultCount = 1;
								fileHardFaults.readSize = hardFaultsTemp.byteCount;
								fileHardFaults.fileName = mapIte->second;
								fileHardFaults.vec_Fault.push_back(hardFaultsTemp);
								m_vecFileFaults.push_back(fileHardFaults);
							}
						}
						break;
					}
				}
			}
		}

		if(IsEqualGUID(pEvent->Header.Guid, StackWalkGuid)  && pEvent->MofLength > 0 )
		{
			int processId = 0;
			CopyMemory(&processId, pEventData + 8, 4);
			if(processId == m_processId)
			{
				BOOL bRet = FALSE;
				UINT64 TimeStamp=0;		// 具体事件触发时候的时间戳,
				CopyMemory(&TimeStamp, pEventData, sizeof(UINT64));
				if(m_preStackWalkStamp == 0)
				{
					m_preStackWalkStamp= TimeStamp;
					return;
				}

				int stackFrameCount = (pEvent->MofLength - 16)/MOF_POINTERSIZE;

				UINT64 stack1 = 0;
				CopyMemory(&stack1, pEventData+16, MOF_POINTERSIZE);

				if(INT64(stack1) < 0 )
					return ;
				std::vector<std::string> vecTemp;
				for(int i=0; i <  stackFrameCount; ++i)
				{		
					std::string sym;
					UINT64 stackEnd = 0;
					CopyMemory(&stackEnd, pEventData+16+i*MOF_POINTERSIZE, MOF_POINTERSIZE);
					DWORD64 dwDisp64;
					BYTE buffer[4096];
					SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
					sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
					sym_info->MaxNameLen = 4096-sizeof(SYMBOL_INFO)-1;
					BOOL bGetSym = SymFromAddr(m_processHandle,stackEnd,&dwDisp64, sym_info);

					IMAGEHLP_MODULE64 mi;
					memset(&mi, 0, sizeof(IMAGEHLP_MODULE64));
					mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
					BOOL bGetModuleInfo = SymGetModuleInfo64(m_processHandle, stackEnd, &mi);   

					if(bGetModuleInfo)
						sym = (std::string)(mi.ModuleName) + "!";
					if(bGetSym)
						sym = sym + sym_info->Name;
					char stackAddress[64] = {0};
					_i64toa_s(stackEnd, stackAddress,64, 16);
					sym += "(0x";
					sym += stackAddress;
					sym += ")";
					vecTemp.push_back(sym);
				}

				SAMPLE_STACK sampleStack;
				sampleStack.timeStamp = TimeStamp;
				sampleStack.timeInterval = TimeStamp - m_preStackWalkStamp;
				sampleStack.vecStack = vecTemp;
				m_vecSampleStack.push_back(sampleStack);
				m_preStackWalkStamp = TimeStamp;
			}
			
		}

		if(IsEqualGUID(pEvent->Header.Guid, FileIoGuid) && pEvent->MofLength > 0)
		{
			UINT64 fileObjectPtr = 0;
			wchar_t fileName[MAX_PATH] = {0};
			
			if( 0 == eventType || 32 == eventType || 35 == eventType || 36 == eventType)
			{
				int lenth = wcslen((wchar_t*)(pEventData+MOF_POINTERSIZE));
				CopyMemory(fileName, pEventData+MOF_POINTERSIZE, lenth*sizeof(wchar_t));
				
				CopyMemory(&fileObjectPtr, pEventData, MOF_POINTERSIZE);

				m_mapFileObjectToFileName[fileObjectPtr] = fileName;
			}

//  			if(64 == eventType)		//创建文件
//  			{
//  				int lenth = wcslen((wchar_t*) (pEventData + 12 + MOF_POINTERSIZE*3));
//  				CopyMemory(fileName, pEventData + 12 + MOF_POINTERSIZE*3, lenth*sizeof(wchar_t));
//  				CopyMemory(&fileObjectPtr, pEventData + 2*MOF_POINTERSIZE, MOF_POINTERSIZE);
// 				m_mapFileCreate[fileObjectPtr] = fileName;
//  			}
//  
//  			if(67 == eventType || 68 == eventType)		//文件读写
//  			{
//  				UINT64 fileCreateObj;
//  				CopyMemory(&fileCreateObj, pEventData + 8 + 2*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				CopyMemory(&fileObjectPtr, pEventData + 8 + 3*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj);
//  				if(iteCreate != m_mapFileCreate.end())
//  				{
//  					m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second;
//  				}
//  				
//  			}
//  
//  			if(65 == eventType || 66 == eventType || 73 == eventType)
//  			{
//  				UINT64 fileCreateObj;
//  				CopyMemory(&fileCreateObj, pEventData + 2*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				CopyMemory(&fileObjectPtr, pEventData + 3*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj);
//  				if(iteCreate != m_mapFileCreate.end())
//  				{
//  					m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second;
//  				}
//  			}
//  
//  			if(69 == eventType || 70 == eventType || 71 == eventType || 74 == eventType || 75 == eventType)
//  			{
//  				UINT64 fileCreateObj;
//  				CopyMemory(&fileCreateObj, pEventData + 2*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				CopyMemory(&fileObjectPtr, pEventData + 3*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj);
//  				if(iteCreate != m_mapFileCreate.end())
//  				{
//  					m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second;
//  				}
//  			}
//  
//  			if(72 == eventType || 77 == eventType)
//  			{
//  // 				int lenth = wcslen((wchar_t*) (pEventData+8 + 5*MOF_POINTERSIZE));
//  // 				CopyMemory(fileName, pEventData+8 + 5*MOF_POINTERSIZE, lenth*sizeof(wchar_t));
//  				UINT64 fileCreateObj;
//  				CopyMemory(&fileCreateObj, pEventData+2*MOF_POINTERSIZE, MOF_POINTERSIZE);
//  				CopyMemory(&fileObjectPtr,pEventData+3*MOF_POINTERSIZE,MOF_POINTERSIZE);
//  				MAP_FILEOBJ_ITE iteCreate = m_mapFileCreate.find(fileCreateObj);
//  				if(iteCreate != m_mapFileCreate.end())
//  				{
//  					m_mapFileObjectToFileName[fileObjectPtr] = iteCreate->second;
//  				}
//  			}
		}

		if(IsEqualGUID(pEvent->Header.Guid,MyCategoryGuid))
		{
			if(THUNDER_PROVIDER_TYPE_END == pEvent->Header.Class.Type)
			{
				m_isContinueTrace = FALSE;
				m_startTimeUsed.QuadPart = TimeStamp - m_processStartSamp.QuadPart;
			}
		}

		if(IsEqualGUID(pEvent->Header.Guid, ThreadGuid) && pEvent->MofLength > 0)
		{
			DWORD processID = 0;
			CopyMemory(&processID, pEventData, 4);
			if(EVENT_TRACE_TYPE_START == pEvent->Header.Class.Type /*|| 3 == pEvent->Header.Class.Type*/)
			{
				if(m_processId == processID )
				{
					CopyMemory(&threadId, pEventData + 4, 4);
					m_vecThreadId.push_back(threadId);
				}
			}
			if(EVENT_TRACE_TYPE_END == pEvent->Header.Class.Type)
			{
				if(m_processId == processID)
				{
					CopyMemory(&threadId, pEventData + 4, 4);
					for(std::vector<DWORD>::iterator ite = m_vecThreadId.begin(); ite != m_vecThreadId.end(); ++ite)
					{
						if(*ite == threadId)
						{
							m_vecThreadId.erase(ite);
							break;
						}
					}
				}
			}
		}

		if(IsEqualGUID(pEvent->Header.Guid, PerfInfoGuid) && pEvent->MofLength > 0)
		{
			if(m_processStartSamp.QuadPart == 0)		// 进程还没开始
				return;
			if(46 == pEvent->Header.Class.Type)			// sample profile
			{
				if(m_beginTimeStamp == 0)
					m_beginTimeStamp = TimeStamp;
				m_endTimeStamp = TimeStamp;

				m_totalSampleCount += 1;

				DWORD perfThreadId = -1;
				CopyMemory(&perfThreadId, pEventData+8, 4);

				for(std::vector<DWORD>::iterator ite = m_vecThreadId.begin(); ite != m_vecThreadId.end(); ++ite)
				{
					if(*ite == perfThreadId )
					{
						m_processSampleCount += 1;
						break;
					}
				}
				 
			}

		}

		if(IsEqualGUID(pEvent->Header.Guid, DiskIoGuid ) && pEvent->MofLength > 0)
		{
			if((EVENT_TRACE_TYPE_IO_READ == pEvent->Header.Class.Type || EVENT_TRACE_TYPE_IO_WRITE == pEvent->Header.Class.Type) && pEvent->Header.ProcessId == m_processId)
			{
// 				pEventCategoryClass = GetEventCategoryClass(_bstr_t(ClassGuid), pEvent->Header.Version);
// 				if(pEventCategoryClass)
// 				{
// 					pEventClass = GetEventClass(pEventCategoryClass, pEvent->Header.Class.Type);
// 					pEventCategoryClass->Release();
// 					pEventCategoryClass = NULL;
// 					if(pEventClass)
// 					{
// 						if(TRUE == GetPropertyList(pEventClass, &pProperties, &PropertyCount, &pProPertyIndex))
// 						{
							
							CopyMemory(&diskReadTransfer, pEventData + sizeof(UINT32) + sizeof(UINT32), sizeof(ULONG));
							CopyMemory(&highResResponseTime, pEventData + 24+2*MOF_POINTERSIZE, sizeof(ULONGLONG));

							LARGE_INTEGER Frequency;
							QueryPerformanceFrequency(&Frequency); 

							highResResponseTime = highResResponseTime * 1000000 / Frequency.QuadPart;

							m_totalReadTime += highResResponseTime;
							m_totalReadBytes += diskReadTransfer;
							TimeStamp = pEvent->Header.TimeStamp.QuadPart;

							UINT64 fileObjectPtr = 0;
							CopyMemory(&fileObjectPtr, pEventData + 24, MOF_POINTERSIZE);



							MAP_FILEOBJ_ITE mapIte = m_mapFileObjectToFileName.begin();
							for(; mapIte != m_mapFileObjectToFileName.end() ; ++mapIte)
							{
								if(mapIte->first == fileObjectPtr)
									break;
							}

							if(mapIte == m_mapFileObjectToFileName.end())
							{
								fileIoInfo fileIo;
								ZeroMemory(&fileIo,sizeof(fileIo));
								fileIo.fileIoSize = diskReadTransfer;
								fileIo.fileObjectPtr = fileObjectPtr;
								fileIo.fileIoTime = highResResponseTime;
								m_vecNotFindPtrFile.push_back(fileIo);
							}

							else
							{
								VEC_FILEINFO_ITE ite = m_vecFileIoInfo.begin();
								for(; ite != m_vecFileIoInfo.end(); ++ite)
								{
									if(ite->fileObjectPtr == fileObjectPtr && wcscmp(ite->fileName.c_str(), mapIte->second.c_str()) == 0 )
									{
										ite->fileIoSize += diskReadTransfer;
										ite->fileIoTime += highResResponseTime;
										break;
									}
								}
								if(ite == m_vecFileIoInfo.end())
								{
									fileIoInfo fileIo;
									ZeroMemory(&fileIo,sizeof(fileIo));
									fileIo.fileName = mapIte->second;
									fileIo.fileIoSize = diskReadTransfer;
									fileIo.fileObjectPtr = fileObjectPtr;
									fileIo.fileIoTime = highResResponseTime;
									m_vecFileIoInfo.push_back(fileIo);
								}
							}


// 							PBYTE pEndEventData = pEventData + pEvent->MofLength;
// 							PBYTE pEventPre = pEventData;
// 							for(int i=0; i < PropertyCount; ++i)
// 							{
// 								PrintPropertyName(pProperties + pProPertyIndex[i]);
// 								pEventData = PrintEventPropertyValue(pProperties + pProPertyIndex[i], pEventData, pEndEventData - pEventData);
// 								wprintf(L"ofsset of property :%d", pEventData - pEventPre);
// 							}
// 
// 						}
// 					}
// 				}
			}
		}
	}

}