diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -56,6 +56,19 @@ "%s resolved via direct object file approach to 0x%" PRIx64, __FUNCTION__, info_location); } else { + const Symbol *_r_debug = + target->GetExecutableModule()->FindFirstSymbolWithNameAndType( + ConstString("_r_debug")); + if (_r_debug) { + info_addr = _r_debug->GetAddress().GetLoadAddress(target); + if (info_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "%s resolved by finding symbol '_r_debug' whose value is " + "0x%" PRIx64, + __FUNCTION__, info_addr); + return info_addr; + } + } LLDB_LOGF(log, "%s FAILED - direct object file approach did not yield a " "valid address", diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -333,28 +333,48 @@ LLDB_LOG(log, "Rendezvous structure is not set up yet. " "Trying to locate rendezvous breakpoint in the interpreter " "by symbol name."); - ModuleSP interpreter = LoadInterpreterModule(); - if (!interpreter) { - LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set."); - return false; - } - - // Function names from different dynamic loaders that are known to be used - // as rendezvous between the loader and debuggers. + // Function names from different dynamic loaders that are known to be + // used as rendezvous between the loader and debuggers. static std::vector DebugStateCandidates{ "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", "r_debug_state", "_r_debug_state", "_rtld_debug_state", }; - FileSpecList containingModules; - containingModules.Append(interpreter->GetFileSpec()); - dyld_break = target.CreateBreakpoint( - &containingModules, nullptr /* containingSourceFiles */, - DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, - 0, /* offset */ - eLazyBoolNo, /* skip_prologue */ - true, /* internal */ - false /* request_hardware */); + ModuleSP interpreter = LoadInterpreterModule(); + if (!interpreter) { + if (NameMatches(m_process->GetTarget() + .GetExecutableModulePointer() + ->GetFileSpec() + .GetFilename() + .GetCString(), + NameMatch::StartsWith, "ld-")) { + FileSpecList containingModules; + containingModules.Append( + m_process->GetTarget().GetExecutableModulePointer()->GetFileSpec()); + + dyld_break = target.CreateBreakpoint( + &containingModules, nullptr /* containingSourceFiles */, + DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, + 0, /* offset */ + eLazyBoolNo, /* skip_prologue */ + true, /* internal */ + false /* request_hardware */); + } else { + LLDB_LOG(log, + "Can't find interpreter, rendezvous breakpoint isn't set."); + return false; + } + } else { + FileSpecList containingModules; + containingModules.Append(interpreter->GetFileSpec()); + dyld_break = target.CreateBreakpoint( + &containingModules, nullptr /* containingSourceFiles */, + DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, + 0, /* offset */ + eLazyBoolNo, /* skip_prologue */ + true, /* internal */ + false /* request_hardware */); + } } if (dyld_break->GetNumResolvedLocations() != 1) { diff --git a/lldb/test/Shell/ObjectFile/ELF/Inputs/main.cpp b/lldb/test/Shell/ObjectFile/ELF/Inputs/main.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/ELF/Inputs/main.cpp @@ -0,0 +1,3 @@ +#include "signal_file.h" + +int main() { return get_signal_crash(); } diff --git a/lldb/test/Shell/ObjectFile/ELF/Inputs/signal_file.h b/lldb/test/Shell/ObjectFile/ELF/Inputs/signal_file.h new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/ELF/Inputs/signal_file.h @@ -0,0 +1 @@ +int get_signal_crash(void); diff --git a/lldb/test/Shell/ObjectFile/ELF/Inputs/signal_file.cpp b/lldb/test/Shell/ObjectFile/ELF/Inputs/signal_file.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/ELF/Inputs/signal_file.cpp @@ -0,0 +1,7 @@ +#include "signal_file.h" +#include + +int get_signal_crash(void) { + raise(SIGSEGV); + return 0; +} diff --git a/lldb/test/Shell/ObjectFile/ELF/ld_test.test b/lldb/test/Shell/ObjectFile/ELF/ld_test.test new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/ELF/ld_test.test @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# REQUIRES: system-linux +# +# RUN: %clang -target x86_64-pc-linux -o %t1.o -c %S/Inputs/signal_file.cpp +# RUN: %clang -target x86_64-pc-linux -o %t2.o -c %S/Inputs/main.cpp +# RUN: %clang -target x86_64-pc-linux -shared %t1.o -o %t3.so +# RUN: %clang -o %tmain %t2.o %t3.so -L. -Wl,-rpath,%t +# +# RUN: echo '-n' > %t.in +# RUN: echo 'run' >> %t.in +# RUN: echo 'bt' >> %t.in +# +# RUN: %lldb -b -s %t.in -- %tmain 2>&1 | FileCheck %s +# +# RUN: %lldb -b -s %t.in -- /lib64/ld-linux-x86-64.so.2 --library-path %t %tmain 2>&1 | FileCheck %s +# +# bt +# CHECK: (lldb) bt +# CHECK: ld_test.test.tmp3.so`get_signal_crash() +#