forked from OSchip/llvm-project
Improve dynamic loader support in DynamicLoaderPOSIXDYLD when using core files.
Prior to this fix, no shared libraries would be loaded for a core file, even if they exist on the current machine. The issue was the DYLDRendezvous would read a DYLDRendezvous::Rendezvous from memory of the process in DYLDRendezvous::Resolve() which would read some ld.so structures as they existed in the middle of a process' lifetime. In core files we see, the DYLDRendezvous::Rendezvous::state would be set to eAdd for running processes. When ProcessELFCore.cpp would load the core file, it would call DynamicLoaderPOSIXDYLD::DidAttach(), which would call the above Rendezvous functions. The issue came when during the DidAttach function it call DYLDRendezvous::GetAction() which would return eNoAction if the DYLDRendezvous::m_current.state was read from memory as eAdd. This caused no shared libraries to be loaded for any ELF core files. We now detect if we have a core file and after reading the DYLDRendezvous::m_current.state from memory we set it to eConsistent, which causes DYLDRendezvous::GetAction() to return the correct action of eTakeSnapshot and shared libraries get loaded. We also improve the DynamicLoaderPOSIXDYLD class to not try and set any breakpoints to catch shared library loads/unloads when we have a core file, which saves a bit of time. Differential Revision: https://reviews.llvm.org/D134842
This commit is contained in:
parent
aaecabe68b
commit
c338516463
|
@ -190,6 +190,14 @@ bool DYLDRendezvous::IsValid() {
|
|||
}
|
||||
|
||||
DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const {
|
||||
// If we have a core file, we will read the current rendezvous state
|
||||
// from the core file's memory into m_current which can be in an inconsistent
|
||||
// state, so we can't rely on its state to determine what we should do. We
|
||||
// always need it to load all of the shared libraries one time when we attach
|
||||
// to a core file.
|
||||
if (IsCoreFile())
|
||||
return eTakeSnapshot;
|
||||
|
||||
switch (m_current.state) {
|
||||
|
||||
case eConsistent:
|
||||
|
@ -664,3 +672,7 @@ void DYLDRendezvous::DumpToLog(Log *log) const {
|
|||
LLDB_LOGF(log, " Prev : %" PRIx64, I->prev);
|
||||
}
|
||||
}
|
||||
|
||||
bool DYLDRendezvous::IsCoreFile() const {
|
||||
return !m_process->IsLiveDebugSession();
|
||||
}
|
||||
|
|
|
@ -267,6 +267,8 @@ protected:
|
|||
|
||||
bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
|
||||
|
||||
bool IsCoreFile() const;
|
||||
|
||||
enum RendezvousAction {
|
||||
eNoAction,
|
||||
eTakeSnapshot,
|
||||
|
|
|
@ -213,6 +213,10 @@ void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
|
|||
void DynamicLoaderPOSIXDYLD::ProbeEntry() {
|
||||
Log *log = GetLog(LLDBLog::DynamicLoader);
|
||||
|
||||
// If we have a core file, we don't need any breakpoints.
|
||||
if (IsCoreFile())
|
||||
return;
|
||||
|
||||
const addr_t entry = GetEntryPoint();
|
||||
if (entry == LLDB_INVALID_ADDRESS) {
|
||||
LLDB_LOGF(
|
||||
|
@ -297,6 +301,11 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
|
|||
|
||||
bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
|
||||
Log *log = GetLog(LLDBLog::DynamicLoader);
|
||||
|
||||
// If we have a core file, we don't need any breakpoints.
|
||||
if (IsCoreFile())
|
||||
return false;
|
||||
|
||||
if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
|
||||
LLDB_LOG(log,
|
||||
"Rendezvous breakpoint breakpoint id {0} for pid {1}"
|
||||
|
@ -829,3 +838,7 @@ bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
|
|||
|
||||
return module_sp->GetFileSpec().GetPath() == "[vdso]";
|
||||
}
|
||||
|
||||
bool DynamicLoaderPOSIXDYLD::IsCoreFile() const {
|
||||
return !m_process->IsLiveDebugSession();
|
||||
}
|
||||
|
|
|
@ -91,6 +91,9 @@ protected:
|
|||
std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
|
||||
m_loaded_modules;
|
||||
|
||||
/// Returns true if the process is for a core file.
|
||||
bool IsCoreFile() const;
|
||||
|
||||
/// If possible sets a breakpoint on a function called by the runtime
|
||||
/// linker each time a module is loaded or unloaded.
|
||||
bool SetRendezvousBreakpoint();
|
||||
|
|
Loading…
Reference in New Issue