Skip to content
Merged
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
46 changes: 32 additions & 14 deletions lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec &core_file)
: PostMortemProcess(target_sp, listener_sp, core_file) {}
: PostMortemProcess(target_sp, listener_sp, core_file), m_uuids() {}

// Destructor
ProcessElfCore::~ProcessElfCore() {
Expand Down Expand Up @@ -257,12 +257,12 @@ Status ProcessElfCore::DoLoadCore() {
// the main executable using data we found in the core file notes.
lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
if (!exe_module_sp) {
// The first entry in the NT_FILE might be our executable
if (!m_nt_file_entries.empty()) {
llvm::StringRef executable_path = GetMainExecutablePath();
ModuleSpec exe_module_spec;
exe_module_spec.GetArchitecture() = arch;
exe_module_spec.GetUUID() = m_nt_file_entries[0].uuid;
exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path,
exe_module_spec.GetUUID() = FindModuleUUID(executable_path);
exe_module_spec.GetFileSpec().SetFile(executable_path,
FileSpec::Style::native);
if (exe_module_spec.GetFileSpec()) {
exe_module_sp =
Expand All @@ -277,21 +277,38 @@ Status ProcessElfCore::DoLoadCore() {

void ProcessElfCore::UpdateBuildIdForNTFileEntries() {
Log *log = GetLog(LLDBLog::Process);
m_uuids.clear();
for (NT_FILE_Entry &entry : m_nt_file_entries) {
entry.uuid = FindBuidIdInCoreMemory(entry.start);
if (log && entry.uuid.IsValid())
LLDB_LOGF(log, "%s found UUID @ %16.16" PRIx64 ": %s \"%s\"",
__FUNCTION__, entry.start, entry.uuid.GetAsString().c_str(),
entry.path.c_str());
UUID uuid = FindBuidIdInCoreMemory(entry.start);
if (uuid.IsValid()) {
// Assert that either the path is not in the map or the UUID matches
assert(m_uuids.count(entry.path) == 0 || m_uuids[entry.path] == uuid);
m_uuids[entry.path] = uuid;
if (log)
LLDB_LOGF(log, "%s found UUID @ %16.16" PRIx64 ": %s \"%s\"",
__FUNCTION__, entry.start, uuid.GetAsString().c_str(),
entry.path.c_str());
}
}
}

llvm::StringRef ProcessElfCore::GetMainExecutablePath() {
if (m_nt_file_entries.empty())
return "";

// The first entry in the NT_FILE might be our executable
llvm::StringRef executable_path = m_nt_file_entries[0].path;
// Prefer the NT_FILE entry matching m_executable_name as main executable.
for (const NT_FILE_Entry &file_entry : m_nt_file_entries)
if (llvm::StringRef(file_entry.path).ends_with("/" + m_executable_name)) {
executable_path = file_entry.path;
break;
}
return executable_path;
}

UUID ProcessElfCore::FindModuleUUID(const llvm::StringRef path) {
// Returns the gnu uuid from matched NT_FILE entry
for (NT_FILE_Entry &entry : m_nt_file_entries)
if (path == entry.path && entry.uuid.IsValid())
return entry.uuid;
return UUID();
return m_uuids[std::string(path)];
}

lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
Expand Down Expand Up @@ -935,6 +952,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
return status.ToError();
thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
SetID(prpsinfo.pr_pid);
m_executable_name = prpsinfo.pr_fname;
break;
}
case ELF::NT_SIGINFO: {
Expand Down
14 changes: 10 additions & 4 deletions lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H

#include <list>
#include <unordered_map>
#include <vector>

#include "lldb/Target/PostMortemProcess.h"
Expand Down Expand Up @@ -115,10 +116,6 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
lldb::addr_t end;
lldb::addr_t file_ofs;
std::string path;
// Add a UUID member for convenient access. The UUID value is not in the
// NT_FILE entries, we will find it in core memory and store it here for
// easy access.
lldb_private::UUID uuid;
};

// For ProcessElfCore only
Expand Down Expand Up @@ -152,6 +149,12 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
// NT_FILE entries found from the NOTE segment
std::vector<NT_FILE_Entry> m_nt_file_entries;

// Map from file path to UUID for quick lookup
std::unordered_map<std::string, lldb_private::UUID> m_uuids;

// Executable name found from the ELF PRPSINFO
std::string m_executable_name;

// Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
llvm::Error ParseThreadContextsFromNoteSegment(
const elf::ELFProgramHeader &segment_header,
Expand All @@ -165,6 +168,9 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {

lldb_private::UUID FindModuleUUID(const llvm::StringRef path) override;

// Returns the main executable path
llvm::StringRef GetMainExecutablePath();

// Returns the value of certain type of note of a given start address
lldb_private::UUID FindBuidIdInCoreMemory(lldb::addr_t address);

Expand Down
Loading