Ejemplo n.º 1
0
//Helper function to quickly print debug info
bool Library::print(
        const std::string &modName, uint64_t loadBase, uint64_t imageBase,
        uint64_t pc, std::string &out, bool file, bool line, bool func)
{

    ExecutableFile *exec = get(modName);
    if (!exec) {
        return false;
    }

    uint64_t reladdr = pc - loadBase + imageBase;
    std::string source, function;
    uint64_t ln;
    if (!exec->getInfo(reladdr, source, ln, function)) {
        return false;
    }

    std::stringstream ss;

    if (file) {
        ss << source;
    }

    if (line) {
        ss << ":" << ln;
    }

    if (func) {
        ss << " - " << function;
    }

    out = ss.str();

    return true;
}
Ejemplo n.º 2
0
bool Library::getInfo(const ModuleInstance *mi, uint64_t pc, std::string &file, uint64_t &line, std::string &func)
{
    if(!mi)
        return false;
    ExecutableFile *exec = get(mi->Name);
    if (!exec) {
        return false;
    }

    uint64_t reladdr = pc - mi->LoadBase + mi->ImageBase;
    if (!exec->getInfo(reladdr, file, line, func)) {
        return false;
    }

    return true;
}
Ejemplo n.º 3
0
HRESULT BaseStackWalkContext::FindSymbolInterface(gtVAddr virtualAddr, IDiaSymbol** ppSymbol) const
{
    assert(NULL != m_pWorkingSet);
    HRESULT hr = E_FAIL;
    ExecutableFile* pExe = m_pWorkingSet->FindModule(virtualAddr);

    if (NULL != pExe)
    {
        SymbolEngine* pSymbolEngine = pExe->GetSymbolEngine();

        if (NULL != pSymbolEngine)
        {
            hr = pSymbolEngine->FindSymbolInterface(virtualAddr, ppSymbol);
        }
    }

    return hr;
}
Ejemplo n.º 4
0
gtVAddr BaseStackWalkContext::GetImageLoadAddress(gtVAddr virtualAddr, gtVAddr& baseAddr) const
{
    assert(NULL != m_pWorkingSet);
    gtVAddr loadAddr;
    ExecutableFile* pExe = m_pWorkingSet->FindModule(virtualAddr);

    if (NULL != pExe)
    {
        baseAddr = pExe->GetImageBase();
        loadAddr = pExe->GetLoadAddress();
    }
    else
    {
        baseAddr = 0ULL;
        loadAddr = 0ULL;
    }

    return loadAddr;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
gtVAddr BaseStackWalkContext::GetImageLoadAddress(gtVAddr virtualAddr) const
{
    assert(NULL != m_pWorkingSet);
    ExecutableFile* pExe = m_pWorkingSet->FindModule(virtualAddr);
    return (NULL != pExe) ? pExe->GetLoadAddress() : 0ULL;
}