diff options
Diffstat (limited to 'source/Plugins/Process/gdb-remote')
3 files changed, 78 insertions, 23 deletions
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 2a253c5..b8c67c5 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1459,6 +1459,21 @@ GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy) } } } + + // If we don't get a response for $qC, check if $qfThreadID gives us a result. + if (m_curr_pid == LLDB_INVALID_PROCESS_ID) + { + std::vector<lldb::tid_t> thread_ids; + bool sequence_mutex_unavailable; + size_t size; + size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable); + if (size && sequence_mutex_unavailable == false) + { + m_curr_pid = thread_ids.front(); + m_curr_pid_is_valid = eLazyBoolYes; + return m_curr_pid; + } + } } return LLDB_INVALID_PROCESS_ID; @@ -2472,26 +2487,45 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num) } lldb_private::Error -GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after) +GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch) { Error error(GetWatchpointSupportInfo(num)); if (error.Success()) - error = GetWatchpointsTriggerAfterInstruction(after); + error = GetWatchpointsTriggerAfterInstruction(after, arch); return error; } lldb_private::Error -GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after) +GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch) { Error error; + llvm::Triple::ArchType atype = arch.GetMachine(); // we assume watchpoints will happen after running the relevant opcode // and we only want to override this behavior if we have explicitly // received a qHostInfo telling us otherwise if (m_qHostInfo_is_valid != eLazyBoolYes) - after = true; + { + // On targets like MIPS, watchpoint exceptions are always generated + // before the instruction is executed. The connected target may not + // support qHostInfo or qWatchpointSupportInfo packets. + if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel + || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el) + after = false; + else + after = true; + } else + { + // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo + // if it is not calculated before. + if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && + (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel + || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) + m_watchpoints_trigger_after_instruction = eLazyBoolNo; + after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); + } return error; } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index deb41b0..b08ff06 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -287,10 +287,10 @@ public: GetWatchpointSupportInfo (uint32_t &num); Error - GetWatchpointSupportInfo (uint32_t &num, bool& after); + GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch); Error - GetWatchpointsTriggerAfterInstruction (bool &after); + GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch); const ArchSpec & GetHostArchitecture (); diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 0bcc8ca..1e150b1 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -371,7 +371,7 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_flags (0), m_gdb_comm (), m_debugserver_pid (LLDB_INVALID_PROCESS_ID), - m_last_stop_packet_mutex (Mutex::eMutexTypeNormal), + m_last_stop_packet_mutex (Mutex::eMutexTypeRecursive), m_register_info (), m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"), m_async_thread_state_mutex(Mutex::eMutexTypeRecursive), @@ -822,7 +822,13 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url) log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ()); if (error.Success()) - SetUnixSignals(std::make_shared<GDBRemoteSignals>(GetTarget().GetPlatform()->GetUnixSignals())); + { + PlatformSP platform_sp = GetTarget().GetPlatform(); + if (platform_sp && platform_sp->IsConnected()) + SetUnixSignals(platform_sp->GetUnixSignals()); + else + SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture())); + } return error; } @@ -1984,6 +1990,7 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid, StringExtractor desc_extractor(description.c_str()); addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS); uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32); + addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS); watch_id_t watch_id = LLDB_INVALID_WATCH_ID; if (wp_addr != LLDB_INVALID_ADDRESS) { @@ -1999,7 +2006,7 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid, Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS)); if (log) log->Printf ("failed to find watchpoint"); } - thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id)); + thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id, wp_hit_addr)); handled = true; } else if (reason.compare("exception") == 0) @@ -2433,6 +2440,21 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) } } } + else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 || key.compare("awatch") == 0) + { + // Support standard GDB remote stop reply packet 'TAAwatch:addr' + lldb::addr_t wp_addr = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16); + WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr); + uint32_t wp_index = LLDB_INVALID_INDEX32; + + if (wp_sp) + wp_index = wp_sp->GetHardwareIndex(); + + reason = "watchpoint"; + StreamString ostr; + ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index); + description = ostr.GetString().c_str(); + } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = StringConvert::ToUInt32 (key.c_str(), UINT32_MAX, 16); @@ -2441,6 +2463,18 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) } } + if (tid == LLDB_INVALID_THREAD_ID) + { + // A thread id may be invalid if the response is old style 'S' packet which does not provide the + // thread information. So update the thread list and choose the first one. + UpdateThreadIDList (); + + if (!m_thread_ids.empty ()) + { + tid = m_thread_ids.front (); + } + } + ThreadSP thread_sp = SetThreadStopInfo (tid, expedited_register_map, signo, @@ -2455,19 +2489,6 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) queue_kind, queue_serial); - // If the response is old style 'S' packet which does not provide us with thread information - // then update the thread list and choose the first one. - if (!thread_sp) - { - UpdateThreadIDList (); - - if (!m_thread_ids.empty ()) - { - Mutex::Locker locker (m_thread_list_real.GetMutex ()); - thread_sp = m_thread_list_real.FindThreadByProtocolID (m_thread_ids.front (), false); - } - } - return eStateStopped; } break; @@ -3006,7 +3027,7 @@ ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num) Error ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num, bool& after) { - Error error (m_gdb_comm.GetWatchpointSupportInfo (num, after)); + Error error (m_gdb_comm.GetWatchpointSupportInfo (num, after, GetTarget().GetArchitecture())); return error; } |