Skip to content

Commit

Permalink
Add MachO dump writer to createdump
Browse files Browse the repository at this point in the history
Instead of the hacky ELF core dumps on MacOS now createdump generates true MachO dumps.

Setting the COMPlus_DbgEnableElfDumpOnMacOS environment variable is no longer needed.

Add special thread info memory region containing the OS thread ids missing from macho core dumps. This allows SOS to map the thread indexes to thread ids. The address (0x7fffffff00000000) of this special memory region is above the highest user address (0x0007FFFFFFFFF000) and below a kernel reserved address (0xffffff8000xxxxxx) which is kind of moot because dumps don't include any kernel regions. lldb seems just fine with this memory region.

The changes include ARM64 support also, but since I don't have a M1 device I can't build/test them. I'm hoping Steve can at least review them.

Add --verbose/TRACE_VERBOSE support to tone down all the macho dump generation spew.

Issue: dotnet#48664
  • Loading branch information
mikem8361 committed Apr 12, 2021
1 parent 8d102e3 commit ef165f2
Show file tree
Hide file tree
Showing 21 changed files with 1,166 additions and 927 deletions.
2 changes: 2 additions & 0 deletions src/coreclr/debug/createdump/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ if(CLR_CMAKE_HOST_OSX)
add_executable_clr(createdump
crashinfomac.cpp
threadinfomac.cpp
dumpwritermacho.cpp
${CREATEDUMP_SOURCES}
)
else()
add_executable_clr(createdump
crashinfounix.cpp
threadinfounix.cpp
dumpwriterelf.cpp
${CREATEDUMP_SOURCES}
${PAL_REDEFINES_FILE}
)
Expand Down
27 changes: 22 additions & 5 deletions src/coreclr/debug/createdump/crashinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,13 @@ CrashInfo::GatherCrashInfo(MINIDUMP_TYPE minidumpType)
return false;
}
#endif
TRACE("Module addresses:\n");
for (const MemoryRegion& region : m_moduleAddresses)
if (g_diagnosticsVerbose)
{
region.Trace();
TRACE_VERBOSE("Module addresses:\n");
for (const MemoryRegion& region : m_moduleAddresses)
{
region.Trace();
}
}
// If full memory dump, include everything regardless of permissions
if (minidumpType & MiniDumpWithFullMemory)
Expand Down Expand Up @@ -589,7 +592,7 @@ CrashInfo::CombineMemoryRegions()

TRACE("CombineMemoryRegions: FINISHED\n");

if (g_diagnostics)
if (g_diagnosticsVerbose)
{
TRACE("Memory Regions:\n");
for (const MemoryRegion& region : m_memoryRegions)
Expand Down Expand Up @@ -619,7 +622,21 @@ CrashInfo::SearchMemoryRegions(const std::set<MemoryRegion>& regions, const Memo
void
CrashInfo::Trace(const char* format, ...)
{
if (g_diagnostics) {
if (g_diagnostics)
{
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
fflush(stdout);
va_end(args);
}
}

void
CrashInfo::TraceVerbose(const char* format, ...)
{
if (g_diagnosticsVerbose)
{
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
Expand Down
8 changes: 6 additions & 2 deletions src/coreclr/debug/createdump/crashinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "../dbgutil/machoreader.h"
#else
#include "../dbgutil/elfreader.h"
#endif

// typedef for our parsing of the auxv variables in /proc/pid/auxv.
#if TARGET_64BIT
Expand All @@ -29,6 +28,8 @@ typedef __typeof__(((elf_aux_entry*) 0)->a_un.a_val) elf_aux_val_t;
// All interesting auvx entry types are AT_SYSINFO_EHDR and below
#define AT_MAX (AT_SYSINFO_EHDR + 1)

#endif

class CrashInfo : public ICLRDataEnumMemoryRegionsCallback,
#ifdef __APPLE__
public MachOReader
Expand All @@ -53,8 +54,8 @@ class CrashInfo : public ICLRDataEnumMemoryRegionsCallback,
std::set<MemoryRegion> m_allMemoryRegions; // all memory regions on MacOS
#else
std::array<elf_aux_val_t, AT_MAX> m_auxvValues; // auxv values
#endif
std::vector<elf_aux_entry> m_auxvEntries; // full auxv entries
#endif
std::vector<ThreadInfo*> m_threads; // threads found and suspended
std::set<MemoryRegion> m_moduleMappings; // module memory mappings
std::set<MemoryRegion> m_otherMappings; // other memory mappings
Expand Down Expand Up @@ -87,8 +88,10 @@ class CrashInfo : public ICLRDataEnumMemoryRegionsCallback,
inline const std::set<MemoryRegion> ModuleMappings() const { return m_moduleMappings; }
inline const std::set<MemoryRegion> OtherMappings() const { return m_otherMappings; }
inline const std::set<MemoryRegion> MemoryRegions() const { return m_memoryRegions; }
#ifndef __APPLE__
inline const std::vector<elf_aux_entry> AuxvEntries() const { return m_auxvEntries; }
inline size_t GetAuxvSize() const { return m_auxvEntries.size() * sizeof(elf_aux_entry); }
#endif

// IUnknown
STDMETHOD(QueryInterface)(___in REFIID InterfaceId, ___out PVOID* Interface);
Expand Down Expand Up @@ -122,4 +125,5 @@ class CrashInfo : public ICLRDataEnumMemoryRegionsCallback,
bool ValidRegion(const MemoryRegion& region);
void CombineMemoryRegions();
void Trace(const char* format, ...);
void TraceVerbose(const char* format, ...);
};
18 changes: 6 additions & 12 deletions src/coreclr/debug/createdump/crashinfomac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ CrashInfo::Initialize()
fprintf(stderr, "task_for_pid(%d) FAILED %x %s\n", m_pid, result, mach_error_string(result));
return false;
}
m_auxvEntries.push_back(elf_aux_entry { AT_BASE, { 0 } });
m_auxvEntries.push_back(elf_aux_entry { AT_NULL, { 0 } });
return true;
}

Expand Down Expand Up @@ -110,7 +108,7 @@ CrashInfo::EnumerateMemoryRegions()
TRACE("mach_vm_region_recurse for address %016llx %08llx FAILED %x %s\n", address, size, result, mach_error_string(result));
break;
}
TRACE("%016llx - %016llx (%06llx) %08llx %s %d %d %d %c%c%c %02x\n",
TRACE_VERBOSE("%016llx - %016llx (%06llx) %08llx %s %d %d %d %c%c%c %02x\n",
address,
address + size,
size / PAGE_SIZE,
Expand Down Expand Up @@ -291,9 +289,11 @@ void CrashInfo::VisitSegment(MachOModule& module, const segment_command_64& segm
const auto& found = m_moduleMappings.find(moduleRegion);
if (found == m_moduleMappings.end())
{
TRACE("VisitSegment: ");
moduleRegion.Trace();

if (g_diagnosticsVerbose)
{
TRACE_VERBOSE("VisitSegment: ");
moduleRegion.Trace();
}
// Add this module segment to the module mappings list
m_moduleMappings.insert(moduleRegion);

Expand Down Expand Up @@ -380,9 +380,3 @@ CrashInfo::ReadProcessMemory(void* address, void* buffer, size_t size, size_t* r
*read = numberOfBytesRead;
return size == 0 || numberOfBytesRead > 0;
}

// For src/inc/llvm/ELF.h
Elf64_Ehdr::Elf64_Ehdr()
{
}

7 changes: 5 additions & 2 deletions src/coreclr/debug/createdump/createdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
#endif

extern void trace_printf(const char* format, ...);
extern void trace_verbose_printf(const char* format, ...);
extern bool g_diagnostics;
extern bool g_diagnosticsVerbose;

#ifdef HOST_UNIX
#define TRACE(args...) trace_printf(args)
#define TRACE_VERBOSE(args...)
#define TRACE_VERBOSE(args...) trace_verbose_printf(args)
#else
#define TRACE(args, ...)
#define TRACE_VERBOSE(args, ...)
Expand Down Expand Up @@ -82,7 +84,8 @@ typedef int T_CONTEXT;
#include <string>
#ifdef HOST_UNIX
#ifdef __APPLE__
#include "mac.h"
#include <mach/mach.h>
#include <mach/mach_vm.h>
#endif
#include "datatarget.h"
#include "threadinfo.h"
Expand Down
Loading

0 comments on commit ef165f2

Please sign in to comment.