int BaseStackWalkContext::ReadMemory(ReadMemoryType type, gtVAddr virtualAddr, gtUByte* pBuffer, int len) const { int lenRead = -1; if (MEM_TYPE_CODE != type) { assert(NULL != m_pStack); if (m_pStack->IsStackAddress(virtualAddr)) { lenRead = len; if (NULL != pBuffer) { m_pStack->ReadMemory(virtualAddr, pBuffer, static_cast<gtUInt32>(len)); } } } if (0 > lenRead && MEM_TYPE_STACK != type) { assert(NULL != m_pWorkingSet); ExecutableFile* pExe = m_pWorkingSet->FindModule(virtualAddr); if (NULL != pExe) { gtUInt32 size = static_cast<gtUInt32>(len); const gtUByte* pMem = pExe->GetMemoryBlock(pExe->VaToRva(virtualAddr), size); if (NULL != pMem) { if (NULL != pBuffer && 0 != size) { memcpy(pBuffer, pMem, size); } lenRead = size; } } } return lenRead; }
unsigned BaseStackWalkContext::GetSectionInfo(gtVAddr virtualAddr, gtRVAddr& offset) { assert(NULL != m_pWorkingSet); unsigned sectionIndex = INVALID_SECTION_INDEX; ExecutableFile* pExe = m_pWorkingSet->FindModule(virtualAddr); if (NULL != pExe) { gtRVAddr rva = pExe->VaToRva(virtualAddr); unsigned index = pExe->LookupSectionIndex(rva); gtRVAddr startRva, endRva; if (pExe->GetSectionRvaLimits(index, startRva, endRva)) { sectionIndex = index; offset = rva - startRva; } } return sectionIndex; }
bool GetImixInfoList(CpuProfileReader& profileReader, ProcessIdType pid, ThreadIdType tid, CpuProfileModule& module, gtUInt64 flags, gtUInt64 coreMask, ModuleImixInfoList& modImixInfoList, gtUInt64& totalSamples) { GT_UNREFERENCED_PARAMETER(profileReader); GT_UNREFERENCED_PARAMETER(tid); GT_UNREFERENCED_PARAMETER(coreMask); bool rv = true; bool ignoreSysModule = ((flags & SAMPLE_IGNORE_SYSTEM_MODULES) == SAMPLE_IGNORE_SYSTEM_MODULES) ? true : false; bool groupByModule = ((flags & SAMPLE_GROUP_BY_MODULE) == SAMPLE_GROUP_BY_MODULE) ? true : false; totalSamples = 0; if (!ignoreSysModule || !module.isSystemModule()) { gtString exePath = module.getPath(); ExecutableFile* pExecutable = ExecutableFile::Open(exePath.asCharArray(), module.getBaseAddr()); if (nullptr == pExecutable) { rv = false; } if (rv) { const gtUByte* pCode = nullptr; gtRVAddr sectionStartRva = 0, sectionEndRva = 0; unsigned int prevSectionIndex = static_cast<unsigned int>(-1); ModuleImixInfo modInfo; modInfo.m_pModule = &module; gtUInt64 totalModSamples = 0; // Setup disassembler LibDisassembler dasm; // if the code is 64-bits bool isLongMode = pExecutable->Is64Bit(); dasm.SetLongMode(isLongMode); // For each function auto fit = module.getBeginFunction(); auto fitEnd = module.getEndFunction(); for (; fit != fitEnd; ++fit) { CpuProfileFunction& function = fit->second; // For each sample auto sit = function.getBeginSample(); auto sitEnd = function.getEndSample(); for (; sit != sitEnd; ++sit) { const AptKey& aptKey = sit->first; gtVAddr funcOffset = aptKey.m_addr; ProcessIdType sampPid = (groupByModule) ? static_cast<ProcessIdType>(-1) : aptKey.m_pid; if (sampPid != pid) { continue; } gtRVAddr startRVAddr = pExecutable->VaToRva(function.getBaseAddr() + funcOffset); unsigned int sectionIndex = pExecutable->LookupSectionIndex(startRVAddr); BYTE error_code; UIInstInfoType temp_struct; char dasmArray[256] = { 0 }; unsigned int strlength = 255; if (pExecutable->GetSectionsCount() <= sectionIndex) { strcpy(dasmArray, "BAD DASM"); } else if (sectionIndex == prevSectionIndex) { gtRVAddr codeOffset = startRVAddr - sectionStartRva; const gtUByte* pCurrentCode = pCode + codeOffset; // Get disassembly for the current pCode from the disassembler HRESULT hr = dasm.UIDisassemble((BYTE*)pCurrentCode, (unsigned int*)&strlength, (BYTE*)dasmArray, &temp_struct, &error_code); if (S_OK != hr) { strcpy(dasmArray, "BAD DASM"); } } else { pCode = pExecutable->GetSectionBytes(sectionIndex); pExecutable->GetSectionRvaLimits(sectionIndex, sectionStartRva, sectionEndRva); // GetCodeBytes return the pointer to the sectionStart // We need to add the offset to the beginning of the function gtRVAddr codeOffset = startRVAddr - sectionStartRva; const gtUByte* pCurrentCode = pCode + codeOffset; // Get disassembly for the current pCode from the disassembler HRESULT hr = dasm.UIDisassemble((BYTE*)pCurrentCode, (unsigned int*)&strlength, (BYTE*)dasmArray, &temp_struct, &error_code); if (S_OK != hr) { strcpy(dasmArray, "BAD DASM"); } prevSectionIndex = sectionIndex; } std::string dasmString(dasmArray); auto it = modInfo.m_InstMap.find(dasmString); gtUInt64 sampleCount = sit->second.getTotal(); if (it == modInfo.m_InstMap.end()) { modInfo.m_InstMap.insert({ dasmString, sampleCount }); } else { it->second += sampleCount; } totalModSamples += sampleCount; } } delete pExecutable; modInfo.m_samplesCount = totalModSamples; modImixInfoList.push_back(modInfo); totalSamples += totalModSamples; } } return rv; }