Exemple #1
0
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;
}