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; }
bool JavaJncReader::Open(const wchar_t* pWFileName) { JncPcStackInfoMap::iterator it; char fileName[261]; memset(fileName, 0, sizeof(fileName)); if (nullptr == pWFileName) { return false; } wcstombs(fileName, pWFileName, 260); ExecutableFile* pExecutable = ExecutableFile::Open(pWFileName); if (nullptr == pExecutable) { return false; } m_sectionCounts = pExecutable->GetSectionsCount(); // Get The .text section unsigned codeSecIndex = pExecutable->LookupSectionIndex(".text"); gtRVAddr codeStartRva = 0, codeEndRva = 0; pExecutable->GetSectionRvaLimits(codeSecIndex, codeStartRva, codeEndRva); m_pCodeBuf = pExecutable->GetSectionBytes(codeSecIndex); m_loadAddr = static_cast<gtRVAddr>(codeStartRva) + pExecutable->GetImageBase(); m_textOffset = codeStartRva; m_textSize = codeEndRva - codeStartRva; if (nullptr == m_pCodeBuf || m_textSize <= 0) { delete pExecutable; return false; } // Get the .stringtable m_string_table_buf = pExecutable->GetSectionBytes(pExecutable->LookupSectionIndex(".stringtable")); if (nullptr == m_string_table_buf) { // JNC Files for Native methods won't have stringtable, bc2src and pc2bc sections.. m_pExecutable = pExecutable; return true; } if (!_process_stringtable_section()) { delete pExecutable; m_pExecutable = nullptr; return false; } // Process .bc2src m_pBc2srcBuf = pExecutable->GetSectionBytes(pExecutable->LookupSectionIndex(".bc2src")); if (nullptr == m_pBc2srcBuf) { delete pExecutable; m_pExecutable = nullptr; return false; } if (!_process_bc2src_section()) { delete pExecutable; m_pExecutable = nullptr; return false; } // Process the .pc2bc m_pPc2bcBuf = pExecutable->GetSectionBytes(pExecutable->LookupSectionIndex(".pc2bc")); if (nullptr == m_pPc2bcBuf) { OS_OUTPUT_FORMAT_DEBUG_LOG(OS_DEBUG_LOG_DEBUG, L"Warning: file %hs does not have pc-to-byte code information", fileName); delete pExecutable; m_pExecutable = nullptr; return false; } if (!_process_pc2bc_section()) { delete pExecutable; m_pExecutable = nullptr; return false; } // Setup inline information map if (!_process_inline_map()) { delete pExecutable; m_pExecutable = nullptr; return false; } // DEBUG: dump the java inline entries // DumpJavaInlineMap(); // Identify the main method for this JNC if (m_jncPcStackInfoMap.empty()) { // If there is no PC stack info, we should still be able to // provide disassembly details. Hence return true; return true; } it = m_jncPcStackInfoMap.begin(); m_mainMethodId = it->second->methods[it->second->numstackframes - 1]; m_methodName = m_jncMethodMap[m_mainMethodId].name; m_srcFile = m_jncMethodMap[m_mainMethodId].sourceName; if (m_jncMethodMap[m_mainMethodId].lineNumberVec.size() > 0) { m_startLine = m_jncMethodMap[m_mainMethodId].lineNumberVec[0].line_number; m_possibleEndLine = m_jncMethodMap[m_mainMethodId].lineNumberVec[m_jncMethodMap[m_mainMethodId].lineNumberVec.size() - 1].line_number; } m_mainInlineDepth = it->second->numstackframes; for (unsigned int i = 0; i < m_addressRangeTable.size(); i++) { if (m_addressRangeTable[i].id == m_mainMethodId) { m_addressRangeTable[i].pc_start = m_loadAddr; } } m_pExecutable = pExecutable; return true; }