diff options
Diffstat (limited to 'source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp')
| -rw-r--r-- | source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 224 | 
1 files changed, 123 insertions, 101 deletions
| diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index c0ea9cceea2e4..c90706a88b84d 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -55,79 +55,79 @@ using namespace lldb_private::process_gdb_remote;  //----------------------------------------------------------------------  // GDBRemoteCommunicationClient constructor  //---------------------------------------------------------------------- -GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : -    GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"), -    m_supports_not_sending_acks (eLazyBoolCalculate), -    m_supports_thread_suffix (eLazyBoolCalculate), -    m_supports_threads_in_stop_reply (eLazyBoolCalculate), -    m_supports_vCont_all (eLazyBoolCalculate), -    m_supports_vCont_any (eLazyBoolCalculate), -    m_supports_vCont_c (eLazyBoolCalculate), -    m_supports_vCont_C (eLazyBoolCalculate), -    m_supports_vCont_s (eLazyBoolCalculate), -    m_supports_vCont_S (eLazyBoolCalculate), -    m_qHostInfo_is_valid (eLazyBoolCalculate), -    m_curr_pid_is_valid (eLazyBoolCalculate), -    m_qProcessInfo_is_valid (eLazyBoolCalculate), -    m_qGDBServerVersion_is_valid (eLazyBoolCalculate), -    m_supports_alloc_dealloc_memory (eLazyBoolCalculate), -    m_supports_memory_region_info  (eLazyBoolCalculate), -    m_supports_watchpoint_support_info  (eLazyBoolCalculate), -    m_supports_detach_stay_stopped (eLazyBoolCalculate), -    m_watchpoints_trigger_after_instruction(eLazyBoolCalculate), -    m_attach_or_wait_reply(eLazyBoolCalculate), -    m_prepare_for_reg_writing_reply (eLazyBoolCalculate), -    m_supports_p (eLazyBoolCalculate), -    m_supports_x (eLazyBoolCalculate), -    m_avoid_g_packets (eLazyBoolCalculate), -    m_supports_QSaveRegisterState (eLazyBoolCalculate), -    m_supports_qXfer_auxv_read (eLazyBoolCalculate), -    m_supports_qXfer_libraries_read (eLazyBoolCalculate), -    m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate), -    m_supports_qXfer_features_read (eLazyBoolCalculate), -    m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), -    m_supports_jThreadExtendedInfo (eLazyBoolCalculate), -    m_supports_jLoadedDynamicLibrariesInfos (eLazyBoolCalculate), -    m_supports_qProcessInfoPID (true), -    m_supports_qfProcessInfo (true), -    m_supports_qUserName (true), -    m_supports_qGroupName (true), -    m_supports_qThreadStopInfo (true), -    m_supports_z0 (true), -    m_supports_z1 (true), -    m_supports_z2 (true), -    m_supports_z3 (true), -    m_supports_z4 (true), -    m_supports_QEnvironment (true), -    m_supports_QEnvironmentHexEncoded (true), -    m_supports_qSymbol (true), -    m_qSymbol_requests_done (false), -    m_supports_qModuleInfo (true), -    m_supports_jThreadsInfo (true), -    m_curr_pid (LLDB_INVALID_PROCESS_ID), -    m_curr_tid (LLDB_INVALID_THREAD_ID), -    m_curr_tid_run (LLDB_INVALID_THREAD_ID), -    m_num_supported_hardware_watchpoints (0), -    m_async_mutex (Mutex::eMutexTypeRecursive), -    m_async_packet_predicate (false), -    m_async_packet (), -    m_async_result (PacketResult::Success), -    m_async_response (), -    m_async_signal (-1), -    m_interrupt_sent (false), -    m_thread_id_to_used_usec_map (), -    m_host_arch(), -    m_process_arch(), -    m_os_version_major (UINT32_MAX), -    m_os_version_minor (UINT32_MAX), -    m_os_version_update (UINT32_MAX), -    m_os_build (), -    m_os_kernel (), -    m_hostname (), -    m_gdb_server_name(), -    m_gdb_server_version(UINT32_MAX), -    m_default_packet_timeout (0), -    m_max_packet_size (0) +GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() +    : GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"), +      m_supports_not_sending_acks(eLazyBoolCalculate), +      m_supports_thread_suffix(eLazyBoolCalculate), +      m_supports_threads_in_stop_reply(eLazyBoolCalculate), +      m_supports_vCont_all(eLazyBoolCalculate), +      m_supports_vCont_any(eLazyBoolCalculate), +      m_supports_vCont_c(eLazyBoolCalculate), +      m_supports_vCont_C(eLazyBoolCalculate), +      m_supports_vCont_s(eLazyBoolCalculate), +      m_supports_vCont_S(eLazyBoolCalculate), +      m_qHostInfo_is_valid(eLazyBoolCalculate), +      m_curr_pid_is_valid(eLazyBoolCalculate), +      m_qProcessInfo_is_valid(eLazyBoolCalculate), +      m_qGDBServerVersion_is_valid(eLazyBoolCalculate), +      m_supports_alloc_dealloc_memory(eLazyBoolCalculate), +      m_supports_memory_region_info(eLazyBoolCalculate), +      m_supports_watchpoint_support_info(eLazyBoolCalculate), +      m_supports_detach_stay_stopped(eLazyBoolCalculate), +      m_watchpoints_trigger_after_instruction(eLazyBoolCalculate), +      m_attach_or_wait_reply(eLazyBoolCalculate), +      m_prepare_for_reg_writing_reply(eLazyBoolCalculate), +      m_supports_p(eLazyBoolCalculate), +      m_supports_x(eLazyBoolCalculate), +      m_avoid_g_packets(eLazyBoolCalculate), +      m_supports_QSaveRegisterState(eLazyBoolCalculate), +      m_supports_qXfer_auxv_read(eLazyBoolCalculate), +      m_supports_qXfer_libraries_read(eLazyBoolCalculate), +      m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate), +      m_supports_qXfer_features_read(eLazyBoolCalculate), +      m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate), +      m_supports_jThreadExtendedInfo(eLazyBoolCalculate), +      m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate), +      m_supports_qProcessInfoPID(true), +      m_supports_qfProcessInfo(true), +      m_supports_qUserName(true), +      m_supports_qGroupName(true), +      m_supports_qThreadStopInfo(true), +      m_supports_z0(true), +      m_supports_z1(true), +      m_supports_z2(true), +      m_supports_z3(true), +      m_supports_z4(true), +      m_supports_QEnvironment(true), +      m_supports_QEnvironmentHexEncoded(true), +      m_supports_qSymbol(true), +      m_qSymbol_requests_done(false), +      m_supports_qModuleInfo(true), +      m_supports_jThreadsInfo(true), +      m_curr_pid(LLDB_INVALID_PROCESS_ID), +      m_curr_tid(LLDB_INVALID_THREAD_ID), +      m_curr_tid_run(LLDB_INVALID_THREAD_ID), +      m_num_supported_hardware_watchpoints(0), +      m_async_mutex(), +      m_async_packet_predicate(false), +      m_async_packet(), +      m_async_result(PacketResult::Success), +      m_async_response(), +      m_async_signal(-1), +      m_interrupt_sent(false), +      m_thread_id_to_used_usec_map(), +      m_host_arch(), +      m_process_arch(), +      m_os_version_major(UINT32_MAX), +      m_os_version_minor(UINT32_MAX), +      m_os_version_update(UINT32_MAX), +      m_os_build(), +      m_os_kernel(), +      m_hostname(), +      m_gdb_server_name(), +      m_gdb_server_version(UINT32_MAX), +      m_default_packet_timeout(0), +      m_max_packet_size(0)  {  } @@ -623,6 +623,7 @@ GDBRemoteCommunicationClient::GetThreadsInfo()      if (m_supports_jThreadsInfo)      {          StringExtractorGDBRemote response; +        response.SetResponseValidatorToJSON();          if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)          {              if (response.IsUnsupportedResponse()) @@ -765,9 +766,29 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *pa                                                                    size_t payload_length,                                                                    StringExtractorGDBRemote &response)  { -    PacketResult packet_result = SendPacketNoLock (payload, payload_length); +    PacketResult packet_result = SendPacketNoLock(payload, payload_length);      if (packet_result == PacketResult::Success) -        packet_result = ReadPacket (response, GetPacketTimeoutInMicroSeconds (), true); +    { +        const size_t max_response_retries = 3; +        for (size_t i=0; i<max_response_retries; ++i) +        { +            packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds (), true); +            // Make sure we received a response +            if (packet_result != PacketResult::Success) +                return packet_result; +            // Make sure our response is valid for the payload that was sent +            if (response.ValidateResponse()) +                return packet_result; +            // Response says it wasn't valid +            Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS); +            if (log) +                log->Printf("error: packet with payload \"%*s\" got invalid response \"%s\": %s", +                            (int)payload_length, +                            payload, +                            response.GetStringRef().c_str(), +                            (i == (max_response_retries - 1)) ? "using invalid response and giving up" : "ignoring response and waiting for another"); +        } +    }      return packet_result;  } @@ -786,8 +807,8 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse      // In order to stop async notifications from being processed in the middle of the      // send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done. -    static Listener hijack_listener("lldb.NotifyHijacker"); -    HijackBroadcaster(&hijack_listener, eBroadcastBitGdbReadThreadGotNotify);     +    static ListenerSP hijack_listener_sp(Listener::MakeListener("lldb.NotifyHijacker")); +    HijackBroadcaster(hijack_listener_sp, eBroadcastBitGdbReadThreadGotNotify);      if (GetSequenceMutex (locker))      { @@ -799,8 +820,9 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse          {              if (IsRunning())              { -                Mutex::Locker async_locker (m_async_mutex); +                std::lock_guard<std::recursive_mutex> guard(m_async_mutex);                  m_async_packet.assign(payload, payload_length); +                m_async_response.CopyResponseValidator(response);                  m_async_packet_predicate.SetValue (true, eBroadcastNever);                  if (log)  @@ -867,6 +889,9 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse                      if (log)                           log->Printf ("async: failed to interrupt");                  } + +                m_async_response.SetResponseValidator(nullptr, nullptr); +              }              else              { @@ -886,7 +911,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse      // If a notification event occurred, rebroadcast since it can now be processed safely.      EventSP event_sp; -    if (hijack_listener.GetNextEvent(event_sp)) +    if (hijack_listener_sp->GetNextEvent(event_sp))          BroadcastEvent(event_sp);      return packet_result; @@ -1136,13 +1161,17 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse                              // which will just re-send a copy of the last stop reply                              // packet. If we don't do this, then the reply for our                              // async packet will be the repeat stop reply packet and cause -                            // a lot of trouble for us! -                            if (signo != sigint_signo && signo != sigstop_signo) +                            // a lot of trouble for us! We also have some debugserver +                            // binaries that would send two stop replies anytime the process +                            // was interrupted, so we need to also check for an extra +                            // stop reply packet if we interrupted the process +                            const bool received_nonstop_signal = signo != sigint_signo && signo != sigstop_signo; +                            if (m_interrupt_sent || received_nonstop_signal)                              { -                                continue_after_async = false; +                                if (received_nonstop_signal) +                                    continue_after_async = false; -                                // We didn't get a SIGINT or SIGSTOP, so try for a -                                // very brief time (0.1s) to get another stop reply +                                // Try for a very brief time (0.1s) to get another stop reply                                  // packet to make sure it doesn't get in the way                                  StringExtractorGDBRemote extra_stop_reply_packet;                                  uint32_t timeout_usec = 100000; @@ -1343,7 +1372,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse  bool  GDBRemoteCommunicationClient::SendAsyncSignal (int signo)  { -    Mutex::Locker async_locker (m_async_mutex); +    std::lock_guard<std::recursive_mutex> guard(m_async_mutex);      m_async_signal = signo;      bool timed_out = false;      Mutex::Locker locker; @@ -2064,7 +2093,8 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)                          if (pointer_byte_size != 0)                              ++num_keys_decoded;                      } -                    else if (name.compare("os_version") == 0) +                    else if ((name.compare("os_version") == 0) || +                             (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...                      {                          Args::StringToVersion (value.c_str(),                                                  m_os_version_major, @@ -2114,20 +2144,6 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)                                  assert (byte_order == m_host_arch.GetByteOrder());                              } -                            if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0) -                            { -                                switch (m_host_arch.GetMachine()) -                                { -                                case llvm::Triple::aarch64: -                                case llvm::Triple::arm: -                                case llvm::Triple::thumb: -                                    os_name = "ios"; -                                    break; -                                default: -                                    os_name = "macosx"; -                                    break; -                                } -                            }                              if (!vendor_name.empty())                                  m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));                              if (!os_name.empty()) @@ -2411,6 +2427,8 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,                              region_info.SetExecutable (MemoryRegionInfo::eYes);                          else                              region_info.SetExecutable (MemoryRegionInfo::eNo); + +                        region_info.SetMapped(MemoryRegionInfo::eYes);                      }                      else                      { @@ -2418,6 +2436,7 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,                          region_info.SetReadable (MemoryRegionInfo::eNo);                          region_info.SetWritable (MemoryRegionInfo::eNo);                          region_info.SetExecutable (MemoryRegionInfo::eNo); +                        region_info.SetMapped(MemoryRegionInfo::eNo);                      }                  }                  else if (name.compare ("error") == 0) @@ -2437,6 +2456,7 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,                  region_info.SetReadable (MemoryRegionInfo::eNo);                  region_info.SetWritable (MemoryRegionInfo::eNo);                  region_info.SetExecutable (MemoryRegionInfo::eNo); +                region_info.SetMapped(MemoryRegionInfo::eNo);              }          }          else @@ -3571,6 +3591,8 @@ GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type,      // Check we haven't overwritten the end of the packet buffer      assert (packet_len + 1 < (int)sizeof(packet));      StringExtractorGDBRemote response; +    // Make sure the response is either "OK", "EXX" where XX are two hex digits, or "" (unsupported) +    response.SetResponseValidatorToOKErrorNotSupported();      // Try to send the breakpoint packet, and check that it was correctly sent      if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)      { @@ -4417,7 +4439,7 @@ GDBRemoteCommunicationClient::ReadExtFeature (const lldb_private::ConstString ob              // last chunk          case ( 'l' ):              active = false; -            // fall through intentional +            LLVM_FALLTHROUGH;              // more chunks          case ( 'm' ) : | 
