コード例 #1
0
ファイル: crashinfo.cpp プロジェクト: elijah6/coreclr
bool
CrashInfo::GatherCrashInfo(const char* pszExePath, MINIDUMP_TYPE minidumpType)
{
    // Get the process info
    if (!GetStatus(m_pid, &m_ppid, &m_tgid, &m_name))
    {
        return false;
    }
    // Get the info about the threads (registers, etc.)
    for (ThreadInfo* thread : m_threads)
    {
        if (!thread->Initialize())
        {
            return false;
        }
    }
    // Get the auxv data
    if (!GetAuxvEntries())
    {
        return false;
    }
    // Get shared module debug info
    if (!GetDSOInfo())
    {
        return false;
    }
    // Gather all the module memory mappings (from /dev/$pid/maps)
    if (!EnumerateModuleMappings())
    {
        return false;
    }
    // Gather all the useful memory regions from the DAC
    if (!EnumerateMemoryRegionsWithDAC(pszExePath, minidumpType))
    {
        return false;
    }
    // Add the thread's stack and some code memory to core
    for (ThreadInfo* thread : m_threads)
    {
        uint64_t start;
        size_t size;

        // Add the thread's stack and some of the code 
        thread->GetThreadStack(*this, &start, &size); 
        InsertMemoryRegion(start, size);

        thread->GetThreadCode(&start, &size);
        InsertMemoryRegion(start, size);
    }
    // Join all adjacent memory regions
    CombineMemoryRegions();
    return true;
}
コード例 #2
0
ファイル: crashinfo.cpp プロジェクト: krytarowski/coreclr
HRESULT STDMETHODCALLTYPE
CrashInfo::EnumMemoryRegion( 
    /* [in] */ CLRDATA_ADDRESS address,
    /* [in] */ ULONG32 size)
{
    InsertMemoryRegion(address, size);
    return S_OK;
}
コード例 #3
0
ファイル: crashinfo.cpp プロジェクト: krytarowski/coreclr
bool
CrashInfo::EnumerateModuleMappings()
{
    // Here we read /proc/<pid>/maps file in order to parse it and figure out what it says 
    // about a library we are looking for. This file looks something like this:
    //
    // [address]          [perms] [offset] [dev] [inode] [pathname] - HEADER is not preset in an actual file
    //
    // 35b1800000-35b1820000 r-xp 00000000 08:02 135522  /usr/lib64/ld-2.15.so
    // 35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522  /usr/lib64/ld-2.15.so
    // 35b1a20000-35b1a21000 rw-p 00020000 08:02 135522  /usr/lib64/ld-2.15.so
    // 35b1a21000-35b1a22000 rw-p 00000000 00:00 0       [heap]
    // 35b1c00000-35b1dac000 r-xp 00000000 08:02 135870  /usr/lib64/libc-2.15.so
    // 35b1dac000-35b1fac000 ---p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
    // 35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
    // 35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870  /usr/lib64/libc-2.15.so
    char* line = NULL;
    size_t lineLen = 0;
    int count = 0;
    ssize_t read;

    // Making something like: /proc/123/maps
    char mapPath[128];
    int chars = snprintf(mapPath, sizeof(mapPath), "/proc/%d/maps", m_pid);
    assert(chars > 0 && chars <= sizeof(mapPath));

    FILE* mapsFile = fopen(mapPath, "r");
    if (mapsFile == NULL)
    {
        fprintf(stderr, "fopen(%s) FAILED %s\n", mapPath, strerror(errno));
        return false;
    }
    // linuxGateAddress is the beginning of the kernel's mapping of
    // linux-gate.so in the process.  It doesn't actually show up in the
    // maps list as a filename, but it can be found using the AT_SYSINFO_EHDR
    // aux vector entry, which gives the information necessary to special
    // case its entry when creating the list of mappings.
    // See http://www.trilithium.com/johan/2005/08/linux-gate/ for more
    // information.
    const void* linuxGateAddress = (const void*)m_auxvValues[AT_SYSINFO_EHDR];

    // Reading maps file line by line 
    while ((read = getline(&line, &lineLen, mapsFile)) != -1)
    {
        uint64_t start, end, offset;
        char* permissions = nullptr;
        char* moduleName = nullptr;

        int c = sscanf(line, "%lx-%lx %m[-rwxsp] %lx %*[:0-9a-f] %*d %ms\n", &start, &end, &permissions, &offset, &moduleName);
        if (c == 4 || c == 5)
        {
            if (linuxGateAddress != nullptr && reinterpret_cast<void*>(start) == linuxGateAddress)
            {
                InsertMemoryRegion(start, end - start);
                free(moduleName);
            }
            else {
                uint32_t permissionFlags = 0;
                if (strchr(permissions, 'r')) {
                    permissionFlags |= PF_R;
                }
                if (strchr(permissions, 'w')) {
                    permissionFlags |= PF_W;
                }
                if (strchr(permissions, 'x')) {
                    permissionFlags |= PF_X;
                }
                MemoryRegion memoryRegion(permissionFlags, start, end, offset, moduleName);

                if (moduleName != nullptr && *moduleName == '/') {
                    m_moduleMappings.insert(memoryRegion);
                }
                else {
                    m_otherMappings.insert(memoryRegion);
                }
            }
            free(permissions);
        }
    }

    if (g_diagnostics)
    {
        TRACE("Module mappings:\n");
        for (const MemoryRegion& region : m_moduleMappings)
        {
            region.Print();
        }
        TRACE("Other mappings:\n");
        for (const MemoryRegion& region : m_otherMappings)
        {
            region.Print();
        }
    }

    free(line); // We didn't allocate line, but as per contract of getline we should free it
    fclose(mapsFile);

    return true;
}
コード例 #4
0
ファイル: crashinfo.cpp プロジェクト: krytarowski/coreclr
bool
CrashInfo::GatherCrashInfo(const char* programPath, MINIDUMP_TYPE minidumpType)
{
    // Get the process info
    if (!GetStatus(m_pid, &m_ppid, &m_tgid, &m_name))
    {
        return false;
    }
    // Get the info about the threads (registers, etc.)
    for (ThreadInfo* thread : m_threads)
    {
        if (!thread->Initialize(m_sos ? m_dataTarget : nullptr))
        {
            return false;
        }
    }
    // Get the auxv data
    if (!GetAuxvEntries())
    {
        return false;
    }
    // Gather all the module memory mappings (from /dev/$pid/maps)
    if (!EnumerateModuleMappings())
    {
        return false;
    }
    // Get shared module debug info
    if (!GetDSOInfo())
    {
        return false;
    }
    // If full memory dump, include everything regardless of permissions
    if (minidumpType & MiniDumpWithFullMemory)
    {
       for (const MemoryRegion& region : m_moduleMappings)
       {
            if (ValidRegion(region))
            {
                InsertMemoryRegion(region);
            }
        }
        for (const MemoryRegion& region : m_otherMappings)
        {
            if (ValidRegion(region))
            {
                InsertMemoryRegion(region);
            }
        }
    }
    else
    {
        // Add all the heap (read/write) memory regions but not the modules' r/w data segments
        if (minidumpType & MiniDumpWithPrivateReadWriteMemory)
        {
            for (const MemoryRegion& region : m_otherMappings)
            {
                if (region.Permissions() == (PF_R | PF_W))
                {
                    if (ValidRegion(region))
                    {
                        InsertMemoryRegion(region);
                    }
                }
            }
        }
        // Gather all the useful memory regions from the DAC
        if (!EnumerateMemoryRegionsWithDAC(programPath, minidumpType))
        {
            return false;
        }
        // Add the thread's stack and some code memory to core
        for (ThreadInfo* thread : m_threads)
        {
            uint64_t start;
            size_t size;

            // Add the thread's stack and some of the code 
            thread->GetThreadStack(*this, &start, &size);
            InsertMemoryRegion(start, size);

            thread->GetThreadCode(&start, &size);
            InsertMemoryRegion(start, size);
        }
    }
    // Join all adjacent memory regions
    CombineMemoryRegions();
    return true;
}