diff options
Diffstat (limited to 'lldb/source/Plugins')
5 files changed, 104 insertions, 2 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 466e6643a18..8cedda651b3 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -139,7 +139,8 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) : m_break_id(LLDB_INVALID_BREAK_ID), m_dyld_image_infos(), m_dyld_image_infos_stop_id (UINT32_MAX), - m_mutex(Mutex::eMutexTypeRecursive) + m_mutex(Mutex::eMutexTypeRecursive), + m_process_image_addr_is_all_images_infos (false) { } @@ -179,6 +180,54 @@ DynamicLoaderMacOSXDYLD::DidLaunch () SetNotificationBreakpoint (); } +bool +DynamicLoaderMacOSXDYLD::ProcessDidExec () +{ + if (m_process) + { + // If we are stopped after an exec, we will have only one thread... + if (m_process->GetThreadList().GetSize() == 1) + { + // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr" + // value differs from the Process' image info address. When a process + // execs itself it might cause a change if ASLR is enabled. + const addr_t shlib_addr = m_process->GetImageInfoAddress (); + if (m_process_image_addr_is_all_images_infos == true && shlib_addr != m_dyld_all_image_infos_addr) + { + // The image info address from the process is the 'dyld_all_image_infos' + // address and it has changed. + return true; + } + + if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address) + { + // The image info address from the process is the mach_header + // address for dyld and it has changed. + return true; + } + + // ASLR might be disabled and dyld could have ended up in the same + // location. We should try and detect if we are stopped at '_dyld_start' + ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0)); + if (thread_sp) + { + lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0)); + if (frame_sp) + { + const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol; + if (symbol) + { + if (symbol->GetName() == ConstString("_dyld_start")) + return true; + } + } + } + } + } + return false; +} + + //---------------------------------------------------------------------- // Clear out the state of this class. @@ -224,7 +273,6 @@ DynamicLoaderMacOSXDYLD::LocateDYLD() // mach header for dyld, or it might point to the // dyld_all_image_infos struct const addr_t shlib_addr = m_process->GetImageInfoAddress (); - ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder(); uint8_t buf[4]; DataExtractor data (buf, sizeof(buf), byte_order, 4); @@ -239,6 +287,7 @@ DynamicLoaderMacOSXDYLD::LocateDYLD() case llvm::MachO::HeaderMagic64: case llvm::MachO::HeaderMagic32Swapped: case llvm::MachO::HeaderMagic64Swapped: + m_process_image_addr_is_all_images_infos = false; return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr); default: @@ -247,6 +296,7 @@ DynamicLoaderMacOSXDYLD::LocateDYLD() } // Maybe it points to the all image infos? m_dyld_all_image_infos_addr = shlib_addr; + m_process_image_addr_is_all_images_infos = true; } if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h index f7e9ac5665a..2e0d2504288 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -62,6 +62,9 @@ public: virtual void DidLaunch (); + virtual bool + ProcessDidExec (); + virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan (lldb_private::Thread &thread, bool stop_others); @@ -372,6 +375,7 @@ protected: uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for mutable lldb_private::Mutex m_mutex; lldb_private::Process::Notifications m_notification_callbacks; + bool m_process_image_addr_is_all_images_infos; private: DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 7db57294dcd..5999e13fb70 100644 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -16,6 +16,8 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/StreamString.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -300,7 +302,39 @@ StopInfoMachException::CreateStopReasonWithMachException case 5: // EXC_SOFTWARE if (exc_code == 0x10003) // EXC_SOFT_SIGNAL + { + if (exc_sub_code == 5) + { + // On MacOSX, a SIGTRAP can signify that a process has called + // exec, so we should check with our dynamic loader to verify. + ProcessSP process_sp (thread.GetProcess()); + if (process_sp) + { + DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader(); + if (dynamic_loader && dynamic_loader->ProcessDidExec()) + { + // The program was re-exec'ed + return StopInfo::CreateStopReasonWithExec (thread); + } +// if (!process_did_exec) +// { +// // We have a SIGTRAP, make sure we didn't exec by checking +// // for the PC being at "_dyld_start"... +// lldb::StackFrameSP frame_sp (thread.GetStackFrameAtIndex(0)); +// if (frame_sp) +// { +// const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol; +// if (symbol) +// { +// if (symbol->GetName() == ConstString("_dyld_start")) +// process_did_exec = true; +// } +// } +// } + } + } return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code); + } break; case 6: // EXC_BREAKPOINT diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 475e6d2bddf..7bc03005b70 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1058,6 +1058,17 @@ ProcessGDBRemote::DidAttach () DidLaunchOrAttach (); } +void +ProcessGDBRemote::DoDidExec () +{ + // The process exec'ed itself, figure out the dynamic loader, etc... + BuildDynamicRegisterInfo (true); + m_gdb_comm.ResetDiscoverableSettings(); + DidLaunchOrAttach (); +} + + + Error ProcessGDBRemote::WillResume () { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 4cf2a4f94fb..d19878f4837 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -113,6 +113,9 @@ public: virtual void DidAttach (); + virtual void + DoDidExec (); + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ |