diff --git a/src/coreclr/debug/createdump/crashinfomac.cpp b/src/coreclr/debug/createdump/crashinfomac.cpp index 4461d2a8c96a55..855917caafd1e8 100644 --- a/src/coreclr/debug/createdump/crashinfomac.cpp +++ b/src/coreclr/debug/createdump/crashinfomac.cpp @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #include "createdump.h" +#include bool CrashInfo::Initialize() @@ -380,3 +381,54 @@ CrashInfo::ReadProcessMemory(void* address, void* buffer, size_t size, size_t* r *read = numberOfBytesRead; return size == 0 || numberOfBytesRead > 0; } + +const struct dyld_all_image_infos* g_image_infos = nullptr; + +// +// Lookup a symbol in a module. The caller needs to call "free()" on symbol returned. +// +const char* +ModuleInfo::GetSymbolName(uint64_t address) +{ + if (m_module == nullptr) + { + m_module = dlopen(m_moduleName.c_str(), RTLD_LAZY); + if (m_module != nullptr) + { + if (g_image_infos == nullptr) + { + struct task_dyld_info dyld_info; + mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; + kern_return_t result = task_info(mach_task_self_, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count); + if (result == KERN_SUCCESS) + { + g_image_infos = (const struct dyld_all_image_infos*)dyld_info.all_image_info_addr; + } + } + if (g_image_infos != nullptr) + { + for (int i = 0; i < g_image_infos->infoArrayCount; ++i) + { + const struct dyld_image_info* image = g_image_infos->infoArray + i; + if (strcasecmp(image->imageFilePath, m_moduleName.c_str()) == 0) + { + m_localBaseAddress = (uint64_t)image->imageLoadAddress; + break; + } + } + } + } + } + if (m_localBaseAddress != 0) + { + uint64_t localAddress = m_localBaseAddress + (address - m_baseAddress); + Dl_info info; + if (dladdr((void*)localAddress, &info) != 0) + { + int status = -1; + char *demangled = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status); + return status == 0 ? demangled : strdup(info.dli_sname); + } + } + return nullptr; +} diff --git a/src/coreclr/debug/createdump/crashreportwriter.cpp b/src/coreclr/debug/createdump/crashreportwriter.cpp index 9cac899968f881..de2fe0da584c8a 100644 --- a/src/coreclr/debug/createdump/crashreportwriter.cpp +++ b/src/coreclr/debug/createdump/crashreportwriter.cpp @@ -176,7 +176,7 @@ CrashReportWriter::WriteStackFrame(const StackFrame& frame) } if (frame.ModuleAddress() != 0) { - const ModuleInfo* moduleInfo = m_crashInfo.GetModuleInfoFromBaseAddress(frame.ModuleAddress()); + ModuleInfo* moduleInfo = (ModuleInfo*)m_crashInfo.GetModuleInfoFromBaseAddress(frame.ModuleAddress()); if (moduleInfo != nullptr) { std::string moduleName = GetFileName(moduleInfo->ModuleName()); @@ -189,6 +189,12 @@ CrashReportWriter::WriteStackFrame(const StackFrame& frame) } else { + const char* symbol = moduleInfo->GetSymbolName(frame.ReturnAddress()); + if (symbol != nullptr) + { + WriteValue("unmanaged_name", symbol); + free((void*)symbol); + } WriteValue("native_module", moduleName.c_str()); } } diff --git a/src/coreclr/debug/createdump/createdump.h b/src/coreclr/debug/createdump/createdump.h index 95f63f460e4af5..ca6a66b7b594c0 100644 --- a/src/coreclr/debug/createdump/createdump.h +++ b/src/coreclr/debug/createdump/createdump.h @@ -71,6 +71,7 @@ typedef int T_CONTEXT; #endif #include #include +#include #ifdef __APPLE__ #include #else diff --git a/src/coreclr/debug/createdump/moduleinfo.h b/src/coreclr/debug/createdump/moduleinfo.h index f07e50d592f08a..96d8069bfc6741 100644 --- a/src/coreclr/debug/createdump/moduleinfo.h +++ b/src/coreclr/debug/createdump/moduleinfo.h @@ -10,10 +10,14 @@ struct ModuleInfo GUID m_mvid; std::string m_moduleName; bool m_isManaged; + void* m_module; + uint64_t m_localBaseAddress; public: ModuleInfo(uint64_t baseAddress) : - m_baseAddress(baseAddress) + m_baseAddress(baseAddress), + m_module(nullptr), + m_localBaseAddress(0) { } @@ -23,7 +27,9 @@ struct ModuleInfo m_imageSize(imageSize), m_mvid(*mvid), m_moduleName(moduleName), - m_isManaged(isManaged) + m_isManaged(isManaged), + m_module(nullptr), + m_localBaseAddress(0) { } @@ -34,13 +40,22 @@ struct ModuleInfo m_imageSize(moduleInfo.m_imageSize), m_mvid(moduleInfo.m_mvid), m_moduleName(moduleInfo.m_moduleName), - m_isManaged(moduleInfo.m_isManaged) + m_isManaged(moduleInfo.m_isManaged), + m_module(nullptr), + m_localBaseAddress(0) { } +#ifdef __APPLE__ ~ModuleInfo() { + if (m_module != nullptr) + { + dlclose(m_module); + m_module = nullptr; + } } +#endif inline bool IsManaged() const { return m_isManaged; } inline uint64_t BaseAddress() const { return m_baseAddress; } @@ -49,6 +64,10 @@ struct ModuleInfo inline const GUID* Mvid() const { return &m_mvid; } inline const std::string& ModuleName() const { return m_moduleName; } +#ifdef __APPLE__ + const char* GetSymbolName(uint64_t address); +#endif + bool operator<(const ModuleInfo& rhs) const { return m_baseAddress < rhs.m_baseAddress;