Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add native frame symbolization (unmanaged_name) using dladdr. #55305

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/coreclr/debug/createdump/crashinfomac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

#include "createdump.h"
#include <cxxabi.h>

bool
CrashInfo::Initialize()
Expand Down Expand Up @@ -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;
}
8 changes: 7 additions & 1 deletion src/coreclr/debug/createdump/crashreportwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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());
}
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/debug/createdump/createdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef int T_CONTEXT;
#endif
#include <dirent.h>
#include <fcntl.h>
#include <dlfcn.h>
#ifdef __APPLE__
#include <ELF.h>
#else
Expand Down
25 changes: 22 additions & 3 deletions src/coreclr/debug/createdump/moduleinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}

Expand All @@ -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)
{
}

Expand All @@ -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; }
Expand All @@ -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;
Expand Down