diff options
Diffstat (limited to 'lldb/source')
7 files changed, 171 insertions, 97 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index bc268b8e905..227a981b809 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -59,8 +59,10 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) : m_dyld(), m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS), m_dyld_all_image_infos(), + m_dyld_all_image_infos_stop_id (UINT32_MAX), m_break_id(LLDB_INVALID_BREAK_ID), m_dyld_image_infos(), + m_dyld_image_infos_stop_id (UINT32_MAX), m_mutex(Mutex::eMutexTypeRecursive) { } @@ -83,10 +85,8 @@ void DynamicLoaderMacOSXDYLD::DidAttach () { PrivateInitialize(m_process); - if (NeedToLocateDYLD ()) - LocateDYLD (); + LocateDYLD (); SetNotificationBreakpoint (); - UpdateAllImageInfos(); } //------------------------------------------------------------------ @@ -99,10 +99,8 @@ void DynamicLoaderMacOSXDYLD::DidLaunch () { PrivateInitialize(m_process); - if (NeedToLocateDYLD ()) - LocateDYLD (); + LocateDYLD (); SetNotificationBreakpoint (); - UpdateAllImageInfos(); } @@ -401,12 +399,23 @@ bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () { Mutex::Locker locker(m_mutex); + + // the all image infos is already valid for this process stop ID + if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id) + return true; + m_dyld_all_image_infos.Clear(); if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) { - const ByteOrder endian = m_process->GetByteOrder(); - const uint32_t addr_size = m_process->GetAddressByteSize(); + ByteOrder byte_order = m_process->GetByteOrder(); + uint32_t addr_size = 4; + if (m_dyld_all_image_infos_addr > UINT32_MAX) + addr_size = 8; + uint8_t buf[256]; + DataExtractor data (buf, sizeof(buf), byte_order, addr_size); + uint32_t offset = 0; + const size_t count_v2 = sizeof (uint32_t) + // version sizeof (uint32_t) + // infoArrayCount addr_size + // infoArray @@ -434,9 +443,23 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () Error error; if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4) { - DataExtractor data(buf, 4, endian, addr_size); - uint32_t offset = 0; m_dyld_all_image_infos.version = data.GetU32(&offset); + // If anything in the high byte is set, we probably got the byte + // order incorrect (the process might not have it set correctly + // yet due to attaching to a program without a specified file). + if (m_dyld_all_image_infos.version & 0xff000000) + { + // We have guessed the wrong byte order. Swap it and try + // reading the version again. + if (byte_order == eByteOrderLittle) + byte_order = eByteOrderBig; + else + byte_order = eByteOrderLittle; + + data.SetByteOrder (byte_order); + offset = 0; + m_dyld_all_image_infos.version = data.GetU32(&offset); + } } else { @@ -451,8 +474,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error); if (bytes_read == count) { - DataExtractor data(buf, count, endian, addr_size); - uint32_t offset = 0; + offset = 0; m_dyld_all_image_infos.version = data.GetU32(&offset); m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset); @@ -486,6 +508,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset; } } + m_dyld_all_image_infos_stop_id = m_process->GetStopID(); return true; } } @@ -504,6 +527,9 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() if (ReadAllImageInfosStructure ()) { Mutex::Locker locker(m_mutex); + if (m_process->GetStopID() == m_dyld_image_infos_stop_id) + m_dyld_image_infos.size(); + uint32_t idx; uint32_t i = 0; DYLDImageInfo::collection old_dyld_all_image_infos; @@ -511,8 +537,8 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() // If we made it here, we are assuming that the all dylib info data should // be valid, lets read the info array. - const ByteOrder endian = m_process->GetByteOrder(); - const uint32_t addr_size = m_process->GetAddressByteSize(); + const ByteOrder endian = m_dyld.GetByteOrder(); + const uint32_t addr_size = m_dyld.GetAddressByteSize(); if (m_dyld_all_image_infos.dylib_info_count > 0) { @@ -605,6 +631,7 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() if (log) PutToLog(log.get()); } + m_dyld_image_infos_stop_id = m_process->GetStopID(); } else { diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h index 34ea8a46781..d8dbe711b3d 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -266,6 +266,41 @@ protected: return uuid.IsValid(); } + uint32_t + GetAddressByteSize () + { + if (header.cputype) + { + if (header.cputype & llvm::MachO::CPUArchABI64) + return 8; + else + return 4; + } + return 0; + } + + lldb::ByteOrder + GetByteOrder() + { + switch (header.magic) + { + case llvm::MachO::HeaderMagic32: // MH_MAGIC + case llvm::MachO::HeaderMagic64: // MH_MAGIC_64 + return lldb::eByteOrderHost; + + case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM + case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64 + if (lldb::eByteOrderHost == lldb::eByteOrderLittle) + return lldb::eByteOrderBig; + else + return lldb::eByteOrderLittle; + default: + assert (!"invalid header.magic value"); + break; + } + return lldb::eByteOrderHost; + } + const Segment * FindSegment (const lldb_private::ConstString &name) const; @@ -348,8 +383,10 @@ protected: DYLDImageInfo m_dyld; // Info about the curent dyld being used lldb::addr_t m_dyld_all_image_infos_addr; DYLDAllImageInfos m_dyld_all_image_infos; + uint32_t m_dyld_all_image_infos_stop_id; lldb::user_id_t m_break_id; DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information + 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; diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp index 259c08072a1..b3933169841 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp @@ -235,9 +235,7 @@ ProcessMacOSX::ProcessMacOSX(Target& target, Listener &listener) : m_exception_messages (), m_exception_messages_mutex (Mutex::eMutexTypeRecursive), m_arch_spec (), - m_dynamic_loader_ap (), -// m_wait_thread (LLDB_INVALID_HOST_THREAD), - m_byte_order (eByteOrderHost) + m_dynamic_loader_ap () { } @@ -676,6 +674,7 @@ ProcessMacOSX::RefreshStateAfterStop () Error ProcessMacOSX::DoHalt (bool &caused_stop) { + caused_stop = true; return Signal (SIGSTOP); } diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h index 92d2c9c1653..4f8bdb930b7 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h @@ -247,8 +247,6 @@ protected: lldb_private::Mutex m_exception_messages_mutex; // Multithreaded protection for m_exception_messages lldb_private::ArchSpec m_arch_spec; std::auto_ptr<lldb_private::DynamicLoader> m_dynamic_loader_ap; -// lldb::thread_t m_wait_thread; - lldb::ByteOrder m_byte_order; //---------------------------------------------------------------------- // Child process control diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index fcbd523699f..5496a02343a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -105,7 +105,6 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_dynamic_loader_ap (), m_flags (0), m_stdio_mutex (Mutex::eMutexTypeRecursive), - m_byte_order (eByteOrderHost), m_gdb_comm(), m_debugserver_pid (LLDB_INVALID_PROCESS_ID), m_debugserver_thread (LLDB_INVALID_HOST_THREAD), @@ -339,13 +338,13 @@ ProcessGDBRemote::WillLaunch (Module* module) } Error -ProcessGDBRemote::WillAttach (lldb::pid_t pid) +ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid) { return WillLaunchOrAttach (); } Error -ProcessGDBRemote::WillAttach (const char *process_name, bool wait_for_launch) +ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) { return WillLaunchOrAttach (); } @@ -556,8 +555,6 @@ ProcessGDBRemote::ConnectToDebugserver (const char *host_port) if (response.IsOKPacket()) m_gdb_comm.SetAckMode (false); } - - BuildDynamicRegisterInfo (); } return error; } @@ -574,22 +571,23 @@ ProcessGDBRemote::DidLaunchOrAttach () { m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS; - Module * exe_module = GetTarget().GetExecutableModule ().get(); + BuildDynamicRegisterInfo (); + + m_byte_order = m_gdb_comm.GetByteOrder(); + + Module * exe_module = GetTarget().GetExecutableModule().get(); assert(exe_module); ObjectFile *exe_objfile = exe_module->GetObjectFile(); assert(exe_objfile); - m_byte_order = exe_objfile->GetByteOrder(); - assert (m_byte_order != eByteOrderInvalid); - StreamString strm; ArchSpec inferior_arch; // See if the GDB server supports the qHostInfo information const char *vendor = m_gdb_comm.GetVendorString().AsCString(); const char *os_type = m_gdb_comm.GetOSString().AsCString(); - ArchSpec arch_spec = GetTarget().GetArchitecture(); + ArchSpec arch_spec (GetTarget().GetArchitecture()); if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm")) { @@ -858,25 +856,8 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait void ProcessGDBRemote::DidAttach () { - // If we haven't got an executable module yet, then we should make a dynamic loader, and - // see if it can find the executable module for us. If we do have an executable module, - // make sure it matches the process we've just attached to. - - ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); - if (!m_dynamic_loader_ap.get()) - { - m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.macosx-dyld")); - } - if (m_dynamic_loader_ap.get()) m_dynamic_loader_ap->DidAttach(); - - Module * new_exe_module = GetTarget().GetExecutableModule().get(); - if (new_exe_module == NULL) - { - - } - DidLaunchOrAttach (); } @@ -1124,45 +1105,26 @@ Error ProcessGDBRemote::DoHalt (bool &caused_stop) { Error error; - caused_stop = false; if (m_gdb_comm.IsRunning()) { - PausePrivateStateThread(); + caused_stop = true; bool timed_out = false; Mutex::Locker locker; - if (m_gdb_comm.SendInterrupt (locker, 2, &timed_out)) - { - EventSP event_sp; - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(2); - - StateType state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp); - - if (!StateIsStoppedState (state)) - { - LogSP log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf("ProcessGDBRemote::DoHalt() failed to stop after sending interrupt"); - error.SetErrorString ("Did not get stopped event after interrupt succeeded."); - } - else - caused_stop = true; - } - else + if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out)) { if (timed_out) error.SetErrorString("timed out sending interrupt packet"); else error.SetErrorString("unknown error sending interrupt packet"); } - - // Resume the private state thread at this point. - ResumePrivateStateThread(); - } + else + { + caused_stop = false; + } + return error; } @@ -1265,12 +1227,6 @@ ProcessGDBRemote::DoDestroy () return error; } -ByteOrder -ProcessGDBRemote::GetByteOrder () const -{ - return m_byte_order; -} - //------------------------------------------------------------------ // Process Queries //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 1e85e9918a7..546f1054536 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -90,10 +90,10 @@ public: DidLaunch (); virtual lldb_private::Error - WillAttach (lldb::pid_t pid); + WillAttachToProcessWithID (lldb::pid_t pid); virtual lldb_private::Error - WillAttach (const char *process_name, bool wait_for_launch); + WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); lldb_private::Error WillLaunchOrAttach (); @@ -215,9 +215,6 @@ public: virtual lldb_private::Error DisableWatchpoint (lldb_private::WatchpointLocation *wp_loc); - virtual lldb::ByteOrder - GetByteOrder () const; - virtual lldb_private::DynamicLoader * GetDynamicLoader (); @@ -322,7 +319,6 @@ protected: std::auto_ptr<lldb_private::DynamicLoader> m_dynamic_loader_ap; lldb_private::Flags m_flags; // Process specific flags (see eFlags enums) lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio - lldb::ByteOrder m_byte_order; GDBRemoteCommunication m_gdb_comm; lldb::pid_t m_debugserver_pid; lldb::thread_t m_debugserver_thread; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 749ae3ceb88..a86a4e10187 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -85,12 +85,19 @@ Process::Process(Target &target, Listener &listener) : m_exit_string (), m_thread_list (this), m_notifications (), - m_persistent_vars(), - m_listener(listener), + m_image_tokens (), + m_listener (listener), + m_breakpoint_site_list (), + m_persistent_vars (), + m_dynamic_checkers_ap (), m_unix_signals (), + m_target_triple (), + m_byte_order (eByteOrderHost), + m_addr_byte_size (0), + m_abi_sp (), m_process_input_reader (), m_stdio_communication ("lldb.process.stdio"), - m_stdio_comm_mutex (Mutex::eMutexTypeRecursive), + m_stdio_communication_mutex (Mutex::eMutexTypeRecursive), m_stdout_data () { UpdateInstanceName(); @@ -1438,19 +1445,71 @@ Process::Halt () if (error.Success()) { - bool caused_stop; + + bool caused_stop = false; + EventSP event_sp; + + // Pause our private state thread so we can ensure no one else eats + // the stop event out from under us. + PausePrivateStateThread(); + + // Ask the process subclass to actually halt our process error = DoHalt(caused_stop); if (error.Success()) { - DidHalt(); + // If "caused_stop" is true, then DoHalt stopped the process. If + // "caused_stop" is false, the process was already stopped. + // If the DoHalt caused the process to stop, then we want to catch + // this event and set the interrupted bool to true before we pass + // this along so clients know that the process was interrupted by + // a halt command. if (caused_stop) { - ProcessEventData *new_data = new ProcessEventData (GetTarget().GetProcessSP(), eStateStopped); - new_data->SetInterrupted(true); - BroadcastEvent (eBroadcastBitStateChanged, new_data); + // Wait for 2 seconds for the process to stop. + TimeValue timeout_time; + timeout_time = TimeValue::Now(); + timeout_time.OffsetWithSeconds(2); + StateType state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp); + + if (state == eStateInvalid) + { + // We timeout out and didn't get a stop event... + error.SetErrorString ("Halt timed out."); + } + else + { + // Since we are eating the event, we need to update our state + // otherwise the process state will not match reality... + SetPublicState(state); + + if (StateIsStoppedState (state)) + { + // We caused the process to interrupt itself, so mark this + // as such in the stop event so clients can tell an interrupted + // process from a natural stop + ProcessEventData::SetInterruptedInEvent (event_sp.get(), true); + } + else + { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + if (log) + log->Printf("Process::Halt() failed to stop, state is: %s", StateAsCString(state)); + error.SetErrorString ("Did not get stopped event after halt."); + } + } } + DidHalt(); + } - + // Resume our private state thread before we post the event (if any) + ResumePrivateStateThread(); + + // Post any event we might have consumed. If all goes well, we will have + // stopped the process, intercepted the event and set the interrupted + // bool in the event. + if (event_sp) + BroadcastEvent(event_sp); + } return error; } @@ -1530,7 +1589,9 @@ Process::GetTarget () const uint32_t Process::GetAddressByteSize() { - return m_target.GetArchitecture().GetAddressByteSize(); + if (m_addr_byte_size == 0) + return m_target.GetArchitecture().GetAddressByteSize(); + return m_addr_byte_size; } bool @@ -1603,8 +1664,8 @@ Process::ShouldBroadcastEvent (Event *event_ptr) // If no thread has an opinion, we don't report it. if (ProcessEventData::GetInterruptedFromEvent (event_ptr)) { - if (log) - log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state)); + if (log) + log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state)); return true; } else @@ -2074,7 +2135,7 @@ Process::GetArchSpecForExistingProcess (const char *process_name) void Process::AppendSTDOUT (const char * s, size_t len) { - Mutex::Locker locker (m_stdio_comm_mutex); + Mutex::Locker locker (m_stdio_communication_mutex); m_stdout_data.append (s, len); BroadcastEventIfUnique (eBroadcastBitSTDOUT); |