diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
| commit | 14f1b3e8826ce43b978db93a62d1166055db5394 (patch) | |
| tree | 0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp | |
| parent | 4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp')
| -rw-r--r-- | source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp | 5426 | 
1 files changed, 2801 insertions, 2625 deletions
| diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index c468ba33e858..bf72673f1769 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -16,13 +16,11 @@  // C Includes  // C++ Includes -#include <cstring>  #include <chrono> +#include <cstring>  #include <thread>  // Other libraries and framework includes -#include "llvm/ADT/Triple.h" -#include "lldb/Interpreter/Args.h"  #include "lldb/Core/DataBuffer.h"  #include "lldb/Core/Log.h"  #include "lldb/Core/RegisterValue.h" @@ -36,20 +34,22 @@  #include "lldb/Host/Host.h"  #include "lldb/Host/HostInfo.h"  #include "lldb/Host/StringConvert.h" -#include "lldb/Host/TimeValue.h" -#include "lldb/Target/FileAction.h" -#include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Host/common/NativeRegisterContext.h"  #include "lldb/Host/common/NativeProcessProtocol.h" +#include "lldb/Host/common/NativeRegisterContext.h"  #include "lldb/Host/common/NativeThreadProtocol.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Target/FileAction.h" +#include "lldb/Target/MemoryRegionInfo.h"  #include "lldb/Utility/JSON.h"  #include "lldb/Utility/LLDBAssert.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/ScopedPrinter.h"  // Project includes -#include "Utility/StringExtractorGDBRemote.h" -#include "Utility/UriParser.h"  #include "ProcessGDBRemote.h"  #include "ProcessGDBRemoteLog.h" +#include "Utility/StringExtractorGDBRemote.h" +#include "Utility/UriParser.h"  using namespace lldb;  using namespace lldb_private; @@ -60,2934 +60,3110 @@ using namespace llvm;  // GDBRemote Errors  //---------------------------------------------------------------------- -namespace -{ -    enum GDBRemoteServerError -    { -        // Set to the first unused error number in literal form below -        eErrorFirst = 29, -        eErrorNoProcess = eErrorFirst, -        eErrorResume, -        eErrorExitStatus -    }; +namespace { +enum GDBRemoteServerError { +  // Set to the first unused error number in literal form below +  eErrorFirst = 29, +  eErrorNoProcess = eErrorFirst, +  eErrorResume, +  eErrorExitStatus +};  }  //----------------------------------------------------------------------  // GDBRemoteCommunicationServerLLGS constructor  //---------------------------------------------------------------------- -GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(MainLoop &mainloop) -    : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"), -      m_mainloop(mainloop), -      m_current_tid(LLDB_INVALID_THREAD_ID), -      m_continue_tid(LLDB_INVALID_THREAD_ID), -      m_debugged_process_mutex(), -      m_debugged_process_sp(), -      m_stdio_communication("process.stdio"), +GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( +    MainLoop &mainloop) +    : GDBRemoteCommunicationServerCommon("gdb-remote.server", +                                         "gdb-remote.server.rx_packet"), +      m_mainloop(mainloop), m_current_tid(LLDB_INVALID_THREAD_ID), +      m_continue_tid(LLDB_INVALID_THREAD_ID), m_debugged_process_mutex(), +      m_debugged_process_sp(), m_stdio_communication("process.stdio"),        m_inferior_prev_state(StateType::eStateInvalid), -      m_active_auxv_buffer_sp(), -      m_saved_registers_mutex(), -      m_saved_registers_map(), -      m_next_saved_registers_id(1), -      m_handshake_completed(false) -{ -    RegisterPacketHandlers(); -} - -void -GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() -{ -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C, -                                  &GDBRemoteCommunicationServerLLGS::Handle_C); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c, -                                  &GDBRemoteCommunicationServerLLGS::Handle_c); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D, -                                  &GDBRemoteCommunicationServerLLGS::Handle_D); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H, -                                  &GDBRemoteCommunicationServerLLGS::Handle_H); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I, -                                  &GDBRemoteCommunicationServerLLGS::Handle_I); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, -                                  &GDBRemoteCommunicationServerLLGS::Handle_interrupt); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_m, -                                  &GDBRemoteCommunicationServerLLGS::Handle_memory_read); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M, -                                  &GDBRemoteCommunicationServerLLGS::Handle_M); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p, -                                  &GDBRemoteCommunicationServerLLGS::Handle_p); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P, -                                  &GDBRemoteCommunicationServerLLGS::Handle_P); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qC); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfThreadInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qRegisterInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState, -                                  &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState, -                                  &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR, -                                  &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, -                                  &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsThreadInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jThreadsInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read, -                                  &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s, -                                  &GDBRemoteCommunicationServerLLGS::Handle_s); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_stop_reason, -                                  &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ? -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vAttach, -                                  &GDBRemoteCommunicationServerLLGS::Handle_vAttach); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont, -                                  &GDBRemoteCommunicationServerLLGS::Handle_vCont); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont_actions, -                                  &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_x, -                                  &GDBRemoteCommunicationServerLLGS::Handle_memory_read); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z, -                                  &GDBRemoteCommunicationServerLLGS::Handle_Z); -    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z, -                                  &GDBRemoteCommunicationServerLLGS::Handle_z); - -    RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k, -                          [this](StringExtractorGDBRemote packet, -                                 Error &error, -                                 bool &interrupt, -                                 bool &quit) -                          { -                              quit = true; -                              return this->Handle_k (packet); -                          }); -} - -Error -GDBRemoteCommunicationServerLLGS::SetLaunchArguments (const char *const args[], int argc) -{ -    if ((argc < 1) || !args || !args[0] || !args[0][0]) -        return Error ("%s: no process command line specified to launch", __FUNCTION__); - -    m_process_launch_info.SetArguments (const_cast<const char**> (args), true); -    return Error (); -} - -Error -GDBRemoteCommunicationServerLLGS::SetLaunchFlags (unsigned int launch_flags) -{ -    m_process_launch_info.GetFlags ().Set (launch_flags); -    return Error (); -} - -Error -GDBRemoteCommunicationServerLLGS::LaunchProcess () -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    if (!m_process_launch_info.GetArguments ().GetArgumentCount ()) -        return Error ("%s: no process command line specified to launch", __FUNCTION__); - -    Error error; -    { -        std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); -        assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists"); -        error = NativeProcessProtocol::Launch( -            m_process_launch_info, -            *this, -            m_mainloop, -            m_debugged_process_sp); -    } - -    if (!error.Success ()) -    { -        fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0)); -        return error; -    } - -    // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol -    // as needed. -    // llgs local-process debugging may specify PTY paths, which will make these -    // file actions non-null -    // process launch -i/e/o will also make these file actions non-null -    // nullptr means that the traffic is expected to flow over gdb-remote protocol -    if ( -        m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr  || -        m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr  || -        m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr -        ) -    { -        // nullptr means it's not redirected to file or pty (in case of LLGS local) -        // at least one of stdio will be transferred pty<->gdb-remote -        // we need to give the pty master handle to this object to read and/or write -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " setting up stdout/stderr redirection via $O gdb-remote commands", __FUNCTION__, m_debugged_process_sp->GetID ()); - -        // Setup stdout/stderr mapping from inferior to $O -        auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor (); -        if (terminal_fd >= 0) -        { -            if (log) -                log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd); -            error = SetSTDIOFileDescriptor (terminal_fd); -            if (error.Fail ()) -                return error; -        } -        else -        { -            if (log) -                log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd); -        } -    } -    else -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " skipping stdout/stderr redirection via $O: inferior will communicate over client-provided file descriptors", __FUNCTION__, m_debugged_process_sp->GetID ()); -    } - -    printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ()); - +      m_active_auxv_buffer_sp(), m_saved_registers_mutex(), +      m_saved_registers_map(), m_next_saved_registers_id(1), +      m_handshake_completed(false) { +  RegisterPacketHandlers(); +} + +void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C, +                                &GDBRemoteCommunicationServerLLGS::Handle_C); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c, +                                &GDBRemoteCommunicationServerLLGS::Handle_c); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D, +                                &GDBRemoteCommunicationServerLLGS::Handle_D); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H, +                                &GDBRemoteCommunicationServerLLGS::Handle_H); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I, +                                &GDBRemoteCommunicationServerLLGS::Handle_I); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_interrupt, +      &GDBRemoteCommunicationServerLLGS::Handle_interrupt); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_m, +      &GDBRemoteCommunicationServerLLGS::Handle_memory_read); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M, +                                &GDBRemoteCommunicationServerLLGS::Handle_M); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p, +                                &GDBRemoteCommunicationServerLLGS::Handle_p); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P, +                                &GDBRemoteCommunicationServerLLGS::Handle_P); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC, +                                &GDBRemoteCommunicationServerLLGS::Handle_qC); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qfThreadInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress, +      &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, +      &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported, +      &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qProcessInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qRegisterInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState, +      &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState, +      &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR, +      &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, +      &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qsThreadInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_jThreadsInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo, +      &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read, +      &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s, +                                &GDBRemoteCommunicationServerLLGS::Handle_s); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_stop_reason, +      &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ? +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_vAttach, +      &GDBRemoteCommunicationServerLLGS::Handle_vAttach); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_vCont, +      &GDBRemoteCommunicationServerLLGS::Handle_vCont); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_vCont_actions, +      &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions); +  RegisterMemberFunctionHandler( +      StringExtractorGDBRemote::eServerPacketType_x, +      &GDBRemoteCommunicationServerLLGS::Handle_memory_read); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z, +                                &GDBRemoteCommunicationServerLLGS::Handle_Z); +  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z, +                                &GDBRemoteCommunicationServerLLGS::Handle_z); + +  RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k, +                        [this](StringExtractorGDBRemote packet, Error &error, +                               bool &interrupt, bool &quit) { +                          quit = true; +                          return this->Handle_k(packet); +                        }); +} + +Error GDBRemoteCommunicationServerLLGS::SetLaunchArguments( +    const char *const args[], int argc) { +  if ((argc < 1) || !args || !args[0] || !args[0][0]) +    return Error("%s: no process command line specified to launch", +                 __FUNCTION__); + +  m_process_launch_info.SetArguments(const_cast<const char **>(args), true); +  return Error(); +} + +Error GDBRemoteCommunicationServerLLGS::SetLaunchFlags( +    unsigned int launch_flags) { +  m_process_launch_info.GetFlags().Set(launch_flags); +  return Error(); +} + +Error GDBRemoteCommunicationServerLLGS::LaunchProcess() { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + +  if (!m_process_launch_info.GetArguments().GetArgumentCount()) +    return Error("%s: no process command line specified to launch", +                 __FUNCTION__); + +  const bool should_forward_stdio = +      m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr || +      m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr || +      m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr; +  m_process_launch_info.SetLaunchInSeparateProcessGroup(true); +  m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); + +  const bool default_to_use_pty = true; +  m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty); + +  Error error; +  { +    std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); +    assert(!m_debugged_process_sp && "lldb-server creating debugged " +                                     "process but one already exists"); +    error = NativeProcessProtocol::Launch(m_process_launch_info, *this, +                                          m_mainloop, m_debugged_process_sp); +  } + +  if (!error.Success()) { +    fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__, +            m_process_launch_info.GetArguments().GetArgumentAtIndex(0));      return error; -} - -Error -GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid) -{ -    Error error; - -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS)); +  } + +  // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol +  // as needed. +  // llgs local-process debugging may specify PTY paths, which will make these +  // file actions non-null +  // process launch -i/e/o will also make these file actions non-null +  // nullptr means that the traffic is expected to flow over gdb-remote protocol +  if (should_forward_stdio) { +    // nullptr means it's not redirected to file or pty (in case of LLGS local) +    // at least one of stdio will be transferred pty<->gdb-remote +    // we need to give the pty master handle to this object to read and/or write      if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid); - -    // Before we try to attach, make sure we aren't already monitoring something else. -    if (m_debugged_process_sp  && m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID) -        return Error("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, m_debugged_process_sp->GetID()); - -    // Try to attach. -    error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp); -    if (!error.Success ()) -    { -        fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ()); +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +          " setting up stdout/stderr redirection via $O gdb-remote commands", +          __FUNCTION__, m_debugged_process_sp->GetID()); + +    // Setup stdout/stderr mapping from inferior to $O +    auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor(); +    if (terminal_fd >= 0) { +      if (log) +        log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting " +                    "inferior STDIO fd to %d", +                    __FUNCTION__, terminal_fd); +      error = SetSTDIOFileDescriptor(terminal_fd); +      if (error.Fail())          return error; +    } else { +      if (log) +        log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " +                    "inferior STDIO since terminal fd reported as %d", +                    __FUNCTION__, terminal_fd);      } - -    // Setup stdout/stderr mapping from inferior. -    auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor (); -    if (terminal_fd >= 0) -    { -        if (log) -            log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd); -        error = SetSTDIOFileDescriptor (terminal_fd); -        if (error.Fail ()) -            return error; -    } -    else -    { -        if (log) -            log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd); -    } - -    printf ("Attached to process %" PRIu64 "...\n", pid); - +  } else { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " skipping stdout/stderr redirection via $O: inferior will " +                  "communicate over client-provided file descriptors", +                  __FUNCTION__, m_debugged_process_sp->GetID()); +  } + +  printf("Launched '%s' as process %" PRIu64 "...\n", +         m_process_launch_info.GetArguments().GetArgumentAtIndex(0), +         m_process_launch_info.GetProcessID()); + +  return error; +} + +Error GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { +  Error error; + +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, +                __FUNCTION__, pid); + +  // Before we try to attach, make sure we aren't already monitoring something +  // else. +  if (m_debugged_process_sp && +      m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID) +    return Error("cannot attach to a process %" PRIu64 +                 " when another process with pid %" PRIu64 +                 " is being debugged.", +                 pid, m_debugged_process_sp->GetID()); + +  // Try to attach. +  error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, +                                        m_debugged_process_sp); +  if (!error.Success()) { +    fprintf(stderr, "%s: failed to attach to process %" PRIu64 ": %s", +            __FUNCTION__, pid, error.AsCString());      return error; -} +  } -void -GDBRemoteCommunicationServerLLGS::InitializeDelegate (NativeProcessProtocol *process) -{ -    assert (process && "process cannot be NULL"); -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  // Setup stdout/stderr mapping from inferior. +  auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor(); +  if (terminal_fd >= 0) {      if (log) -    { -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", current state: %s", -                __FUNCTION__, -                process->GetID (), -                StateAsCString (process->GetState ())); -    } -} - -GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::SendWResponse (NativeProcessProtocol *process) -{ -    assert (process && "process cannot be NULL"); -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    // send W notification -    ExitType exit_type = ExitType::eExitTypeInvalid; -    int return_code = 0; -    std::string exit_description; - -    const bool got_exit_info = process->GetExitStatus (&exit_type, &return_code, exit_description); -    if (!got_exit_info) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", failed to retrieve process exit status", __FUNCTION__, process->GetID ()); - -        StreamGDBRemote response; -        response.PutChar ('E'); -        response.PutHex8 (GDBRemoteServerError::eErrorExitStatus); -        return SendPacketNoLock(response.GetData(), response.GetSize()); -    } -    else -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", returning exit type %d, return code %d [%s]", __FUNCTION__, process->GetID (), exit_type, return_code, exit_description.c_str ()); - -        StreamGDBRemote response; - -        char return_type_code; -        switch (exit_type) -        { -            case ExitType::eExitTypeExit: -                return_type_code = 'W'; -                break; -            case ExitType::eExitTypeSignal: -                return_type_code = 'X'; -                break; -            case ExitType::eExitTypeStop: -                return_type_code = 'S'; -                break; -            case ExitType::eExitTypeInvalid: -                return_type_code = 'E'; -                break; -        } -        response.PutChar (return_type_code); +      log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting " +                  "inferior STDIO fd to %d", +                  __FUNCTION__, terminal_fd); +    error = SetSTDIOFileDescriptor(terminal_fd); +    if (error.Fail()) +      return error; +  } else { +    if (log) +      log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " +                  "inferior STDIO since terminal fd reported as %d", +                  __FUNCTION__, terminal_fd); +  } -        // POSIX exit status limited to unsigned 8 bits. -        response.PutHex8 (return_code); +  printf("Attached to process %" PRIu64 "...\n", pid); -        return SendPacketNoLock(response.GetData(), response.GetSize()); -    } +  return error;  } -static void -AppendHexValue (StreamString &response, const uint8_t* buf, uint32_t buf_size, bool swap) -{ -    int64_t i; -    if (swap) -    { -        for (i = buf_size-1; i >= 0; i--) -            response.PutHex8 (buf[i]); -    } -    else -    { -        for (i = 0; i < buf_size; i++) -            response.PutHex8 (buf[i]); -    } +void GDBRemoteCommunicationServerLLGS::InitializeDelegate( +    NativeProcessProtocol *process) { +  assert(process && "process cannot be NULL"); +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  if (log) { +    log->Printf("GDBRemoteCommunicationServerLLGS::%s called with " +                "NativeProcessProtocol pid %" PRIu64 ", current state: %s", +                __FUNCTION__, process->GetID(), +                StateAsCString(process->GetState())); +  }  } -static void -WriteRegisterValueInHexFixedWidth (StreamString &response, -                                   NativeRegisterContextSP ®_ctx_sp, -                                   const RegisterInfo ®_info, -                                   const RegisterValue *reg_value_p) -{ -    RegisterValue reg_value; -    if (!reg_value_p) -    { -        Error error = reg_ctx_sp->ReadRegister (®_info, reg_value); -        if (error.Success ()) -            reg_value_p = ®_value; -        // else log. -    } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::SendWResponse( +    NativeProcessProtocol *process) { +  assert(process && "process cannot be NULL"); +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + +  // send W notification +  ExitType exit_type = ExitType::eExitTypeInvalid; +  int return_code = 0; +  std::string exit_description; + +  const bool got_exit_info = +      process->GetExitStatus(&exit_type, &return_code, exit_description); +  if (!got_exit_info) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  ", failed to retrieve process exit status", +                  __FUNCTION__, process->GetID()); -    if (reg_value_p) -    { -        AppendHexValue (response, (const uint8_t*) reg_value_p->GetBytes (), reg_value_p->GetByteSize (), false); -    } -    else -    { -        // Zero-out any unreadable values. -        if (reg_info.byte_size > 0) -        { -            std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0'); -            AppendHexValue (response, zeros.data(), zeros.size(), false); -        } -    } -} +    StreamGDBRemote response; +    response.PutChar('E'); +    response.PutHex8(GDBRemoteServerError::eErrorExitStatus); +    return SendPacketNoLock(response.GetString()); +  } else { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  ", returning exit type %d, return code %d [%s]", +                  __FUNCTION__, process->GetID(), exit_type, return_code, +                  exit_description.c_str()); -static JSONObject::SP -GetRegistersAsJSON(NativeThreadProtocol &thread, bool abridged) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD)); +    StreamGDBRemote response; -    NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext (); -    if (! reg_ctx_sp) -        return nullptr; +    char return_type_code; +    switch (exit_type) { +    case ExitType::eExitTypeExit: +      return_type_code = 'W'; +      break; +    case ExitType::eExitTypeSignal: +      return_type_code = 'X'; +      break; +    case ExitType::eExitTypeStop: +      return_type_code = 'S'; +      break; +    case ExitType::eExitTypeInvalid: +      return_type_code = 'E'; +      break; +    } +    response.PutChar(return_type_code); + +    // POSIX exit status limited to unsigned 8 bits. +    response.PutHex8(return_code); + +    return SendPacketNoLock(response.GetString()); +  } +} + +static void AppendHexValue(StreamString &response, const uint8_t *buf, +                           uint32_t buf_size, bool swap) { +  int64_t i; +  if (swap) { +    for (i = buf_size - 1; i >= 0; i--) +      response.PutHex8(buf[i]); +  } else { +    for (i = 0; i < buf_size; i++) +      response.PutHex8(buf[i]); +  } +} + +static void WriteRegisterValueInHexFixedWidth( +    StreamString &response, NativeRegisterContextSP ®_ctx_sp, +    const RegisterInfo ®_info, const RegisterValue *reg_value_p) { +  RegisterValue reg_value; +  if (!reg_value_p) { +    Error error = reg_ctx_sp->ReadRegister(®_info, reg_value); +    if (error.Success()) +      reg_value_p = ®_value; +    // else log. +  } + +  if (reg_value_p) { +    AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(), +                   reg_value_p->GetByteSize(), false); +  } else { +    // Zero-out any unreadable values. +    if (reg_info.byte_size > 0) { +      std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0'); +      AppendHexValue(response, zeros.data(), zeros.size(), false); +    } +  } +} + +static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread, +                                         bool abridged) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); +  if (!reg_ctx_sp) +    return nullptr; -    JSONObject::SP register_object_sp = std::make_shared<JSONObject>(); +  JSONObject::SP register_object_sp = std::make_shared<JSONObject>();  #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET -    // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers. -    const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0); -    if (! reg_set_p) -        return nullptr; -    for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) -    { -        uint32_t reg_num = *reg_num_p; +  // Expedite all registers in the first register set (i.e. should be GPRs) that +  // are not contained in other registers. +  const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0); +  if (!reg_set_p) +    return nullptr; +  for (const uint32_t *reg_num_p = reg_set_p->registers; +       *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { +    uint32_t reg_num = *reg_num_p;  #else -    // Expedite only a couple of registers until we figure out why sending registers is -    // expensive. -    static const uint32_t k_expedited_registers[] = { -        LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM -    }; -    static const uint32_t k_abridged_expedited_registers[] = { -        LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM -    }; - -    for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers : k_expedited_registers; -         *generic_reg_p != LLDB_INVALID_REGNUM; -         ++generic_reg_p) -    { -        uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, *generic_reg_p); -        if (reg_num == LLDB_INVALID_REGNUM) -            continue; // Target does not support the given register. +  // Expedite only a couple of registers until we figure out why sending +  // registers is +  // expensive. +  static const uint32_t k_expedited_registers[] = { +      LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, +      LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM}; +  static const uint32_t k_abridged_expedited_registers[] = { +      LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM}; + +  for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers +                                                : k_expedited_registers; +       *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) { +    uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( +        eRegisterKindGeneric, *generic_reg_p); +    if (reg_num == LLDB_INVALID_REGNUM) +      continue; // Target does not support the given register.  #endif -        const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex(reg_num); -        if (reg_info_p == nullptr) -        { -            if (log) -                log->Printf("%s failed to get register info for register index %" PRIu32, -                        __FUNCTION__, reg_num); -            continue; -        } - -        if (reg_info_p->value_regs != nullptr) -            continue; // Only expedite registers that are not contained in other registers. - -        RegisterValue reg_value; -        Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); -        if (error.Fail()) -        { -            if (log) -                log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__, -                        reg_info_p->name ? reg_info_p->name : "<unnamed-register>", reg_num, -                        error.AsCString ()); -            continue; -        } - -        StreamString stream; -        WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, ®_value); - -        register_object_sp->SetObject(std::to_string(reg_num), -                std::make_shared<JSONString>(stream.GetString())); -    } - -    return register_object_sp; -} - -static const char * -GetStopReasonString(StopReason stop_reason) -{ -    switch (stop_reason) -    { -    case eStopReasonTrace: -        return "trace"; -    case eStopReasonBreakpoint: -        return "breakpoint"; -    case eStopReasonWatchpoint: -        return "watchpoint"; -    case eStopReasonSignal: -        return "signal"; -    case eStopReasonException: -        return "exception"; -    case eStopReasonExec: -        return "exec"; -    case eStopReasonInstrumentation: -    case eStopReasonInvalid: -    case eStopReasonPlanComplete: -    case eStopReasonThreadExiting: -    case eStopReasonNone: -        break; // ignored +    const RegisterInfo *const reg_info_p = +        reg_ctx_sp->GetRegisterInfoAtIndex(reg_num); +    if (reg_info_p == nullptr) { +      if (log) +        log->Printf( +            "%s failed to get register info for register index %" PRIu32, +            __FUNCTION__, reg_num); +      continue;      } -    return nullptr; -} -static JSONArray::SP -GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); +    if (reg_info_p->value_regs != nullptr) +      continue; // Only expedite registers that are not contained in other +                // registers. -    JSONArray::SP threads_array_sp = std::make_shared<JSONArray>(); - -    // Ensure we can get info on the given thread. -    uint32_t thread_idx = 0; -    for ( NativeThreadProtocolSP thread_sp; -          (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr; -          ++thread_idx) -    { - -        lldb::tid_t tid = thread_sp->GetID(); - -        // Grab the reason this thread stopped. -        struct ThreadStopInfo tid_stop_info; -        std::string description; -        if (!thread_sp->GetStopReason (tid_stop_info, description)) -            return nullptr; - -        const int signum = tid_stop_info.details.signal.signo; -        if (log) -        { -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64, +    RegisterValue reg_value; +    Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); +    if (error.Fail()) { +      if (log) +        log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",                      __FUNCTION__, -                    process.GetID (), -                    tid, -                    signum, -                    tid_stop_info.reason, -                    tid_stop_info.details.exception.type); -        } - -        JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>(); -        threads_array_sp->AppendObject(thread_obj_sp); - -        if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged)) -            thread_obj_sp->SetObject("registers", registers_sp); - -        thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid)); -        if (signum != 0) -            thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum)); +                    reg_info_p->name ? reg_info_p->name : "<unnamed-register>", +                    reg_num, error.AsCString()); +      continue; +    } + +    StreamString stream; +    WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, +                                      ®_value); + +    register_object_sp->SetObject( +        llvm::to_string(reg_num), +        std::make_shared<JSONString>(stream.GetString())); +  } + +  return register_object_sp; +} + +static const char *GetStopReasonString(StopReason stop_reason) { +  switch (stop_reason) { +  case eStopReasonTrace: +    return "trace"; +  case eStopReasonBreakpoint: +    return "breakpoint"; +  case eStopReasonWatchpoint: +    return "watchpoint"; +  case eStopReasonSignal: +    return "signal"; +  case eStopReasonException: +    return "exception"; +  case eStopReasonExec: +    return "exec"; +  case eStopReasonInstrumentation: +  case eStopReasonInvalid: +  case eStopReasonPlanComplete: +  case eStopReasonThreadExiting: +  case eStopReasonNone: +    break; // ignored +  } +  return nullptr; +} + +static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, +                                        bool abridged) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + +  JSONArray::SP threads_array_sp = std::make_shared<JSONArray>(); + +  // Ensure we can get info on the given thread. +  uint32_t thread_idx = 0; +  for (NativeThreadProtocolSP thread_sp; +       (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr; +       ++thread_idx) { + +    lldb::tid_t tid = thread_sp->GetID(); -        const std::string thread_name = thread_sp->GetName (); -        if (! thread_name.empty()) -            thread_obj_sp->SetObject("name", std::make_shared<JSONString>(thread_name)); - -        if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason)) -            thread_obj_sp->SetObject("reason", std::make_shared<JSONString>(stop_reason_str)); - -        if (! description.empty()) -            thread_obj_sp->SetObject("description", std::make_shared<JSONString>(description)); - -        if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type) -        { -            thread_obj_sp->SetObject("metype", -                    std::make_shared<JSONNumber>(tid_stop_info.details.exception.type)); - -            JSONArray::SP medata_array_sp = std::make_shared<JSONArray>(); -            for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) -            { -                medata_array_sp->AppendObject(std::make_shared<JSONNumber>( -                            tid_stop_info.details.exception.data[i])); -            } -            thread_obj_sp->SetObject("medata", medata_array_sp); -        } +    // Grab the reason this thread stopped. +    struct ThreadStopInfo tid_stop_info; +    std::string description; +    if (!thread_sp->GetStopReason(tid_stop_info, description)) +      return nullptr; -        // TODO: Expedite interesting regions of inferior memory +    const int signum = tid_stop_info.details.signal.signo; +    if (log) { +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " tid %" PRIu64 +                  " got signal signo = %d, reason = %d, exc_type = %" PRIu64, +                  __FUNCTION__, process.GetID(), tid, signum, +                  tid_stop_info.reason, tid_stop_info.details.exception.type);      } -    return threads_array_sp; -} +    JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>(); +    threads_array_sp->AppendObject(thread_obj_sp); -GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread (lldb::tid_t tid) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); +    if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged)) +      thread_obj_sp->SetObject("registers", registers_sp); -    // Ensure we have a debugged process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -        return SendErrorResponse (50); +    thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid)); +    if (signum != 0) +      thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64 " tid %" PRIu64, -                __FUNCTION__, m_debugged_process_sp->GetID (), tid); +    const std::string thread_name = thread_sp->GetName(); +    if (!thread_name.empty()) +      thread_obj_sp->SetObject("name", +                               std::make_shared<JSONString>(thread_name)); -    // Ensure we can get info on the given thread. -    NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid)); -    if (!thread_sp) -        return SendErrorResponse (51); +    if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason)) +      thread_obj_sp->SetObject("reason", +                               std::make_shared<JSONString>(stop_reason_str)); -    // Grab the reason this thread stopped. -    struct ThreadStopInfo tid_stop_info; -    std::string description; -    if (!thread_sp->GetStopReason (tid_stop_info, description)) -        return SendErrorResponse (52); +    if (!description.empty()) +      thread_obj_sp->SetObject("description", +                               std::make_shared<JSONString>(description)); -    // FIXME implement register handling for exec'd inferiors. -    // if (tid_stop_info.reason == eStopReasonExec) -    // { -    //     const bool force = true; -    //     InitializeRegisters(force); -    // } +    if ((tid_stop_info.reason == eStopReasonException) && +        tid_stop_info.details.exception.type) { +      thread_obj_sp->SetObject( +          "metype", +          std::make_shared<JSONNumber>(tid_stop_info.details.exception.type)); -    StreamString response; -    // Output the T packet with the thread -    response.PutChar ('T'); -    int signum = tid_stop_info.details.signal.signo; -    if (log) -    { -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,  -                __FUNCTION__, -                m_debugged_process_sp->GetID (), -                tid, -                signum, -                tid_stop_info.reason, -                tid_stop_info.details.exception.type); +      JSONArray::SP medata_array_sp = std::make_shared<JSONArray>(); +      for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; +           ++i) { +        medata_array_sp->AppendObject(std::make_shared<JSONNumber>( +            tid_stop_info.details.exception.data[i])); +      } +      thread_obj_sp->SetObject("medata", medata_array_sp);      } -    // Print the signal number. -    response.PutHex8 (signum & 0xff); - -    // Include the tid. -    response.Printf ("thread:%" PRIx64 ";", tid); - -    // Include the thread name if there is one. -    const std::string thread_name = thread_sp->GetName (); -    if (!thread_name.empty ()) -    { -        size_t thread_name_len = thread_name.length (); +    // TODO: Expedite interesting regions of inferior memory +  } -        if (::strcspn (thread_name.c_str (), "$#+-;:") == thread_name_len) -        { -            response.PutCString ("name:"); -            response.PutCString (thread_name.c_str ()); -        } -        else -        { -            // The thread name contains special chars, send as hex bytes. -            response.PutCString ("hexname:"); -            response.PutCStringAsRawHex8 (thread_name.c_str ()); -        } -        response.PutChar (';'); -    } - -    // If a 'QListThreadsInStopReply' was sent to enable this feature, we -    // will send all thread IDs back in the "threads" key whose value is -    // a list of hex thread IDs separated by commas: -    //  "threads:10a,10b,10c;" -    // This will save the debugger from having to send a pair of qfThreadInfo -    // and qsThreadInfo packets, but it also might take a lot of room in the -    // stop reply packet, so it must be enabled only on systems where there -    // are no limits on packet lengths. -    if (m_list_threads_in_stop_reply) -    { -        response.PutCString ("threads:"); - -        uint32_t thread_index = 0; -        NativeThreadProtocolSP listed_thread_sp; -        for (listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index); listed_thread_sp; ++thread_index, listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index)) -        { -            if (thread_index > 0) -                response.PutChar (','); -            response.Printf ("%" PRIx64, listed_thread_sp->GetID ()); -        } -        response.PutChar (';'); - -        // Include JSON info that describes the stop reason for any threads -        // that actually have stop reasons. We use the new "jstopinfo" key -        // whose values is hex ascii JSON that contains the thread IDs -        // thread stop info only for threads that have stop reasons. Only send -        // this if we have more than one thread otherwise this packet has all -        // the info it needs. -        if (thread_index > 0) -        { -            const bool threads_with_valid_stop_info_only = true; -            JSONArray::SP threads_info_sp = GetJSONThreadsInfo(*m_debugged_process_sp, -                                                               threads_with_valid_stop_info_only); -            if (threads_info_sp) -            { -                response.PutCString("jstopinfo:"); -                StreamString unescaped_response; -                threads_info_sp->Write(unescaped_response); -                response.PutCStringAsRawHex8(unescaped_response.GetData()); -                response.PutChar(';'); -            } -            else if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a jstopinfo field for pid %" PRIu64, -                        __FUNCTION__, m_debugged_process_sp->GetID()); +  return threads_array_sp; +} -        } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( +    lldb::tid_t tid) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + +  // Ensure we have a debugged process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) +    return SendErrorResponse(50); + +  if (log) +    log->Printf( +        "GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64 +        " tid %" PRIu64, +        __FUNCTION__, m_debugged_process_sp->GetID(), tid); + +  // Ensure we can get info on the given thread. +  NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid)); +  if (!thread_sp) +    return SendErrorResponse(51); + +  // Grab the reason this thread stopped. +  struct ThreadStopInfo tid_stop_info; +  std::string description; +  if (!thread_sp->GetStopReason(tid_stop_info, description)) +    return SendErrorResponse(52); + +  // FIXME implement register handling for exec'd inferiors. +  // if (tid_stop_info.reason == eStopReasonExec) +  // { +  //     const bool force = true; +  //     InitializeRegisters(force); +  // } + +  StreamString response; +  // Output the T packet with the thread +  response.PutChar('T'); +  int signum = tid_stop_info.details.signal.signo; +  if (log) { +    log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                " tid %" PRIu64 +                " got signal signo = %d, reason = %d, exc_type = %" PRIu64, +                __FUNCTION__, m_debugged_process_sp->GetID(), tid, signum, +                tid_stop_info.reason, tid_stop_info.details.exception.type); +  } + +  // Print the signal number. +  response.PutHex8(signum & 0xff); + +  // Include the tid. +  response.Printf("thread:%" PRIx64 ";", tid); + +  // Include the thread name if there is one. +  const std::string thread_name = thread_sp->GetName(); +  if (!thread_name.empty()) { +    size_t thread_name_len = thread_name.length(); + +    if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) { +      response.PutCString("name:"); +      response.PutCString(thread_name); +    } else { +      // The thread name contains special chars, send as hex bytes. +      response.PutCString("hexname:"); +      response.PutCStringAsRawHex8(thread_name.c_str()); +    } +    response.PutChar(';'); +  } + +  // If a 'QListThreadsInStopReply' was sent to enable this feature, we +  // will send all thread IDs back in the "threads" key whose value is +  // a list of hex thread IDs separated by commas: +  //  "threads:10a,10b,10c;" +  // This will save the debugger from having to send a pair of qfThreadInfo +  // and qsThreadInfo packets, but it also might take a lot of room in the +  // stop reply packet, so it must be enabled only on systems where there +  // are no limits on packet lengths. +  if (m_list_threads_in_stop_reply) { +    response.PutCString("threads:"); + +    uint32_t thread_index = 0; +    NativeThreadProtocolSP listed_thread_sp; +    for (listed_thread_sp = +             m_debugged_process_sp->GetThreadAtIndex(thread_index); +         listed_thread_sp; ++thread_index, +        listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex( +            thread_index)) { +      if (thread_index > 0) +        response.PutChar(','); +      response.Printf("%" PRIx64, listed_thread_sp->GetID()); +    } +    response.PutChar(';'); + +    // Include JSON info that describes the stop reason for any threads +    // that actually have stop reasons. We use the new "jstopinfo" key +    // whose values is hex ascii JSON that contains the thread IDs +    // thread stop info only for threads that have stop reasons. Only send +    // this if we have more than one thread otherwise this packet has all +    // the info it needs. +    if (thread_index > 0) { +      const bool threads_with_valid_stop_info_only = true; +      JSONArray::SP threads_info_sp = GetJSONThreadsInfo( +          *m_debugged_process_sp, threads_with_valid_stop_info_only); +      if (threads_info_sp) { +        response.PutCString("jstopinfo:"); +        StreamString unescaped_response; +        threads_info_sp->Write(unescaped_response); +        response.PutCStringAsRawHex8(unescaped_response.GetData()); +        response.PutChar(';'); +      } else if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a " +                    "jstopinfo field for pid %" PRIu64, +                    __FUNCTION__, m_debugged_process_sp->GetID());      } - -    // -    // Expedite registers. -    // - -    // Grab the register context. -    NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext (); -    if (reg_ctx_sp) -    { -        // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers. -        const RegisterSet *reg_set_p; -        if (reg_ctx_sp->GetRegisterSetCount () > 0 && ((reg_set_p = reg_ctx_sp->GetRegisterSet (0)) != nullptr)) -        { +  } + +  // +  // Expedite registers. +  // + +  // Grab the register context. +  NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); +  if (reg_ctx_sp) { +    // Expedite all registers in the first register set (i.e. should be GPRs) +    // that are not contained in other registers. +    const RegisterSet *reg_set_p; +    if (reg_ctx_sp->GetRegisterSetCount() > 0 && +        ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers " +                    "from set '%s' (registers set count: %zu)", +                    __FUNCTION__, +                    reg_set_p->name ? reg_set_p->name : "<unnamed-set>", +                    reg_set_p->num_registers); + +      for (const uint32_t *reg_num_p = reg_set_p->registers; +           *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { +        const RegisterInfo *const reg_info_p = +            reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p); +        if (reg_info_p == nullptr) { +          if (log) +            log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get " +                        "register info for register set '%s', register index " +                        "%" PRIu32, +                        __FUNCTION__, +                        reg_set_p->name ? reg_set_p->name : "<unnamed-set>", +                        *reg_num_p); +        } else if (reg_info_p->value_regs == nullptr) { +          // Only expediate registers that are not contained in other registers. +          RegisterValue reg_value; +          Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); +          if (error.Success()) { +            response.Printf("%.02x:", *reg_num_p); +            WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, +                                              ®_value); +            response.PutChar(';'); +          } else {              if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s expediting registers from set '%s' (registers set count: %zu)", __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", reg_set_p->num_registers); - -            for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) -            { -                const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex (*reg_num_p); -                if (reg_info_p == nullptr) -                { -                    if (log) -                        log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get register info for register set '%s', register index %" PRIu32, __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", *reg_num_p); -                } -                else if (reg_info_p->value_regs == nullptr) -                { -                    // Only expediate registers that are not contained in other registers. -                    RegisterValue reg_value; -                    Error error = reg_ctx_sp->ReadRegister (reg_info_p, reg_value); -                    if (error.Success ()) -                    { -                        response.Printf ("%.02x:", *reg_num_p); -                        WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, ®_value); -                        response.PutChar (';'); -                    } -                    else -                    { -                        if (log) -                            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__, reg_info_p->name ? reg_info_p->name : "<unnamed-register>", *reg_num_p, error.AsCString ()); - -                    } -                } -            } +              log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read " +                          "register '%s' index %" PRIu32 ": %s", +                          __FUNCTION__, reg_info_p->name ? reg_info_p->name +                                                         : "<unnamed-register>", +                          *reg_num_p, error.AsCString()); +          }          } +      }      } +  } -    const char* reason_str = GetStopReasonString(tid_stop_info.reason); -    if (reason_str != nullptr) -    { -        response.Printf ("reason:%s;", reason_str); -    } +  const char *reason_str = GetStopReasonString(tid_stop_info.reason); +  if (reason_str != nullptr) { +    response.Printf("reason:%s;", reason_str); +  } -    if (!description.empty()) -    { -        // Description may contains special chars, send as hex bytes. -        response.PutCString ("description:"); -        response.PutCStringAsRawHex8 (description.c_str ()); -        response.PutChar (';'); -    } -    else if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type) -    { -        response.PutCString ("metype:"); -        response.PutHex64 (tid_stop_info.details.exception.type); -        response.PutCString (";mecount:"); -        response.PutHex32 (tid_stop_info.details.exception.data_count); -        response.PutChar (';'); - -        for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) -        { -            response.PutCString ("medata:"); -            response.PutHex64 (tid_stop_info.details.exception.data[i]); -            response.PutChar (';'); -        } +  if (!description.empty()) { +    // Description may contains special chars, send as hex bytes. +    response.PutCString("description:"); +    response.PutCStringAsRawHex8(description.c_str()); +    response.PutChar(';'); +  } else if ((tid_stop_info.reason == eStopReasonException) && +             tid_stop_info.details.exception.type) { +    response.PutCString("metype:"); +    response.PutHex64(tid_stop_info.details.exception.type); +    response.PutCString(";mecount:"); +    response.PutHex32(tid_stop_info.details.exception.data_count); +    response.PutChar(';'); + +    for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) { +      response.PutCString("medata:"); +      response.PutHex64(tid_stop_info.details.exception.data[i]); +      response.PutChar(';');      } +  } -    return SendPacketNoLock (response.GetData(), response.GetSize()); +  return SendPacketNoLock(response.GetString());  } -void -GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited (NativeProcessProtocol *process) -{ -    assert (process && "process cannot be NULL"); - -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); - -    PacketResult result = SendStopReasonForState(StateType::eStateExited); -    if (result != PacketResult::Success) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ()); -    } +void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( +    NativeProcessProtocol *process) { +  assert(process && "process cannot be NULL"); -    // Close the pipe to the inferior terminal i/o if we launched it -    // and set one up. -    MaybeCloseInferiorTerminalConnection (); - -    // We are ready to exit the debug monitor. -    m_exit_now = true; -} - -void -GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped (NativeProcessProtocol *process) -{ -    assert (process && "process cannot be NULL"); - -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); - -    // Send the stop reason unless this is the stop after the -    // launch or attach. -    switch (m_inferior_prev_state) -    { -        case eStateLaunching: -        case eStateAttaching: -            // Don't send anything per debugserver behavior. -            break; -        default: -            // In all other cases, send the stop reason. -            PacketResult result = SendStopReasonForState(StateType::eStateStopped); -            if (result != PacketResult::Success) -            { -                if (log) -                    log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ()); -            } -            break; -    } -} +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); -void -GDBRemoteCommunicationServerLLGS::ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state) -{ -    assert (process && "process cannot be NULL"); -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  PacketResult result = SendStopReasonForState(StateType::eStateExited); +  if (result != PacketResult::Success) {      if (log) -    { -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", state: %s", -                __FUNCTION__, -                process->GetID (), -                StateAsCString (state)); -    } +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop " +                  "notification for PID %" PRIu64 ", state: eStateExited", +                  __FUNCTION__, process->GetID()); +  } + +  // Close the pipe to the inferior terminal i/o if we launched it +  // and set one up. +  MaybeCloseInferiorTerminalConnection(); + +  // We are ready to exit the debug monitor. +  m_exit_now = true; +} + +void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( +    NativeProcessProtocol *process) { +  assert(process && "process cannot be NULL"); + +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); + +  // Send the stop reason unless this is the stop after the +  // launch or attach. +  switch (m_inferior_prev_state) { +  case eStateLaunching: +  case eStateAttaching: +    // Don't send anything per debugserver behavior. +    break; +  default: +    // In all other cases, send the stop reason. +    PacketResult result = SendStopReasonForState(StateType::eStateStopped); +    if (result != PacketResult::Success) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop " +                    "notification for PID %" PRIu64 ", state: eStateExited", +                    __FUNCTION__, process->GetID()); +    } +    break; +  } +} + +void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( +    NativeProcessProtocol *process, lldb::StateType state) { +  assert(process && "process cannot be NULL"); +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  if (log) { +    log->Printf("GDBRemoteCommunicationServerLLGS::%s called with " +                "NativeProcessProtocol pid %" PRIu64 ", state: %s", +                __FUNCTION__, process->GetID(), StateAsCString(state)); +  } + +  switch (state) { +  case StateType::eStateRunning: +    StartSTDIOForwarding(); +    break; + +  case StateType::eStateStopped: +    // Make sure we get all of the pending stdout/stderr from the inferior +    // and send it to the lldb host before we send the state change +    // notification +    SendProcessOutput(); +    // Then stop the forwarding, so that any late output (see llvm.org/pr25652) +    // does not +    // interfere with our protocol. +    StopSTDIOForwarding(); +    HandleInferiorState_Stopped(process); +    break; -    switch (state) -    { -    case StateType::eStateRunning: -        StartSTDIOForwarding(); -        break; - -    case StateType::eStateStopped: -        // Make sure we get all of the pending stdout/stderr from the inferior -        // and send it to the lldb host before we send the state change -        // notification -        SendProcessOutput(); -        // Then stop the forwarding, so that any late output (see llvm.org/pr25652) does not -        // interfere with our protocol. -        StopSTDIOForwarding(); -        HandleInferiorState_Stopped (process); -        break; - -    case StateType::eStateExited: -        // Same as above -        SendProcessOutput(); -        StopSTDIOForwarding(); -        HandleInferiorState_Exited (process); -        break; +  case StateType::eStateExited: +    // Same as above +    SendProcessOutput(); +    StopSTDIOForwarding(); +    HandleInferiorState_Exited(process); +    break; -    default: -        if (log) -        { -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s didn't handle state change for pid %" PRIu64 ", new state: %s", -                    __FUNCTION__, -                    process->GetID (), -                    StateAsCString (state)); -        } -        break; +  default: +    if (log) { +      log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state " +                  "change for pid %" PRIu64 ", new state: %s", +                  __FUNCTION__, process->GetID(), StateAsCString(state));      } +    break; +  } -    // Remember the previous state reported to us. -    m_inferior_prev_state = state; +  // Remember the previous state reported to us. +  m_inferior_prev_state = state;  } -void -GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process) -{ -    ClearProcessSpecificData (); +void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) { +  ClearProcessSpecificData();  } -void -GDBRemoteCommunicationServerLLGS::DataAvailableCallback () -{ -    Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM)); +void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { +  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM)); -    if (! m_handshake_completed) -    { -        if (! HandshakeWithClient()) -        { -            if(log) -                log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting", -                        __FUNCTION__); -            m_mainloop.RequestTermination(); -            return; -        } -        m_handshake_completed = true; +  if (!m_handshake_completed) { +    if (!HandshakeWithClient()) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with " +                    "client failed, exiting", +                    __FUNCTION__); +      m_mainloop.RequestTermination(); +      return;      } +    m_handshake_completed = true; +  } -    bool interrupt = false; -    bool done = false; -    Error error; -    while (true) -    { -        const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done); -        if (result == PacketResult::ErrorReplyTimeout) -            break; // No more packets in the queue - -        if ((result != PacketResult::Success)) -        { -            if(log) -                log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s", -                        __FUNCTION__, error.AsCString()); -            m_mainloop.RequestTermination(); -            break; -        } +  bool interrupt = false; +  bool done = false; +  Error error; +  while (true) { +    const PacketResult result = GetPacketAndSendResponse( +        std::chrono::microseconds(0), error, interrupt, done); +    if (result == PacketResult::ErrorReplyTimeout) +      break; // No more packets in the queue + +    if ((result != PacketResult::Success)) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet " +                    "failed: %s", +                    __FUNCTION__, error.AsCString()); +      m_mainloop.RequestTermination(); +      break;      } +  }  } -Error -GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection) -{ -    IOObjectSP read_object_sp = connection->GetReadObject(); -    GDBRemoteCommunicationServer::SetConnection(connection.release()); +Error GDBRemoteCommunicationServerLLGS::InitializeConnection( +    std::unique_ptr<Connection> &&connection) { +  IOObjectSP read_object_sp = connection->GetReadObject(); +  GDBRemoteCommunicationServer::SetConnection(connection.release()); -    Error error; -    m_network_handle_up = m_mainloop.RegisterReadObject(read_object_sp, -            [this] (MainLoopBase &) { DataAvailableCallback(); }, error); -    return error; +  Error error; +  m_network_handle_up = m_mainloop.RegisterReadObject( +      read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); }, +      error); +  return error;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len) -{ -    if ((buffer == nullptr) || (len == 0)) -    { -        // Nothing to send. -        return PacketResult::Success; -    } - -    StreamString response; -    response.PutChar ('O'); -    response.PutBytesAsRawHex8 (buffer, len); - -    return SendPacketNoLock (response.GetData (), response.GetSize ()); -} - -Error -GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor (int fd) -{ -    Error error; - -    // Set up the reading/handling of process I/O -    std::unique_ptr<ConnectionFileDescriptor> conn_up (new ConnectionFileDescriptor (fd, true)); -    if (!conn_up) -    { -        error.SetErrorString ("failed to create ConnectionFileDescriptor"); -        return error; -    } +GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer, +                                                    uint32_t len) { +  if ((buffer == nullptr) || (len == 0)) { +    // Nothing to send. +    return PacketResult::Success; +  } -    m_stdio_communication.SetCloseOnEOF (false); -    m_stdio_communication.SetConnection (conn_up.release()); -    if (!m_stdio_communication.IsConnected ()) -    { -        error.SetErrorString ("failed to set connection for inferior I/O communication"); -        return error; -    } +  StreamString response; +  response.PutChar('O'); +  response.PutBytesAsRawHex8(buffer, len); -    return Error(); +  return SendPacketNoLock(response.GetString());  } -void -GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() -{ -    // Don't forward if not connected (e.g. when attaching). -    if (! m_stdio_communication.IsConnected()) -        return; - -    // llgs local-process debugging may specify PTY paths, which will make these -    // file actions non-null -    // process launch -e/o will also make these file actions non-null -    // nullptr means that the traffic is expected to flow over gdb-remote protocol -    if ( m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) && -         m_process_launch_info.GetFileActionForFD(STDERR_FILENO)) -        return; - -    Error error; -    lldbassert(! m_stdio_handle_up); -    m_stdio_handle_up = m_mainloop.RegisterReadObject( -            m_stdio_communication.GetConnection()->GetReadObject(), -            [this] (MainLoopBase &) { SendProcessOutput(); }, error); - -    if (! m_stdio_handle_up) -    { -        // Not much we can do about the failure. Log it and continue without forwarding. -        if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) -            log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio forwarding: %s", -                        __FUNCTION__, error.AsCString()); -    } -} +Error GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) { +  Error error; -void -GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() -{ -    m_stdio_handle_up.reset(); -} +  // Set up the reading/handling of process I/O +  std::unique_ptr<ConnectionFileDescriptor> conn_up( +      new ConnectionFileDescriptor(fd, true)); +  if (!conn_up) { +    error.SetErrorString("failed to create ConnectionFileDescriptor"); +    return error; +  } -void -GDBRemoteCommunicationServerLLGS::SendProcessOutput() -{ -    char buffer[1024]; -    ConnectionStatus status; -    Error error; -    while (true) -    { -        size_t bytes_read = m_stdio_communication.Read(buffer, sizeof buffer, 0, status, &error); -        switch (status) -        { -        case eConnectionStatusSuccess: -            SendONotification(buffer, bytes_read); -            break; -        case eConnectionStatusLostConnection: -        case eConnectionStatusEndOfFile: -        case eConnectionStatusError: -        case eConnectionStatusNoConnection: -            if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) -                log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio forwarding as communication returned status %d (error: %s)", __FUNCTION__, status, error.AsCString()); -            m_stdio_handle_up.reset(); -            return; - -        case eConnectionStatusInterrupted: -        case eConnectionStatusTimedOut: -            return; -        } -    } +  m_stdio_communication.SetCloseOnEOF(false); +  m_stdio_communication.SetConnection(conn_up.release()); +  if (!m_stdio_communication.IsConnected()) { +    error.SetErrorString( +        "failed to set connection for inferior I/O communication"); +    return error; +  } + +  return Error(); +} + +void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { +  // Don't forward if not connected (e.g. when attaching). +  if (!m_stdio_communication.IsConnected()) +    return; + +  Error error; +  lldbassert(!m_stdio_handle_up); +  m_stdio_handle_up = m_mainloop.RegisterReadObject( +      m_stdio_communication.GetConnection()->GetReadObject(), +      [this](MainLoopBase &) { SendProcessOutput(); }, error); + +  if (!m_stdio_handle_up) { +    // Not much we can do about the failure. Log it and continue without +    // forwarding. +    if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio " +                  "forwarding: %s", +                  __FUNCTION__, error.AsCString()); +  } +} + +void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() { +  m_stdio_handle_up.reset(); +} + +void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { +  char buffer[1024]; +  ConnectionStatus status; +  Error error; +  while (true) { +    size_t bytes_read = m_stdio_communication.Read( +        buffer, sizeof buffer, std::chrono::microseconds(0), status, &error); +    switch (status) { +    case eConnectionStatusSuccess: +      SendONotification(buffer, bytes_read); +      break; +    case eConnectionStatusLostConnection: +    case eConnectionStatusEndOfFile: +    case eConnectionStatusError: +    case eConnectionStatusNoConnection: +      if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio " +                    "forwarding as communication returned status %d (error: " +                    "%s)", +                    __FUNCTION__, status, error.AsCString()); +      m_stdio_handle_up.reset(); +      return; + +    case eConnectionStatusInterrupted: +    case eConnectionStatusTimedOut: +      return; +    } +  }  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo (StringExtractorGDBRemote &packet) -{ -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -        return SendErrorResponse (68); +GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo( +    StringExtractorGDBRemote &packet) { +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) +    return SendErrorResponse(68); -    lldb::pid_t pid = m_debugged_process_sp->GetID (); +  lldb::pid_t pid = m_debugged_process_sp->GetID(); -    if (pid == LLDB_INVALID_PROCESS_ID) -        return SendErrorResponse (1); +  if (pid == LLDB_INVALID_PROCESS_ID) +    return SendErrorResponse(1); -    ProcessInstanceInfo proc_info; -    if (!Host::GetProcessInfo (pid, proc_info)) -        return SendErrorResponse (1); +  ProcessInstanceInfo proc_info; +  if (!Host::GetProcessInfo(pid, proc_info)) +    return SendErrorResponse(1); -    StreamString response; -    CreateProcessInfoResponse_DebugServerStyle(proc_info, response); -    return SendPacketNoLock (response.GetData (), response.GetSize ()); +  StreamString response; +  CreateProcessInfoResponse_DebugServerStyle(proc_info, response); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qC (StringExtractorGDBRemote &packet) -{ -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -        return SendErrorResponse (68); +GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) +    return SendErrorResponse(68); -    // Make sure we set the current thread so g and p packets return -    // the data the gdb will expect. -    lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID (); -    SetCurrentThreadID (tid); +  // Make sure we set the current thread so g and p packets return +  // the data the gdb will expect. +  lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID(); +  SetCurrentThreadID(tid); -    NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread (); -    if (!thread_sp) -        return SendErrorResponse (69); +  NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread(); +  if (!thread_sp) +    return SendErrorResponse(69); -    StreamString response; -    response.Printf ("QC%" PRIx64, thread_sp->GetID ()); +  StreamString response; +  response.Printf("QC%" PRIx64, thread_sp->GetID()); -    return SendPacketNoLock (response.GetData(), response.GetSize()); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    StopSTDIOForwarding(); +  StopSTDIOForwarding(); -    if (! m_debugged_process_sp) -    { -        if (log) -            log->Printf("GDBRemoteCommunicationServerLLGS::%s No debugged process found.", __FUNCTION__); -        return PacketResult::Success; -    } +  if (!m_debugged_process_sp) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s No debugged process found.", +          __FUNCTION__); +    return PacketResult::Success; +  } -    Error error = m_debugged_process_sp->Kill(); -    if (error.Fail() && log) -        log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged process %" PRIu64 ": %s", -                __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString()); +  Error error = m_debugged_process_sp->Kill(); +  if (error.Fail() && log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged " +                "process %" PRIu64 ": %s", +                __FUNCTION__, m_debugged_process_sp->GetID(), +                error.AsCString()); -    // No OK response for kill packet. -    // return SendOKResponse (); -    return PacketResult::Success; +  // No OK response for kill packet. +  // return SendOKResponse (); +  return PacketResult::Success;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) -{ -    packet.SetFilePos(::strlen ("QSetDisableASLR:")); -    if (packet.GetU32(0)) -        m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); -    else -        m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); -    return SendOKResponse (); +GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR( +    StringExtractorGDBRemote &packet) { +  packet.SetFilePos(::strlen("QSetDisableASLR:")); +  if (packet.GetU32(0)) +    m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR); +  else +    m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) -{ -    packet.SetFilePos (::strlen ("QSetWorkingDir:")); -    std::string path; -    packet.GetHexByteString (path); -    m_process_launch_info.SetWorkingDirectory(FileSpec{path, true}); -    return SendOKResponse (); +GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( +    StringExtractorGDBRemote &packet) { +  packet.SetFilePos(::strlen("QSetWorkingDir:")); +  std::string path; +  packet.GetHexByteString(path); +  m_process_launch_info.SetWorkingDirectory(FileSpec{path, true}); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet) -{ -    FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()}; -    if (working_dir) -    { -        StreamString response; -        response.PutCStringAsRawHex8(working_dir.GetCString()); -        return SendPacketNoLock(response.GetData(), response.GetSize()); -    } +GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir( +    StringExtractorGDBRemote &packet) { +  FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()}; +  if (working_dir) { +    StreamString response; +    response.PutCStringAsRawHex8(working_dir.GetCString()); +    return SendPacketNoLock(response.GetString()); +  } -    return SendErrorResponse(14); +  return SendErrorResponse(14);  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_C (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); - -    // Ensure we have a native process. -    if (!m_debugged_process_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__); -        return SendErrorResponse (0x36); -    } - -    // Pull out the signal number. -    packet.SetFilePos (::strlen ("C")); -    if (packet.GetBytesLeft () < 1) -    { -        // Shouldn't be using a C without a signal. -        return SendIllFormedResponse (packet, "C packet specified without signal."); -    } -    const uint32_t signo = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ()); -    if (signo == std::numeric_limits<uint32_t>::max ()) -        return SendIllFormedResponse (packet, "failed to parse signal number"); - -    // Handle optional continue address. -    if (packet.GetBytesLeft () > 0) -    { -        // FIXME add continue at address support for $C{signo}[;{continue-address}]. -        if (*packet.Peek () == ';') -            return SendUnimplementedResponse (packet.GetStringRef().c_str()); -        else -            return SendIllFormedResponse (packet, "unexpected content after $C{signal-number}"); -    } +GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); -    ResumeActionList resume_actions (StateType::eStateRunning, 0); -    Error error; - -    // We have two branches: what to do if a continue thread is specified (in which case we target -    // sending the signal to that thread), or when we don't have a continue thread set (in which -    // case we send a signal to the process). - -    // TODO discuss with Greg Clayton, make sure this makes sense. - -    lldb::tid_t signal_tid = GetContinueThreadID (); -    if (signal_tid != LLDB_INVALID_THREAD_ID) -    { -        // The resume action for the continue thread (or all threads if a continue thread is not set). -        ResumeAction action = { GetContinueThreadID (), StateType::eStateRunning, static_cast<int> (signo) }; - -        // Add the action for the continue thread (or all threads when the continue thread isn't present). -        resume_actions.Append (action); -    } +  // Ensure we have a native process. +  if (!m_debugged_process_sp) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process " +                  "shared pointer", +                  __FUNCTION__); +    return SendErrorResponse(0x36); +  } + +  // Pull out the signal number. +  packet.SetFilePos(::strlen("C")); +  if (packet.GetBytesLeft() < 1) { +    // Shouldn't be using a C without a signal. +    return SendIllFormedResponse(packet, "C packet specified without signal."); +  } +  const uint32_t signo = +      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); +  if (signo == std::numeric_limits<uint32_t>::max()) +    return SendIllFormedResponse(packet, "failed to parse signal number"); + +  // Handle optional continue address. +  if (packet.GetBytesLeft() > 0) { +    // FIXME add continue at address support for $C{signo}[;{continue-address}]. +    if (*packet.Peek() == ';') +      return SendUnimplementedResponse(packet.GetStringRef().c_str());      else -    { -        // Send the signal to the process since we weren't targeting a specific continue thread with the signal. -        error = m_debugged_process_sp->Signal (signo); -        if (error.Fail ()) -        { -            if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send signal for process %" PRIu64 ": %s", -                             __FUNCTION__, -                             m_debugged_process_sp->GetID (), -                             error.AsCString ()); - -            return SendErrorResponse (0x52); -        } -    } - -    // Resume the threads. -    error = m_debugged_process_sp->Resume (resume_actions); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to resume threads for process %" PRIu64 ": %s", -                         __FUNCTION__, -                         m_debugged_process_sp->GetID (), -                         error.AsCString ()); +      return SendIllFormedResponse( +          packet, "unexpected content after $C{signal-number}"); +  } + +  ResumeActionList resume_actions(StateType::eStateRunning, 0); +  Error error; + +  // We have two branches: what to do if a continue thread is specified (in +  // which case we target +  // sending the signal to that thread), or when we don't have a continue thread +  // set (in which +  // case we send a signal to the process). + +  // TODO discuss with Greg Clayton, make sure this makes sense. + +  lldb::tid_t signal_tid = GetContinueThreadID(); +  if (signal_tid != LLDB_INVALID_THREAD_ID) { +    // The resume action for the continue thread (or all threads if a continue +    // thread is not set). +    ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning, +                           static_cast<int>(signo)}; + +    // Add the action for the continue thread (or all threads when the continue +    // thread isn't present). +    resume_actions.Append(action); +  } else { +    // Send the signal to the process since we weren't targeting a specific +    // continue thread with the signal. +    error = m_debugged_process_sp->Signal(signo); +    if (error.Fail()) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send " +                    "signal for process %" PRIu64 ": %s", +                    __FUNCTION__, m_debugged_process_sp->GetID(), +                    error.AsCString()); + +      return SendErrorResponse(0x52); +    } +  } + +  // Resume the threads. +  error = m_debugged_process_sp->Resume(resume_actions); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to resume " +                  "threads for process %" PRIu64 ": %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); -        return SendErrorResponse (0x38); -    } +    return SendErrorResponse(0x38); +  } -    // Don't send an "OK" packet; response is the stopped/exited message. -    return PacketResult::Success; +  // Don't send an "OK" packet; response is the stopped/exited message. +  return PacketResult::Success;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_c (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); - -    packet.SetFilePos (packet.GetFilePos() + ::strlen ("c")); +GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); -    // For now just support all continue. -    const bool has_continue_address = (packet.GetBytesLeft () > 0); -    if (has_continue_address) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]", __FUNCTION__, packet.Peek ()); -        return SendUnimplementedResponse (packet.GetStringRef().c_str()); -    } +  packet.SetFilePos(packet.GetFilePos() + ::strlen("c")); -    // Ensure we have a native process. -    if (!m_debugged_process_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__); -        return SendErrorResponse (0x36); -    } +  // For now just support all continue. +  const bool has_continue_address = (packet.GetBytesLeft() > 0); +  if (has_continue_address) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s not implemented for " +                  "c{address} variant [%s remains]", +                  __FUNCTION__, packet.Peek()); +    return SendUnimplementedResponse(packet.GetStringRef().c_str()); +  } + +  // Ensure we have a native process. +  if (!m_debugged_process_sp) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process " +                  "shared pointer", +                  __FUNCTION__); +    return SendErrorResponse(0x36); +  } -    // Build the ResumeActionList -    ResumeActionList actions (StateType::eStateRunning, 0); +  // Build the ResumeActionList +  ResumeActionList actions(StateType::eStateRunning, 0); -    Error error = m_debugged_process_sp->Resume (actions); -    if (error.Fail ()) -    { -        if (log) -        { -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64 ": %s", -                         __FUNCTION__, -                         m_debugged_process_sp->GetID (), -                         error.AsCString ()); -        } -        return SendErrorResponse (GDBRemoteServerError::eErrorResume); +  Error error = m_debugged_process_sp->Resume(actions); +  if (error.Fail()) { +    if (log) { +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64 +          ": %s", +          __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());      } +    return SendErrorResponse(GDBRemoteServerError::eErrorResume); +  } -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ()); +  if (log) +    log->Printf( +        "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, +        __FUNCTION__, m_debugged_process_sp->GetID()); -    // No response required from continue. -    return PacketResult::Success; +  // No response required from continue. +  return PacketResult::Success;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_vCont_actions (StringExtractorGDBRemote &packet) -{ -    StreamString response; -    response.Printf("vCont;c;C;s;S"); +GDBRemoteCommunicationServerLLGS::Handle_vCont_actions( +    StringExtractorGDBRemote &packet) { +  StreamString response; +  response.Printf("vCont;c;C;s;S"); -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s handling vCont packet", __FUNCTION__); - -    packet.SetFilePos (::strlen ("vCont")); +GDBRemoteCommunicationServerLLGS::Handle_vCont( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet", +                __FUNCTION__); -    if (packet.GetBytesLeft() == 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s missing action from vCont package", __FUNCTION__); -        return SendIllFormedResponse (packet, "Missing action from vCont package"); -    } +  packet.SetFilePos(::strlen("vCont")); -    // Check if this is all continue (no options or ";c"). -    if (::strcmp (packet.Peek (), ";c") == 0) -    { -        // Move past the ';', then do a simple 'c'. -        packet.SetFilePos (packet.GetFilePos () + 1); -        return Handle_c (packet); -    } -    else if (::strcmp (packet.Peek (), ";s") == 0) -    { -        // Move past the ';', then do a simple 's'. -        packet.SetFilePos (packet.GetFilePos () + 1); -        return Handle_s (packet); -    } +  if (packet.GetBytesLeft() == 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from " +                  "vCont package", +                  __FUNCTION__); +    return SendIllFormedResponse(packet, "Missing action from vCont package"); +  } + +  // Check if this is all continue (no options or ";c"). +  if (::strcmp(packet.Peek(), ";c") == 0) { +    // Move past the ';', then do a simple 'c'. +    packet.SetFilePos(packet.GetFilePos() + 1); +    return Handle_c(packet); +  } else if (::strcmp(packet.Peek(), ";s") == 0) { +    // Move past the ';', then do a simple 's'. +    packet.SetFilePos(packet.GetFilePos() + 1); +    return Handle_s(packet); +  } + +  // Ensure we have a native process. +  if (!m_debugged_process_sp) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process " +                  "shared pointer", +                  __FUNCTION__); +    return SendErrorResponse(0x36); +  } + +  ResumeActionList thread_actions; + +  while (packet.GetBytesLeft() && *packet.Peek() == ';') { +    // Skip the semi-colon. +    packet.GetChar(); + +    // Build up the thread action. +    ResumeAction thread_action; +    thread_action.tid = LLDB_INVALID_THREAD_ID; +    thread_action.state = eStateInvalid; +    thread_action.signal = 0; + +    const char action = packet.GetChar(); +    switch (action) { +    case 'C': +      thread_action.signal = packet.GetHexMaxU32(false, 0); +      if (thread_action.signal == 0) +        return SendIllFormedResponse( +            packet, "Could not parse signal in vCont packet C action"); +      LLVM_FALLTHROUGH; + +    case 'c': +      // Continue +      thread_action.state = eStateRunning; +      break; + +    case 'S': +      thread_action.signal = packet.GetHexMaxU32(false, 0); +      if (thread_action.signal == 0) +        return SendIllFormedResponse( +            packet, "Could not parse signal in vCont packet S action"); +      LLVM_FALLTHROUGH; + +    case 's': +      // Step +      thread_action.state = eStateStepping; +      break; -    // Ensure we have a native process. -    if (!m_debugged_process_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__); -        return SendErrorResponse (0x36); +    default: +      return SendIllFormedResponse(packet, "Unsupported vCont action"); +      break;      } -    ResumeActionList thread_actions; - -    while (packet.GetBytesLeft () && *packet.Peek () == ';') -    { -        // Skip the semi-colon. -        packet.GetChar (); - -        // Build up the thread action. -        ResumeAction thread_action; -        thread_action.tid = LLDB_INVALID_THREAD_ID; -        thread_action.state = eStateInvalid; -        thread_action.signal = 0; - -        const char action = packet.GetChar (); -        switch (action) -        { -            case 'C': -                thread_action.signal = packet.GetHexMaxU32 (false, 0); -                if (thread_action.signal == 0) -                    return SendIllFormedResponse (packet, "Could not parse signal in vCont packet C action"); -                LLVM_FALLTHROUGH; - -            case 'c': -                // Continue -                thread_action.state = eStateRunning; -                break; - -            case 'S': -                thread_action.signal = packet.GetHexMaxU32 (false, 0); -                if (thread_action.signal == 0) -                    return SendIllFormedResponse (packet, "Could not parse signal in vCont packet S action"); -                LLVM_FALLTHROUGH; - -            case 's': -                // Step -                thread_action.state = eStateStepping; -                break; - -            default: -                return SendIllFormedResponse (packet, "Unsupported vCont action"); -                break; -        } - -        // Parse out optional :{thread-id} value. -        if (packet.GetBytesLeft () && (*packet.Peek () == ':')) -        { -            // Consume the separator. -            packet.GetChar (); - -            thread_action.tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID); -            if (thread_action.tid == LLDB_INVALID_THREAD_ID) -                return SendIllFormedResponse (packet, "Could not parse thread number in vCont packet"); -        } +    // Parse out optional :{thread-id} value. +    if (packet.GetBytesLeft() && (*packet.Peek() == ':')) { +      // Consume the separator. +      packet.GetChar(); -        thread_actions.Append (thread_action); +      thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID); +      if (thread_action.tid == LLDB_INVALID_THREAD_ID) +        return SendIllFormedResponse( +            packet, "Could not parse thread number in vCont packet");      } -    Error error = m_debugged_process_sp->Resume (thread_actions); -    if (error.Fail ()) -    { -        if (log) -        { -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s vCont failed for process %" PRIu64 ": %s", -                         __FUNCTION__, -                         m_debugged_process_sp->GetID (), -                         error.AsCString ()); -        } -        return SendErrorResponse (GDBRemoteServerError::eErrorResume); +    thread_actions.Append(thread_action); +  } + +  Error error = m_debugged_process_sp->Resume(thread_actions); +  if (error.Fail()) { +    if (log) { +      log->Printf("GDBRemoteCommunicationServerLLGS::%s vCont failed for " +                  "process %" PRIu64 ": %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString());      } +    return SendErrorResponse(GDBRemoteServerError::eErrorResume); +  } -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ()); +  if (log) +    log->Printf( +        "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, +        __FUNCTION__, m_debugged_process_sp->GetID()); -    // No response required from vCont. -    return PacketResult::Success; +  // No response required from vCont. +  return PacketResult::Success;  } -void -GDBRemoteCommunicationServerLLGS::SetCurrentThreadID (lldb::tid_t tid) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting current thread id to %" PRIu64, __FUNCTION__, tid); +void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s setting current thread " +                "id to %" PRIu64, +                __FUNCTION__, tid); -    m_current_tid = tid; -    if (m_debugged_process_sp) -        m_debugged_process_sp->SetCurrentThreadID (m_current_tid); +  m_current_tid = tid; +  if (m_debugged_process_sp) +    m_debugged_process_sp->SetCurrentThreadID(m_current_tid);  } -void -GDBRemoteCommunicationServerLLGS::SetContinueThreadID (lldb::tid_t tid) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting continue thread id to %" PRIu64, __FUNCTION__, tid); +void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s setting continue thread " +                "id to %" PRIu64, +                __FUNCTION__, tid); -    m_continue_tid = tid; +  m_continue_tid = tid;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_stop_reason (StringExtractorGDBRemote &packet) -{ -    // Handle the $? gdbremote command. +GDBRemoteCommunicationServerLLGS::Handle_stop_reason( +    StringExtractorGDBRemote &packet) { +  // Handle the $? gdbremote command. -    // If no process, indicate error -    if (!m_debugged_process_sp) -        return SendErrorResponse (02); +  // If no process, indicate error +  if (!m_debugged_process_sp) +    return SendErrorResponse(02); -    return SendStopReasonForState (m_debugged_process_sp->GetState()); +  return SendStopReasonForState(m_debugged_process_sp->GetState());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::SendStopReasonForState (lldb::StateType process_state) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    switch (process_state) -    { -        case eStateAttaching: -        case eStateLaunching: -        case eStateRunning: -        case eStateStepping: -        case eStateDetached: -            // NOTE: gdb protocol doc looks like it should return $OK -            // when everything is running (i.e. no stopped result). -            return PacketResult::Success;  // Ignore - -        case eStateSuspended: -        case eStateStopped: -        case eStateCrashed: -        { -            lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID (); -            // Make sure we set the current thread so g and p packets return -            // the data the gdb will expect. -            SetCurrentThreadID (tid); -            return SendStopReplyPacketForThread (tid); -        } +GDBRemoteCommunicationServerLLGS::SendStopReasonForState( +    lldb::StateType process_state) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + +  switch (process_state) { +  case eStateAttaching: +  case eStateLaunching: +  case eStateRunning: +  case eStateStepping: +  case eStateDetached: +    // NOTE: gdb protocol doc looks like it should return $OK +    // when everything is running (i.e. no stopped result). +    return PacketResult::Success; // Ignore + +  case eStateSuspended: +  case eStateStopped: +  case eStateCrashed: { +    lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID(); +    // Make sure we set the current thread so g and p packets return +    // the data the gdb will expect. +    SetCurrentThreadID(tid); +    return SendStopReplyPacketForThread(tid); +  } -        case eStateInvalid: -        case eStateUnloaded: -        case eStateExited: -            return SendWResponse(m_debugged_process_sp.get()); +  case eStateInvalid: +  case eStateUnloaded: +  case eStateExited: +    return SendWResponse(m_debugged_process_sp.get()); -        default: -            if (log) -            { -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", current state reporting not handled: %s", -                             __FUNCTION__, -                             m_debugged_process_sp->GetID (), -                             StateAsCString (process_state)); -            } -            break; +  default: +    if (log) { +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  ", current state reporting not handled: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  StateAsCString(process_state));      } -     -    return SendErrorResponse (0); +    break; +  } + +  return SendErrorResponse(0);  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo (StringExtractorGDBRemote &packet) -{ -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -        return SendErrorResponse (68); - -    // Ensure we have a thread. -    NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadAtIndex (0)); -    if (!thread_sp) -        return SendErrorResponse (69); - -    // Get the register context for the first thread. -    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ()); -    if (!reg_context_sp) -        return SendErrorResponse (69); - -    // Parse out the register number from the request. -    packet.SetFilePos (strlen("qRegisterInfo")); -    const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ()); -    if (reg_index == std::numeric_limits<uint32_t>::max ()) -        return SendErrorResponse (69); - -    // Return the end of registers response if we've iterated one past the end of the register set. -    if (reg_index >= reg_context_sp->GetUserRegisterCount ()) -        return SendErrorResponse (69); - -    const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index); -    if (!reg_info) -        return SendErrorResponse (69); - -    // Build the reginfos response. -    StreamGDBRemote response; - -    response.PutCString ("name:"); -    response.PutCString (reg_info->name); -    response.PutChar (';'); - -    if (reg_info->alt_name && reg_info->alt_name[0]) -    { -        response.PutCString ("alt-name:"); -        response.PutCString (reg_info->alt_name); -        response.PutChar (';'); -    } - -    response.Printf ("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", reg_info->byte_size * 8, reg_info->byte_offset); - -    switch (reg_info->encoding) -    { -        case eEncodingUint:    response.PutCString ("encoding:uint;"); break; -        case eEncodingSint:    response.PutCString ("encoding:sint;"); break; -        case eEncodingIEEE754: response.PutCString ("encoding:ieee754;"); break; -        case eEncodingVector:  response.PutCString ("encoding:vector;"); break; -        default: break; -    } - -    switch (reg_info->format) -    { -        case eFormatBinary:          response.PutCString ("format:binary;"); break; -        case eFormatDecimal:         response.PutCString ("format:decimal;"); break; -        case eFormatHex:             response.PutCString ("format:hex;"); break; -        case eFormatFloat:           response.PutCString ("format:float;"); break; -        case eFormatVectorOfSInt8:   response.PutCString ("format:vector-sint8;"); break; -        case eFormatVectorOfUInt8:   response.PutCString ("format:vector-uint8;"); break; -        case eFormatVectorOfSInt16:  response.PutCString ("format:vector-sint16;"); break; -        case eFormatVectorOfUInt16:  response.PutCString ("format:vector-uint16;"); break; -        case eFormatVectorOfSInt32:  response.PutCString ("format:vector-sint32;"); break; -        case eFormatVectorOfUInt32:  response.PutCString ("format:vector-uint32;"); break; -        case eFormatVectorOfFloat32: response.PutCString ("format:vector-float32;"); break; -        case eFormatVectorOfUInt128: response.PutCString ("format:vector-uint128;"); break; -        default: break; -    }; - -    const char *const register_set_name = reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index); -    if (register_set_name) -    { -        response.PutCString ("set:"); -        response.PutCString (register_set_name); -        response.PutChar (';'); -    } - -    if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) -        response.Printf ("ehframe:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); - -    if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM) -        response.Printf ("dwarf:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindDWARF]); - -    switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) -    { -        case LLDB_REGNUM_GENERIC_PC:     response.PutCString("generic:pc;"); break; -        case LLDB_REGNUM_GENERIC_SP:     response.PutCString("generic:sp;"); break; -        case LLDB_REGNUM_GENERIC_FP:     response.PutCString("generic:fp;"); break; -        case LLDB_REGNUM_GENERIC_RA:     response.PutCString("generic:ra;"); break; -        case LLDB_REGNUM_GENERIC_FLAGS:  response.PutCString("generic:flags;"); break; -        case LLDB_REGNUM_GENERIC_ARG1:   response.PutCString("generic:arg1;"); break; -        case LLDB_REGNUM_GENERIC_ARG2:   response.PutCString("generic:arg2;"); break; -        case LLDB_REGNUM_GENERIC_ARG3:   response.PutCString("generic:arg3;"); break; -        case LLDB_REGNUM_GENERIC_ARG4:   response.PutCString("generic:arg4;"); break; -        case LLDB_REGNUM_GENERIC_ARG5:   response.PutCString("generic:arg5;"); break; -        case LLDB_REGNUM_GENERIC_ARG6:   response.PutCString("generic:arg6;"); break; -        case LLDB_REGNUM_GENERIC_ARG7:   response.PutCString("generic:arg7;"); break; -        case LLDB_REGNUM_GENERIC_ARG8:   response.PutCString("generic:arg8;"); break; -        default: break; -    } - -    if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) -    { -        response.PutCString ("container-regs:"); -        int i = 0; -        for (const uint32_t *reg_num = reg_info->value_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) -        { -            if (i > 0) -                response.PutChar (','); -            response.Printf ("%" PRIx32, *reg_num); -        } -        response.PutChar (';'); -    } - -    if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) -    { -        response.PutCString ("invalidate-regs:"); -        int i = 0; -        for (const uint32_t *reg_num = reg_info->invalidate_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) -        { -            if (i > 0) -                response.PutChar (','); -            response.Printf ("%" PRIx32, *reg_num); -        } -        response.PutChar (';'); -    } - -    if (reg_info->dynamic_size_dwarf_expr_bytes) -    { -       const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; -       response.PutCString("dynamic_size_dwarf_expr_bytes:"); -       for(uint32_t i = 0; i < dwarf_opcode_len; ++i) -           response.PutHex8 (reg_info->dynamic_size_dwarf_expr_bytes[i]); -       response.PutChar(';'); -    } -    return SendPacketNoLock(response.GetData(), response.GetSize()); +GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( +    StringExtractorGDBRemote &packet) { +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) +    return SendErrorResponse(68); + +  // Ensure we have a thread. +  NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadAtIndex(0)); +  if (!thread_sp) +    return SendErrorResponse(69); + +  // Get the register context for the first thread. +  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); +  if (!reg_context_sp) +    return SendErrorResponse(69); + +  // Parse out the register number from the request. +  packet.SetFilePos(strlen("qRegisterInfo")); +  const uint32_t reg_index = +      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); +  if (reg_index == std::numeric_limits<uint32_t>::max()) +    return SendErrorResponse(69); + +  // Return the end of registers response if we've iterated one past the end of +  // the register set. +  if (reg_index >= reg_context_sp->GetUserRegisterCount()) +    return SendErrorResponse(69); + +  const RegisterInfo *reg_info = +      reg_context_sp->GetRegisterInfoAtIndex(reg_index); +  if (!reg_info) +    return SendErrorResponse(69); + +  // Build the reginfos response. +  StreamGDBRemote response; + +  response.PutCString("name:"); +  response.PutCString(reg_info->name); +  response.PutChar(';'); + +  if (reg_info->alt_name && reg_info->alt_name[0]) { +    response.PutCString("alt-name:"); +    response.PutCString(reg_info->alt_name); +    response.PutChar(';'); +  } + +  response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", +                  reg_info->byte_size * 8, reg_info->byte_offset); + +  switch (reg_info->encoding) { +  case eEncodingUint: +    response.PutCString("encoding:uint;"); +    break; +  case eEncodingSint: +    response.PutCString("encoding:sint;"); +    break; +  case eEncodingIEEE754: +    response.PutCString("encoding:ieee754;"); +    break; +  case eEncodingVector: +    response.PutCString("encoding:vector;"); +    break; +  default: +    break; +  } + +  switch (reg_info->format) { +  case eFormatBinary: +    response.PutCString("format:binary;"); +    break; +  case eFormatDecimal: +    response.PutCString("format:decimal;"); +    break; +  case eFormatHex: +    response.PutCString("format:hex;"); +    break; +  case eFormatFloat: +    response.PutCString("format:float;"); +    break; +  case eFormatVectorOfSInt8: +    response.PutCString("format:vector-sint8;"); +    break; +  case eFormatVectorOfUInt8: +    response.PutCString("format:vector-uint8;"); +    break; +  case eFormatVectorOfSInt16: +    response.PutCString("format:vector-sint16;"); +    break; +  case eFormatVectorOfUInt16: +    response.PutCString("format:vector-uint16;"); +    break; +  case eFormatVectorOfSInt32: +    response.PutCString("format:vector-sint32;"); +    break; +  case eFormatVectorOfUInt32: +    response.PutCString("format:vector-uint32;"); +    break; +  case eFormatVectorOfFloat32: +    response.PutCString("format:vector-float32;"); +    break; +  case eFormatVectorOfUInt64: +    response.PutCString("format:vector-uint64;"); +    break; +  case eFormatVectorOfUInt128: +    response.PutCString("format:vector-uint128;"); +    break; +  default: +    break; +  }; + +  const char *const register_set_name = +      reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index); +  if (register_set_name) { +    response.PutCString("set:"); +    response.PutCString(register_set_name); +    response.PutChar(';'); +  } + +  if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != +      LLDB_INVALID_REGNUM) +    response.Printf("ehframe:%" PRIu32 ";", +                    reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); + +  if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM) +    response.Printf("dwarf:%" PRIu32 ";", +                    reg_info->kinds[RegisterKind::eRegisterKindDWARF]); + +  switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) { +  case LLDB_REGNUM_GENERIC_PC: +    response.PutCString("generic:pc;"); +    break; +  case LLDB_REGNUM_GENERIC_SP: +    response.PutCString("generic:sp;"); +    break; +  case LLDB_REGNUM_GENERIC_FP: +    response.PutCString("generic:fp;"); +    break; +  case LLDB_REGNUM_GENERIC_RA: +    response.PutCString("generic:ra;"); +    break; +  case LLDB_REGNUM_GENERIC_FLAGS: +    response.PutCString("generic:flags;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG1: +    response.PutCString("generic:arg1;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG2: +    response.PutCString("generic:arg2;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG3: +    response.PutCString("generic:arg3;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG4: +    response.PutCString("generic:arg4;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG5: +    response.PutCString("generic:arg5;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG6: +    response.PutCString("generic:arg6;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG7: +    response.PutCString("generic:arg7;"); +    break; +  case LLDB_REGNUM_GENERIC_ARG8: +    response.PutCString("generic:arg8;"); +    break; +  default: +    break; +  } + +  if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { +    response.PutCString("container-regs:"); +    int i = 0; +    for (const uint32_t *reg_num = reg_info->value_regs; +         *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { +      if (i > 0) +        response.PutChar(','); +      response.Printf("%" PRIx32, *reg_num); +    } +    response.PutChar(';'); +  } + +  if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { +    response.PutCString("invalidate-regs:"); +    int i = 0; +    for (const uint32_t *reg_num = reg_info->invalidate_regs; +         *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { +      if (i > 0) +        response.PutChar(','); +      response.Printf("%" PRIx32, *reg_num); +    } +    response.PutChar(';'); +  } + +  if (reg_info->dynamic_size_dwarf_expr_bytes) { +    const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; +    response.PutCString("dynamic_size_dwarf_expr_bytes:"); +    for (uint32_t i = 0; i < dwarf_opcode_len; ++i) +      response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]); +    response.PutChar(';'); +  } +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s() no process (%s), returning OK", __FUNCTION__, m_debugged_process_sp ? "invalid process id" : "null m_debugged_process_sp"); -        return SendOKResponse (); -    } - -    StreamGDBRemote response; -    response.PutChar ('m'); +GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {      if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s() starting thread iteration", __FUNCTION__); - -    NativeThreadProtocolSP thread_sp; -    uint32_t thread_index; -    for (thread_index = 0, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index); -         thread_sp; -         ++thread_index, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32 "(%s, tid=0x%" PRIx64 ")", __FUNCTION__, thread_index, thread_sp ? "is not null" : "null", thread_sp ? thread_sp->GetID () : LLDB_INVALID_THREAD_ID); -        if (thread_index > 0) -            response.PutChar(','); -        response.Printf ("%" PRIx64, thread_sp->GetID ()); -    } - +      log->Printf("GDBRemoteCommunicationServerLLGS::%s() no process (%s), " +                  "returning OK", +                  __FUNCTION__, +                  m_debugged_process_sp ? "invalid process id" +                                        : "null m_debugged_process_sp"); +    return SendOKResponse(); +  } + +  StreamGDBRemote response; +  response.PutChar('m'); + +  if (log) +    log->Printf( +        "GDBRemoteCommunicationServerLLGS::%s() starting thread iteration", +        __FUNCTION__); + +  NativeThreadProtocolSP thread_sp; +  uint32_t thread_index; +  for (thread_index = 0, +      thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index); +       thread_sp; ++thread_index, +      thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index)) {      if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s() finished thread iteration", __FUNCTION__); +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32 +          "(%s, tid=0x%" PRIx64 ")", +          __FUNCTION__, thread_index, thread_sp ? "is not null" : "null", +          thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID); +    if (thread_index > 0) +      response.PutChar(','); +    response.Printf("%" PRIx64, thread_sp->GetID()); +  } + +  if (log) +    log->Printf( +        "GDBRemoteCommunicationServerLLGS::%s() finished thread iteration", +        __FUNCTION__); -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo (StringExtractorGDBRemote &packet) -{ -    // FIXME for now we return the full thread list in the initial packet and always do nothing here. -    return SendPacketNoLock ("l", 1); +GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo( +    StringExtractorGDBRemote &packet) { +  // FIXME for now we return the full thread list in the initial packet and +  // always do nothing here. +  return SendPacketNoLock("l");  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_p (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    // Parse out the register number from the request. -    packet.SetFilePos (strlen("p")); -    const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ()); -    if (reg_index == std::numeric_limits<uint32_t>::max ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ()); -        return SendErrorResponse (0x15); -    } - -    // Get the thread to use. -    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet); -    if (!thread_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Get the thread's register context. -    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ()); -    if (!reg_context_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ()); -        return SendErrorResponse (0x15); -    } - -    // Return the end of registers response if we've iterated one past the end of the register set. -    if (reg_index >= reg_context_sp->GetUserRegisterCount ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ()); -        return SendErrorResponse (0x15); -    } - -    const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index); -    if (!reg_info) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index); -        return SendErrorResponse (0x15); -    } - -    // Build the reginfos response. -    StreamGDBRemote response; - -    // Retrieve the value -    RegisterValue reg_value; -    Error error = reg_context_sp->ReadRegister (reg_info, reg_value); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, read of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ()); -        return SendErrorResponse (0x15); -    } - -    const uint8_t *const data = reinterpret_cast<const uint8_t*> (reg_value.GetBytes ()); -    if (!data) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get data bytes from requested register %" PRIu32, __FUNCTION__, reg_index); -        return SendErrorResponse (0x15); -    } +GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  // Parse out the register number from the request. +  packet.SetFilePos(strlen("p")); +  const uint32_t reg_index = +      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); +  if (reg_index == std::numeric_limits<uint32_t>::max()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not " +                  "parse register number from request \"%s\"", +                  __FUNCTION__, packet.GetStringRef().c_str()); +    return SendErrorResponse(0x15); +  } + +  // Get the thread to use. +  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); +  if (!thread_sp) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no thread available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Get the thread's register context. +  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); +  if (!reg_context_sp) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 +          " failed, no register context available for the thread", +          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID()); +    return SendErrorResponse(0x15); +  } + +  // Return the end of registers response if we've iterated one past the end of +  // the register set. +  if (reg_index >= reg_context_sp->GetUserRegisterCount()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " +                  "register %" PRIu32 " beyond register count %" PRIu32, +                  __FUNCTION__, reg_index, +                  reg_context_sp->GetUserRegisterCount()); +    return SendErrorResponse(0x15); +  } + +  const RegisterInfo *reg_info = +      reg_context_sp->GetRegisterInfoAtIndex(reg_index); +  if (!reg_info) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " +                  "register %" PRIu32 " returned NULL", +                  __FUNCTION__, reg_index); +    return SendErrorResponse(0x15); +  } + +  // Build the reginfos response. +  StreamGDBRemote response; + +  // Retrieve the value +  RegisterValue reg_value; +  Error error = reg_context_sp->ReadRegister(reg_info, reg_value); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of " +                  "requested register %" PRIu32 " (%s) failed: %s", +                  __FUNCTION__, reg_index, reg_info->name, error.AsCString()); +    return SendErrorResponse(0x15); +  } + +  const uint8_t *const data = +      reinterpret_cast<const uint8_t *>(reg_value.GetBytes()); +  if (!data) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data " +                  "bytes from requested register %" PRIu32, +                  __FUNCTION__, reg_index); +    return SendErrorResponse(0x15); +  } -    // FIXME flip as needed to get data in big/little endian format for this host. -    for (uint32_t i = 0; i < reg_value.GetByteSize (); ++i) -        response.PutHex8 (data[i]); +  // FIXME flip as needed to get data in big/little endian format for this host. +  for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i) +    response.PutHex8(data[i]); -    return SendPacketNoLock (response.GetData (), response.GetSize ()); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_P (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    // Ensure there is more content. -    if (packet.GetBytesLeft () < 1) -        return SendIllFormedResponse (packet, "Empty P packet"); - -    // Parse out the register number from the request. -    packet.SetFilePos (strlen("P")); -    const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ()); -    if (reg_index == std::numeric_limits<uint32_t>::max ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ()); -        return SendErrorResponse (0x29); -    } - -    // Note debugserver would send an E30 here. -    if ((packet.GetBytesLeft () < 1) || (packet.GetChar () != '=')) -        return SendIllFormedResponse (packet, "P packet missing '=' char after register number"); - -    // Get process architecture. -    ArchSpec process_arch; -    if (!m_debugged_process_sp || !m_debugged_process_sp->GetArchitecture (process_arch)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to retrieve inferior architecture", __FUNCTION__); -        return SendErrorResponse (0x49); -    } - -    // Parse out the value. -    uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register -    size_t reg_size = packet.GetHexBytesAvail (reg_bytes, sizeof(reg_bytes)); - -    // Get the thread to use. -    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet); -    if (!thread_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available (thread index 0)", __FUNCTION__); -        return SendErrorResponse (0x28); -    } - -    // Get the thread's register context. -    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ()); -    if (!reg_context_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ()); -        return SendErrorResponse (0x15); -    } - -    const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex (reg_index); -    if (!reg_info) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index); -        return SendErrorResponse (0x48); -    } - -    // Return the end of registers response if we've iterated one past the end of the register set. -    if (reg_index >= reg_context_sp->GetUserRegisterCount ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ()); -        return SendErrorResponse (0x47); -    } - -    // The dwarf expression are evaluate on host site -    // which may cause register size to change -    // Hence the reg_size may not be same as reg_info->bytes_size -    if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes)) -    { -        return SendIllFormedResponse (packet, "P packet register size is incorrect"); -    } - -    // Build the reginfos response. -    StreamGDBRemote response; - -    RegisterValue reg_value (reg_bytes, reg_size, process_arch.GetByteOrder ()); -    Error error = reg_context_sp->WriteRegister (reg_info, reg_value); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, write of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ()); -        return SendErrorResponse (0x32); -    } +GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  // Ensure there is more content. +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Empty P packet"); + +  // Parse out the register number from the request. +  packet.SetFilePos(strlen("P")); +  const uint32_t reg_index = +      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); +  if (reg_index == std::numeric_limits<uint32_t>::max()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not " +                  "parse register number from request \"%s\"", +                  __FUNCTION__, packet.GetStringRef().c_str()); +    return SendErrorResponse(0x29); +  } + +  // Note debugserver would send an E30 here. +  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '=')) +    return SendIllFormedResponse( +        packet, "P packet missing '=' char after register number"); + +  // Get process architecture. +  ArchSpec process_arch; +  if (!m_debugged_process_sp || +      !m_debugged_process_sp->GetArchitecture(process_arch)) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve " +                  "inferior architecture", +                  __FUNCTION__); +    return SendErrorResponse(0x49); +  } + +  // Parse out the value. +  uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register +  size_t reg_size = packet.GetHexBytesAvail(reg_bytes); + +  // Get the thread to use. +  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); +  if (!thread_sp) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread " +                  "available (thread index 0)", +                  __FUNCTION__); +    return SendErrorResponse(0x28); +  } + +  // Get the thread's register context. +  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); +  if (!reg_context_sp) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 +          " failed, no register context available for the thread", +          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID()); +    return SendErrorResponse(0x15); +  } + +  const RegisterInfo *reg_info = +      reg_context_sp->GetRegisterInfoAtIndex(reg_index); +  if (!reg_info) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " +                  "register %" PRIu32 " returned NULL", +                  __FUNCTION__, reg_index); +    return SendErrorResponse(0x48); +  } + +  // Return the end of registers response if we've iterated one past the end of +  // the register set. +  if (reg_index >= reg_context_sp->GetUserRegisterCount()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " +                  "register %" PRIu32 " beyond register count %" PRIu32, +                  __FUNCTION__, reg_index, +                  reg_context_sp->GetUserRegisterCount()); +    return SendErrorResponse(0x47); +  } + +  // The dwarf expression are evaluate on host site +  // which may cause register size to change +  // Hence the reg_size may not be same as reg_info->bytes_size +  if ((reg_size != reg_info->byte_size) && +      !(reg_info->dynamic_size_dwarf_expr_bytes)) { +    return SendIllFormedResponse(packet, "P packet register size is incorrect"); +  } + +  // Build the reginfos response. +  StreamGDBRemote response; + +  RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder()); +  Error error = reg_context_sp->WriteRegister(reg_info, reg_value); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of " +                  "requested register %" PRIu32 " (%s) failed: %s", +                  __FUNCTION__, reg_index, reg_info->name, error.AsCString()); +    return SendErrorResponse(0x32); +  } -    return SendOKResponse(); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_H (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Parse out which variant of $H is requested. -    packet.SetFilePos (strlen("H")); -    if (packet.GetBytesLeft () < 1) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, H command missing {g,c} variant", __FUNCTION__); -        return SendIllFormedResponse (packet, "H command missing {g,c} variant"); -    } - -    const char h_variant = packet.GetChar (); -    switch (h_variant) -    { -        case 'g': -            break; - -        case 'c': -            break; - -        default: -            if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", __FUNCTION__, h_variant); -            return SendIllFormedResponse (packet, "H variant unsupported, should be c or g"); -    } - -    // Parse out the thread number. -    // FIXME return a parse success/fail value.  All values are valid here. -    const lldb::tid_t tid = packet.GetHexMaxU64 (false, std::numeric_limits<lldb::tid_t>::max ()); +GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); -    // Ensure we have the given thread when not specifying -1 (all threads) or 0 (any thread). -    if (tid != LLDB_INVALID_THREAD_ID && tid != 0) -    { -        NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid)); -        if (!thread_sp) -        { -            if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 " not found", __FUNCTION__, tid); -            return SendErrorResponse (0x15); -        } -    } +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Parse out which variant of $H is requested. +  packet.SetFilePos(strlen("H")); +  if (packet.GetBytesLeft() < 1) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command " +                  "missing {g,c} variant", +                  __FUNCTION__); +    return SendIllFormedResponse(packet, "H command missing {g,c} variant"); +  } -    // Now switch the given thread type. -    switch (h_variant) -    { -        case 'g': -            SetCurrentThreadID (tid); -            break; +  const char h_variant = packet.GetChar(); +  switch (h_variant) { +  case 'g': +    break; -        case 'c': -            SetContinueThreadID (tid); -            break; +  case 'c': +    break; -        default: -            assert (false && "unsupported $H variant - shouldn't get here"); -            return SendIllFormedResponse (packet, "H variant unsupported, should be c or g"); -    } - -    return SendOKResponse(); +  default: +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", +          __FUNCTION__, h_variant); +    return SendIllFormedResponse(packet, +                                 "H variant unsupported, should be c or g"); +  } + +  // Parse out the thread number. +  // FIXME return a parse success/fail value.  All values are valid here. +  const lldb::tid_t tid = +      packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max()); + +  // Ensure we have the given thread when not specifying -1 (all threads) or 0 +  // (any thread). +  if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { +    NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid)); +    if (!thread_sp) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 +                    " not found", +                    __FUNCTION__, tid); +      return SendErrorResponse(0x15); +    } +  } + +  // Now switch the given thread type. +  switch (h_variant) { +  case 'g': +    SetCurrentThreadID(tid); +    break; + +  case 'c': +    SetContinueThreadID(tid); +    break; + +  default: +    assert(false && "unsupported $H variant - shouldn't get here"); +    return SendIllFormedResponse(packet, +                                 "H variant unsupported, should be c or g"); +  } + +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_I (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); +GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    packet.SetFilePos (::strlen("I")); -    char tmp[4096]; -    for (;;) -    { -        size_t read = packet.GetHexBytesAvail(tmp, sizeof(tmp)); -        if (read == 0) -        { -            break; -        } -        // write directly to stdin *this might block if stdin buffer is full* -        // TODO: enqueue this block in circular buffer and send window size to remote host -        ConnectionStatus status; -        Error error; -        m_stdio_communication.Write(tmp, read, status, &error); -        if (error.Fail()) -        { -            return SendErrorResponse (0x15); -        } +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  packet.SetFilePos(::strlen("I")); +  uint8_t tmp[4096]; +  for (;;) { +    size_t read = packet.GetHexBytesAvail(tmp); +    if (read == 0) { +      break; +    } +    // write directly to stdin *this might block if stdin buffer is full* +    // TODO: enqueue this block in circular buffer and send window size to +    // remote host +    ConnectionStatus status; +    Error error; +    m_stdio_communication.Write(tmp, read, status, &error); +    if (error.Fail()) { +      return SendErrorResponse(0x15);      } +  } -    return SendOKResponse(); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_interrupt (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); - -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Interrupt the process. -    Error error = m_debugged_process_sp->Interrupt (); -    if (error.Fail ()) -    { -        if (log) -        { -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64 ": %s", -                         __FUNCTION__, -                         m_debugged_process_sp->GetID (), -                         error.AsCString ()); -        } -        return SendErrorResponse (GDBRemoteServerError::eErrorResume); -    } +GDBRemoteCommunicationServerLLGS::Handle_interrupt( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {      if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ()); +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Interrupt the process. +  Error error = m_debugged_process_sp->Interrupt(); +  if (error.Fail()) { +    if (log) { +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64 +          ": %s", +          __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString()); +    } +    return SendErrorResponse(GDBRemoteServerError::eErrorResume); +  } + +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64, +                __FUNCTION__, m_debugged_process_sp->GetID()); -    // No response required from stop all. -    return PacketResult::Success; +  // No response required from stop all. +  return PacketResult::Success;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_memory_read(StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Parse out the memory address. -    packet.SetFilePos (strlen("m")); -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short m packet"); - -    // Read the address.  Punting on validation. -    // FIXME replace with Hex U64 read with no default value that fails on failed read. -    const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); - -    // Validate comma. -    if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) -        return SendIllFormedResponse(packet, "Comma sep missing in m packet"); - -    // Get # bytes to read. -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Length missing in m packet"); - -    const uint64_t byte_count = packet.GetHexMaxU64(false, 0); -    if (byte_count == 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to read: zero-length packet", __FUNCTION__); -        return SendOKResponse(); -    } - -    // Allocate the response buffer. -    std::string buf(byte_count, '\0'); -    if (buf.empty()) -        return SendErrorResponse (0x78); - - -    // Retrieve the process memory. -    size_t bytes_read = 0; -    Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(read_addr, &buf[0], byte_count, bytes_read); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to read. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, error.AsCString ()); -        return SendErrorResponse (0x08); -    } +GDBRemoteCommunicationServerLLGS::Handle_memory_read( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    if (bytes_read == 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, byte_count); -        return SendErrorResponse (0x08); -    } - -    StreamGDBRemote response; -    packet.SetFilePos(0); -    char kind = packet.GetChar('?'); -    if (kind == 'x') -        response.PutEscapedBytes(buf.data(), byte_count); -    else -    { -        assert(kind == 'm'); -        for (size_t i = 0; i < bytes_read; ++i) -            response.PutHex8(buf[i]); -    } - -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Parse out the memory address. +  packet.SetFilePos(strlen("m")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Too short m packet"); + +  // Read the address.  Punting on validation. +  // FIXME replace with Hex U64 read with no default value that fails on failed +  // read. +  const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); + +  // Validate comma. +  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) +    return SendIllFormedResponse(packet, "Comma sep missing in m packet"); + +  // Get # bytes to read. +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Length missing in m packet"); + +  const uint64_t byte_count = packet.GetHexMaxU64(false, 0); +  if (byte_count == 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: " +                  "zero-length packet", +                  __FUNCTION__); +    return SendOKResponse(); +  } + +  // Allocate the response buffer. +  std::string buf(byte_count, '\0'); +  if (buf.empty()) +    return SendErrorResponse(0x78); + +  // Retrieve the process memory. +  size_t bytes_read = 0; +  Error error = m_debugged_process_sp->ReadMemoryWithoutTrap( +      read_addr, &buf[0], byte_count, bytes_read); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " mem 0x%" PRIx64 ": failed to read. Error: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), read_addr, +                  error.AsCString()); +    return SendErrorResponse(0x08); +  } + +  if (bytes_read == 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", +                  __FUNCTION__, m_debugged_process_sp->GetID(), read_addr, +                  byte_count); +    return SendErrorResponse(0x08); +  } + +  StreamGDBRemote response; +  packet.SetFilePos(0); +  char kind = packet.GetChar('?'); +  if (kind == 'x') +    response.PutEscapedBytes(buf.data(), byte_count); +  else { +    assert(kind == 'm'); +    for (size_t i = 0; i < bytes_read; ++i) +      response.PutHex8(buf[i]); +  } + +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_M (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Parse out the memory address. -    packet.SetFilePos (strlen("M")); -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short M packet"); - -    // Read the address.  Punting on validation. -    // FIXME replace with Hex U64 read with no default value that fails on failed read. -    const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0); - -    // Validate comma. -    if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) -        return SendIllFormedResponse(packet, "Comma sep missing in M packet"); - -    // Get # bytes to read. -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Length missing in M packet"); +GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    const uint64_t byte_count = packet.GetHexMaxU64(false, 0); -    if (byte_count == 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to write: zero-length packet", __FUNCTION__); -        return PacketResult::Success; -    } - -    // Validate colon. -    if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':')) -        return SendIllFormedResponse(packet, "Comma sep missing in M packet after byte length"); - -    // Allocate the conversion buffer. -    std::vector<uint8_t> buf(byte_count, 0); -    if (buf.empty()) -        return SendErrorResponse (0x78); - -    // Convert the hex memory write contents to bytes. -    StreamGDBRemote response; -    const uint64_t convert_count = packet.GetHexBytes(&buf[0], byte_count, 0); -    if (convert_count != byte_count) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": asked to write %" PRIu64 " bytes, but only found %" PRIu64 " to convert.", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count, convert_count); -        return SendIllFormedResponse (packet, "M content byte length specified did not match hex-encoded content length"); -    } - -    // Write the process memory. -    size_t bytes_written = 0; -    Error error = m_debugged_process_sp->WriteMemory (write_addr, &buf[0], byte_count, bytes_written); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to write. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, error.AsCString ()); -        return SendErrorResponse (0x09); -    } - -    if (bytes_written == 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count); -        return SendErrorResponse (0x09); -    } +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Parse out the memory address. +  packet.SetFilePos(strlen("M")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Too short M packet"); + +  // Read the address.  Punting on validation. +  // FIXME replace with Hex U64 read with no default value that fails on failed +  // read. +  const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0); + +  // Validate comma. +  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) +    return SendIllFormedResponse(packet, "Comma sep missing in M packet"); + +  // Get # bytes to read. +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Length missing in M packet"); + +  const uint64_t byte_count = packet.GetHexMaxU64(false, 0); +  if (byte_count == 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to write: " +                  "zero-length packet", +                  __FUNCTION__); +    return PacketResult::Success; +  } + +  // Validate colon. +  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':')) +    return SendIllFormedResponse( +        packet, "Comma sep missing in M packet after byte length"); + +  // Allocate the conversion buffer. +  std::vector<uint8_t> buf(byte_count, 0); +  if (buf.empty()) +    return SendErrorResponse(0x78); + +  // Convert the hex memory write contents to bytes. +  StreamGDBRemote response; +  const uint64_t convert_count = packet.GetHexBytes(buf, 0); +  if (convert_count != byte_count) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " mem 0x%" PRIx64 ": asked to write %" PRIu64 +                  " bytes, but only found %" PRIu64 " to convert.", +                  __FUNCTION__, m_debugged_process_sp->GetID(), write_addr, +                  byte_count, convert_count); +    return SendIllFormedResponse(packet, "M content byte length specified did " +                                         "not match hex-encoded content " +                                         "length"); +  } + +  // Write the process memory. +  size_t bytes_written = 0; +  Error error = m_debugged_process_sp->WriteMemory(write_addr, &buf[0], +                                                   byte_count, bytes_written); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " mem 0x%" PRIx64 ": failed to write. Error: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), write_addr, +                  error.AsCString()); +    return SendErrorResponse(0x09); +  } + +  if (bytes_written == 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes", +                  __FUNCTION__, m_debugged_process_sp->GetID(), write_addr, +                  byte_count); +    return SendErrorResponse(0x09); +  } -    return SendOKResponse (); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    // Currently only the NativeProcessProtocol knows if it can handle a qMemoryRegionInfoSupported -    // request, but we're not guaranteed to be attached to a process.  For now we'll assume the -    // client only asks this when a process is being debugged. - -    // Ensure we have a process running; otherwise, we can't figure this out -    // since we won't have a NativeProcessProtocol. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } +GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + +  // Currently only the NativeProcessProtocol knows if it can handle a +  // qMemoryRegionInfoSupported +  // request, but we're not guaranteed to be attached to a process.  For now +  // we'll assume the +  // client only asks this when a process is being debugged. + +  // Ensure we have a process running; otherwise, we can't figure this out +  // since we won't have a NativeProcessProtocol. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } -    // Test if we can get any region back when asking for the region around NULL. -    MemoryRegionInfo region_info; -    const Error error = m_debugged_process_sp->GetMemoryRegionInfo (0, region_info); -    if (error.Fail ()) -    { -        // We don't support memory region info collection for this NativeProcessProtocol. -        return SendUnimplementedResponse (""); -    } +  // Test if we can get any region back when asking for the region around NULL. +  MemoryRegionInfo region_info; +  const Error error = +      m_debugged_process_sp->GetMemoryRegionInfo(0, region_info); +  if (error.Fail()) { +    // We don't support memory region info collection for this +    // NativeProcessProtocol. +    return SendUnimplementedResponse(""); +  } -    return SendOKResponse(); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    // Ensure we have a process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Parse out the memory address. -    packet.SetFilePos (strlen("qMemoryRegionInfo:")); -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet"); - -    // Read the address.  Punting on validation. -    const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); +GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    StreamGDBRemote response; - -    // Get the memory region info for the target address. -    MemoryRegionInfo region_info; -    const Error error = m_debugged_process_sp->GetMemoryRegionInfo (read_addr, region_info); -    if (error.Fail ()) -    { -        // Return the error message. - -        response.PutCString ("error:"); -        response.PutCStringAsRawHex8 (error.AsCString ()); -        response.PutChar (';'); -    } -    else -    { -        // Range start and size. -        response.Printf ("start:%" PRIx64 ";size:%" PRIx64 ";", region_info.GetRange ().GetRangeBase (), region_info.GetRange ().GetByteSize ()); - -        // Permissions. -        if (region_info.GetReadable () || -            region_info.GetWritable () || -            region_info.GetExecutable ()) -        { -            // Write permissions info. -            response.PutCString ("permissions:"); - -            if (region_info.GetReadable ()) -                response.PutChar ('r'); -            if (region_info.GetWritable ()) -                response.PutChar('w'); -            if (region_info.GetExecutable()) -                response.PutChar ('x'); - -            response.PutChar (';'); -        } -    } - -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  // Ensure we have a process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Parse out the memory address. +  packet.SetFilePos(strlen("qMemoryRegionInfo:")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet"); + +  // Read the address.  Punting on validation. +  const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); + +  StreamGDBRemote response; + +  // Get the memory region info for the target address. +  MemoryRegionInfo region_info; +  const Error error = +      m_debugged_process_sp->GetMemoryRegionInfo(read_addr, region_info); +  if (error.Fail()) { +    // Return the error message. + +    response.PutCString("error:"); +    response.PutCStringAsRawHex8(error.AsCString()); +    response.PutChar(';'); +  } else { +    // Range start and size. +    response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";", +                    region_info.GetRange().GetRangeBase(), +                    region_info.GetRange().GetByteSize()); + +    // Permissions. +    if (region_info.GetReadable() || region_info.GetWritable() || +        region_info.GetExecutable()) { +      // Write permissions info. +      response.PutCString("permissions:"); + +      if (region_info.GetReadable()) +        response.PutChar('r'); +      if (region_info.GetWritable()) +        response.PutChar('w'); +      if (region_info.GetExecutable()) +        response.PutChar('x'); + +      response.PutChar(';'); +    } + +    // Name +    ConstString name = region_info.GetName(); +    if (name) { +      response.PutCString("name:"); +      response.PutCStringAsRawHex8(name.AsCString()); +      response.PutChar(';'); +    } +  } + +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_Z (StringExtractorGDBRemote &packet) -{ -    // Ensure we have a process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Parse out software or hardware breakpoint or watchpoint requested. -    packet.SetFilePos (strlen("Z")); -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short Z packet, missing software/hardware specifier"); - -    bool want_breakpoint = true; -    bool want_hardware = false; -    uint32_t watch_flags = 0; - -    const GDBStoppointType stoppoint_type = -        GDBStoppointType(packet.GetS32 (eStoppointInvalid)); -    switch (stoppoint_type) -    { -        case eBreakpointSoftware: -            want_hardware = false; want_breakpoint = true;  break; -        case eBreakpointHardware: -            want_hardware = true;  want_breakpoint = true;  break; -        case eWatchpointWrite: -            watch_flags = 1; -            want_hardware = true;  want_breakpoint = false; break; -        case eWatchpointRead: -            watch_flags = 2; -            want_hardware = true;  want_breakpoint = false; break; -        case eWatchpointReadWrite: -            watch_flags = 3; -            want_hardware = true;  want_breakpoint = false; break; -        case eStoppointInvalid: -            return SendIllFormedResponse(packet, "Z packet had invalid software/hardware specifier"); - -    } - -    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',') -        return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type"); - -    // Parse out the stoppoint address. -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short Z packet, missing address"); -    const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); - -    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',') -        return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after address"); - -    // Parse out the stoppoint size (i.e. size hint for opcode size). -    const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ()); -    if (size == std::numeric_limits<uint32_t>::max ()) -        return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse size argument"); - -    if (want_breakpoint) -    { -        // Try to set the breakpoint. -        const Error error = m_debugged_process_sp->SetBreakpoint (addr, size, want_hardware); -        if (error.Success ()) -            return SendOKResponse (); -        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 -                    " failed to set breakpoint: %s", -                    __FUNCTION__, -                    m_debugged_process_sp->GetID (), -                    error.AsCString ()); -        return SendErrorResponse (0x09); -    } -    else -    { -        // Try to set the watchpoint. -        const Error error = m_debugged_process_sp->SetWatchpoint ( -                addr, size, watch_flags, want_hardware); -        if (error.Success ()) -            return SendOKResponse (); -        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 -                    " failed to set watchpoint: %s", -                    __FUNCTION__, -                    m_debugged_process_sp->GetID (), -                    error.AsCString ()); -        return SendErrorResponse (0x09); -    } +GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { +  // Ensure we have a process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Parse out software or hardware breakpoint or watchpoint requested. +  packet.SetFilePos(strlen("Z")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse( +        packet, "Too short Z packet, missing software/hardware specifier"); + +  bool want_breakpoint = true; +  bool want_hardware = false; +  uint32_t watch_flags = 0; + +  const GDBStoppointType stoppoint_type = +      GDBStoppointType(packet.GetS32(eStoppointInvalid)); +  switch (stoppoint_type) { +  case eBreakpointSoftware: +    want_hardware = false; +    want_breakpoint = true; +    break; +  case eBreakpointHardware: +    want_hardware = true; +    want_breakpoint = true; +    break; +  case eWatchpointWrite: +    watch_flags = 1; +    want_hardware = true; +    want_breakpoint = false; +    break; +  case eWatchpointRead: +    watch_flags = 2; +    want_hardware = true; +    want_breakpoint = false; +    break; +  case eWatchpointReadWrite: +    watch_flags = 3; +    want_hardware = true; +    want_breakpoint = false; +    break; +  case eStoppointInvalid: +    return SendIllFormedResponse( +        packet, "Z packet had invalid software/hardware specifier"); +  } + +  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') +    return SendIllFormedResponse( +        packet, "Malformed Z packet, expecting comma after stoppoint type"); + +  // Parse out the stoppoint address. +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Too short Z packet, missing address"); +  const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); + +  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') +    return SendIllFormedResponse( +        packet, "Malformed Z packet, expecting comma after address"); + +  // Parse out the stoppoint size (i.e. size hint for opcode size). +  const uint32_t size = +      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); +  if (size == std::numeric_limits<uint32_t>::max()) +    return SendIllFormedResponse( +        packet, "Malformed Z packet, failed to parse size argument"); + +  if (want_breakpoint) { +    // Try to set the breakpoint. +    const Error error = +        m_debugged_process_sp->SetBreakpoint(addr, size, want_hardware); +    if (error.Success()) +      return SendOKResponse(); +    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " failed to set breakpoint: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x09); +  } else { +    // Try to set the watchpoint. +    const Error error = m_debugged_process_sp->SetWatchpoint( +        addr, size, watch_flags, want_hardware); +    if (error.Success()) +      return SendOKResponse(); +    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " failed to set watchpoint: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x09); +  }  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_z (StringExtractorGDBRemote &packet) -{ -    // Ensure we have a process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    // Parse out software or hardware breakpoint or watchpoint requested. -    packet.SetFilePos (strlen("z")); -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier"); - -    bool want_breakpoint = true; - -    const GDBStoppointType stoppoint_type = -        GDBStoppointType(packet.GetS32 (eStoppointInvalid)); -    switch (stoppoint_type) -    { -        case eBreakpointHardware:  want_breakpoint = true;  break; -        case eBreakpointSoftware:  want_breakpoint = true;  break; -        case eWatchpointWrite:     want_breakpoint = false; break; -        case eWatchpointRead:      want_breakpoint = false; break; -        case eWatchpointReadWrite: want_breakpoint = false; break; -        default: -            return SendIllFormedResponse(packet, "z packet had invalid software/hardware specifier"); - -    } - -    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',') -        return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after stoppoint type"); - -    // Parse out the stoppoint address. -    if (packet.GetBytesLeft() < 1) -        return SendIllFormedResponse(packet, "Too short z packet, missing address"); -    const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); - -    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',') -        return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after address"); - -    /* -    // Parse out the stoppoint size (i.e. size hint for opcode size). -    const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ()); -    if (size == std::numeric_limits<uint32_t>::max ()) -        return SendIllFormedResponse(packet, "Malformed z packet, failed to parse size argument"); -    */ - -    if (want_breakpoint) -    { -        // Try to clear the breakpoint. -        const Error error = m_debugged_process_sp->RemoveBreakpoint (addr); -        if (error.Success ()) -            return SendOKResponse (); -        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 -                    " failed to remove breakpoint: %s", -                    __FUNCTION__, -                    m_debugged_process_sp->GetID (), -                    error.AsCString ()); -        return SendErrorResponse (0x09); -    } -    else -    { -        // Try to clear the watchpoint. -        const Error error = m_debugged_process_sp->RemoveWatchpoint (addr); -        if (error.Success ()) -            return SendOKResponse (); -        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 -                    " failed to remove watchpoint: %s", -                    __FUNCTION__, -                    m_debugged_process_sp->GetID (), -                    error.AsCString ()); -        return SendErrorResponse (0x09); -    } +GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { +  // Ensure we have a process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  // Parse out software or hardware breakpoint or watchpoint requested. +  packet.SetFilePos(strlen("z")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse( +        packet, "Too short z packet, missing software/hardware specifier"); + +  bool want_breakpoint = true; + +  const GDBStoppointType stoppoint_type = +      GDBStoppointType(packet.GetS32(eStoppointInvalid)); +  switch (stoppoint_type) { +  case eBreakpointHardware: +    want_breakpoint = true; +    break; +  case eBreakpointSoftware: +    want_breakpoint = true; +    break; +  case eWatchpointWrite: +    want_breakpoint = false; +    break; +  case eWatchpointRead: +    want_breakpoint = false; +    break; +  case eWatchpointReadWrite: +    want_breakpoint = false; +    break; +  default: +    return SendIllFormedResponse( +        packet, "z packet had invalid software/hardware specifier"); +  } + +  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') +    return SendIllFormedResponse( +        packet, "Malformed z packet, expecting comma after stoppoint type"); + +  // Parse out the stoppoint address. +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, "Too short z packet, missing address"); +  const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); + +  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') +    return SendIllFormedResponse( +        packet, "Malformed z packet, expecting comma after address"); + +  /* +  // Parse out the stoppoint size (i.e. size hint for opcode size). +  const uint32_t size = packet.GetHexMaxU32 (false, +  std::numeric_limits<uint32_t>::max ()); +  if (size == std::numeric_limits<uint32_t>::max ()) +      return SendIllFormedResponse(packet, "Malformed z packet, failed to parse +  size argument"); +  */ + +  if (want_breakpoint) { +    // Try to clear the breakpoint. +    const Error error = m_debugged_process_sp->RemoveBreakpoint(addr); +    if (error.Success()) +      return SendOKResponse(); +    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " failed to remove breakpoint: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x09); +  } else { +    // Try to clear the watchpoint. +    const Error error = m_debugged_process_sp->RemoveWatchpoint(addr); +    if (error.Success()) +      return SendOKResponse(); +    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " failed to remove watchpoint: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x09); +  }  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_s (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD)); - -    // Ensure we have a process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x32); -    } +GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); -    // We first try to use a continue thread id.  If any one or any all set, use the current thread. -    // Bail out if we don't have a thread id. -    lldb::tid_t tid = GetContinueThreadID (); -    if (tid == 0 || tid == LLDB_INVALID_THREAD_ID) -        tid = GetCurrentThreadID (); -    if (tid == LLDB_INVALID_THREAD_ID) -        return SendErrorResponse (0x33); - -    // Double check that we have such a thread. -    // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. -    NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID (tid); -    if (!thread_sp || thread_sp->GetID () != tid) -        return SendErrorResponse (0x33); - -    // Create the step action for the given thread. -    ResumeAction action = { tid, eStateStepping, 0 }; - -    // Setup the actions list. -    ResumeActionList actions; -    actions.Append (action); - -    // All other threads stop while we're single stepping a thread. -    actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); -    Error error = m_debugged_process_sp->Resume (actions); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " Resume() failed with error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), tid, error.AsCString ()); -        return SendErrorResponse(0x49); -    } +  // Ensure we have a process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x32); +  } + +  // We first try to use a continue thread id.  If any one or any all set, use +  // the current thread. +  // Bail out if we don't have a thread id. +  lldb::tid_t tid = GetContinueThreadID(); +  if (tid == 0 || tid == LLDB_INVALID_THREAD_ID) +    tid = GetCurrentThreadID(); +  if (tid == LLDB_INVALID_THREAD_ID) +    return SendErrorResponse(0x33); + +  // Double check that we have such a thread. +  // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. +  NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID(tid); +  if (!thread_sp || thread_sp->GetID() != tid) +    return SendErrorResponse(0x33); + +  // Create the step action for the given thread. +  ResumeAction action = {tid, eStateStepping, 0}; + +  // Setup the actions list. +  ResumeActionList actions; +  actions.Append(action); + +  // All other threads stop while we're single stepping a thread. +  actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); +  Error error = m_debugged_process_sp->Resume(actions); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " tid %" PRIu64 " Resume() failed with error: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), tid, +                  error.AsCString()); +    return SendErrorResponse(0x49); +  } -    // No response here - the stop or exit will come from the resulting action. -    return PacketResult::Success; +  // No response here - the stop or exit will come from the resulting action. +  return PacketResult::Success;  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet) -{ -    // *BSD impls should be able to do this too. +GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read( +    StringExtractorGDBRemote &packet) { +// *BSD impls should be able to do this too.  #if defined(__linux__) -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    // Parse out the offset. -    packet.SetFilePos (strlen("qXfer:auxv:read::")); -    if (packet.GetBytesLeft () < 1) -        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset"); - -    const uint64_t auxv_offset = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ()); -    if (auxv_offset == std::numeric_limits<uint64_t>::max ()) -        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset"); - -    // Parse out comma. -    if (packet.GetBytesLeft () < 1 || packet.GetChar () != ',') -        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing comma after offset"); - -    // Parse out the length. -    const uint64_t auxv_length = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ()); -    if (auxv_length == std::numeric_limits<uint64_t>::max ()) -        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing length"); - -    // Grab the auxv data if we need it. -    if (!m_active_auxv_buffer_sp) -    { -        // Make sure we have a valid process. -        if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -        { -            if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -            return SendErrorResponse (0x10); -        } - -        // Grab the auxv data. -        m_active_auxv_buffer_sp = Host::GetAuxvData (m_debugged_process_sp->GetID ()); -        if (!m_active_auxv_buffer_sp || m_active_auxv_buffer_sp->GetByteSize () ==  0) -        { -            // Hmm, no auxv data, call that an error. -            if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data retrieved", __FUNCTION__); -            m_active_auxv_buffer_sp.reset (); -            return SendErrorResponse (0x11); -        } -    } - -    // FIXME find out if/how I lock the stream here. - -    StreamGDBRemote response; -    bool done_with_buffer = false; - -    if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize ()) -    { -        // We have nothing left to send.  Mark the buffer as complete. -        response.PutChar ('l'); -        done_with_buffer = true; -    } -    else -    { -        // Figure out how many bytes are available starting at the given offset. -        const uint64_t bytes_remaining = m_active_auxv_buffer_sp->GetByteSize () - auxv_offset; - -        // Figure out how many bytes we're going to read. -        const uint64_t bytes_to_read = (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length; - -        // Mark the response type according to whether we're reading the remainder of the auxv data. -        if (bytes_to_read >= bytes_remaining) -        { -            // There will be nothing left to read after this -            response.PutChar ('l'); -            done_with_buffer = true; -        } -        else -        { -            // There will still be bytes to read after this request. -            response.PutChar ('m'); -        } - -        // Now write the data in encoded binary form. -        response.PutEscapedBytes (m_active_auxv_buffer_sp->GetBytes () + auxv_offset, bytes_to_read); -    } - -    if (done_with_buffer) -        m_active_auxv_buffer_sp.reset (); - -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + +  // Parse out the offset. +  packet.SetFilePos(strlen("qXfer:auxv:read::")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse(packet, +                                 "qXfer:auxv:read:: packet missing offset"); + +  const uint64_t auxv_offset = +      packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max()); +  if (auxv_offset == std::numeric_limits<uint64_t>::max()) +    return SendIllFormedResponse(packet, +                                 "qXfer:auxv:read:: packet missing offset"); + +  // Parse out comma. +  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ',') +    return SendIllFormedResponse( +        packet, "qXfer:auxv:read:: packet missing comma after offset"); + +  // Parse out the length. +  const uint64_t auxv_length = +      packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max()); +  if (auxv_length == std::numeric_limits<uint64_t>::max()) +    return SendIllFormedResponse(packet, +                                 "qXfer:auxv:read:: packet missing length"); + +  // Grab the auxv data if we need it. +  if (!m_active_auxv_buffer_sp) { +    // Make sure we have a valid process. +    if (!m_debugged_process_sp || +        (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +      if (log) +        log->Printf( +            "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +            __FUNCTION__); +      return SendErrorResponse(0x10); +    } + +    // Grab the auxv data. +    m_active_auxv_buffer_sp = Host::GetAuxvData(m_debugged_process_sp->GetID()); +    if (!m_active_auxv_buffer_sp || +        m_active_auxv_buffer_sp->GetByteSize() == 0) { +      // Hmm, no auxv data, call that an error. +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data " +                    "retrieved", +                    __FUNCTION__); +      m_active_auxv_buffer_sp.reset(); +      return SendErrorResponse(0x11); +    } +  } + +  // FIXME find out if/how I lock the stream here. + +  StreamGDBRemote response; +  bool done_with_buffer = false; + +  if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize()) { +    // We have nothing left to send.  Mark the buffer as complete. +    response.PutChar('l'); +    done_with_buffer = true; +  } else { +    // Figure out how many bytes are available starting at the given offset. +    const uint64_t bytes_remaining = +        m_active_auxv_buffer_sp->GetByteSize() - auxv_offset; + +    // Figure out how many bytes we're going to read. +    const uint64_t bytes_to_read = +        (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length; + +    // Mark the response type according to whether we're reading the remainder +    // of the auxv data. +    if (bytes_to_read >= bytes_remaining) { +      // There will be nothing left to read after this +      response.PutChar('l'); +      done_with_buffer = true; +    } else { +      // There will still be bytes to read after this request. +      response.PutChar('m'); +    } + +    // Now write the data in encoded binary form. +    response.PutEscapedBytes(m_active_auxv_buffer_sp->GetBytes() + auxv_offset, +                             bytes_to_read); +  } + +  if (done_with_buffer) +    m_active_auxv_buffer_sp.reset(); + +  return SendPacketNoLock(response.GetString());  #else -    return SendUnimplementedResponse ("not implemented on this platform"); +  return SendUnimplementedResponse("not implemented on this platform");  #endif  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    // Move past packet name. -    packet.SetFilePos (strlen ("QSaveRegisterState")); - -    // Get the thread to use. -    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet); -    if (!thread_sp) -    { -        if (m_thread_suffix_supported) -            return SendIllFormedResponse (packet, "No thread specified in QSaveRegisterState packet"); -        else -            return SendIllFormedResponse (packet, "No thread was is set with the Hg packet"); -    } - -    // Grab the register context for the thread. -    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ()); -    if (!reg_context_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ()); -        return SendErrorResponse (0x15); -    } - -    // Save registers to a buffer. -    DataBufferSP register_data_sp; -    Error error = reg_context_sp->ReadAllRegisterValues (register_data_sp); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to save all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ()); -        return SendErrorResponse (0x75); -    } - -    // Allocate a new save id. -    const uint32_t save_id = GetNextSavedRegistersID (); -    assert ((m_saved_registers_map.find (save_id) == m_saved_registers_map.end ()) && "GetNextRegisterSaveID() returned an existing register save id"); +GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  // Move past packet name. +  packet.SetFilePos(strlen("QSaveRegisterState")); + +  // Get the thread to use. +  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); +  if (!thread_sp) { +    if (m_thread_suffix_supported) +      return SendIllFormedResponse( +          packet, "No thread specified in QSaveRegisterState packet"); +    else +      return SendIllFormedResponse(packet, +                                   "No thread was is set with the Hg packet"); +  } -    // Save the register data buffer under the save id. -    { -        std::lock_guard<std::mutex> guard(m_saved_registers_mutex); -        m_saved_registers_map[save_id] = register_data_sp; -    } +  // Grab the register context for the thread. +  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); +  if (!reg_context_sp) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 +          " failed, no register context available for the thread", +          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID()); +    return SendErrorResponse(0x15); +  } + +  // Save registers to a buffer. +  DataBufferSP register_data_sp; +  Error error = reg_context_sp->ReadAllRegisterValues(register_data_sp); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " failed to save all register values: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x75); +  } + +  // Allocate a new save id. +  const uint32_t save_id = GetNextSavedRegistersID(); +  assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) && +         "GetNextRegisterSaveID() returned an existing register save id"); + +  // Save the register data buffer under the save id. +  { +    std::lock_guard<std::mutex> guard(m_saved_registers_mutex); +    m_saved_registers_map[save_id] = register_data_sp; +  } -    // Write the response. -    StreamGDBRemote response; -    response.Printf ("%" PRIu32, save_id); -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  // Write the response. +  StreamGDBRemote response; +  response.Printf("%" PRIu32, save_id); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    // Parse out save id. -    packet.SetFilePos (strlen ("QRestoreRegisterState:")); -    if (packet.GetBytesLeft () < 1) -        return SendIllFormedResponse (packet, "QRestoreRegisterState packet missing register save id"); - -    const uint32_t save_id = packet.GetU32 (0); -    if (save_id == 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState packet has malformed save id, expecting decimal uint32_t", __FUNCTION__); -        return SendErrorResponse (0x76); -    } +GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  // Parse out save id. +  packet.SetFilePos(strlen("QRestoreRegisterState:")); +  if (packet.GetBytesLeft() < 1) +    return SendIllFormedResponse( +        packet, "QRestoreRegisterState packet missing register save id"); + +  const uint32_t save_id = packet.GetU32(0); +  if (save_id == 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState " +                  "packet has malformed save id, expecting decimal uint32_t", +                  __FUNCTION__); +    return SendErrorResponse(0x76); +  } + +  // Get the thread to use. +  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); +  if (!thread_sp) { +    if (m_thread_suffix_supported) +      return SendIllFormedResponse( +          packet, "No thread specified in QRestoreRegisterState packet"); +    else +      return SendIllFormedResponse(packet, +                                   "No thread was is set with the Hg packet"); +  } -    // Get the thread to use. -    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet); -    if (!thread_sp) -    { -        if (m_thread_suffix_supported) -            return SendIllFormedResponse (packet, "No thread specified in QRestoreRegisterState packet"); -        else -            return SendIllFormedResponse (packet, "No thread was is set with the Hg packet"); -    } +  // Grab the register context for the thread. +  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); +  if (!reg_context_sp) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 +          " failed, no register context available for the thread", +          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID()); +    return SendErrorResponse(0x15); +  } + +  // Retrieve register state buffer, then remove from the list. +  DataBufferSP register_data_sp; +  { +    std::lock_guard<std::mutex> guard(m_saved_registers_mutex); -    // Grab the register context for the thread. -    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ()); -    if (!reg_context_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ()); -        return SendErrorResponse (0x15); +    // Find the register set buffer for the given save id. +    auto it = m_saved_registers_map.find(save_id); +    if (it == m_saved_registers_map.end()) { +      if (log) +        log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                    " does not have a register set save buffer for id %" PRIu32, +                    __FUNCTION__, m_debugged_process_sp->GetID(), save_id); +      return SendErrorResponse(0x77);      } +    register_data_sp = it->second; -    // Retrieve register state buffer, then remove from the list. -    DataBufferSP register_data_sp; -    { -        std::lock_guard<std::mutex> guard(m_saved_registers_mutex); - -        // Find the register set buffer for the given save id. -        auto it = m_saved_registers_map.find (save_id); -        if (it == m_saved_registers_map.end ()) -        { -            if (log) -                log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " does not have a register set save buffer for id %" PRIu32, __FUNCTION__, m_debugged_process_sp->GetID (), save_id); -            return SendErrorResponse (0x77); -        } -        register_data_sp = it->second; - -        // Remove it from the map. -        m_saved_registers_map.erase (it); -    } +    // Remove it from the map. +    m_saved_registers_map.erase(it); +  } -    Error error = reg_context_sp->WriteAllRegisterValues (register_data_sp); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to restore all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ()); -        return SendErrorResponse (0x77); -    } +  Error error = reg_context_sp->WriteAllRegisterValues(register_data_sp); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 +                  " failed to restore all register values: %s", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x77); +  } -    return SendOKResponse(); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_vAttach (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    // Consume the ';' after vAttach. -    packet.SetFilePos (strlen ("vAttach")); -    if (!packet.GetBytesLeft () || packet.GetChar () != ';') -        return SendIllFormedResponse (packet, "vAttach missing expected ';'"); - -    // Grab the PID to which we will attach (assume hex encoding). -    lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16); -    if (pid == LLDB_INVALID_PROCESS_ID) -        return SendIllFormedResponse (packet, "vAttach failed to parse the process id"); - -    // Attempt to attach. +GDBRemoteCommunicationServerLLGS::Handle_vAttach( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + +  // Consume the ';' after vAttach. +  packet.SetFilePos(strlen("vAttach")); +  if (!packet.GetBytesLeft() || packet.GetChar() != ';') +    return SendIllFormedResponse(packet, "vAttach missing expected ';'"); + +  // Grab the PID to which we will attach (assume hex encoding). +  lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); +  if (pid == LLDB_INVALID_PROCESS_ID) +    return SendIllFormedResponse(packet, +                                 "vAttach failed to parse the process id"); + +  // Attempt to attach. +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to " +                "pid %" PRIu64, +                __FUNCTION__, pid); + +  Error error = AttachToProcess(pid); + +  if (error.Fail()) {      if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s attempting to attach to pid %" PRIu64, __FUNCTION__, pid); +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to " +                  "pid %" PRIu64 ": %s\n", +                  __FUNCTION__, pid, error.AsCString()); +    return SendErrorResponse(0x01); +  } -    Error error = AttachToProcess (pid); - -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to attach to pid %" PRIu64 ": %s\n", __FUNCTION__, pid, error.AsCString()); -        return SendErrorResponse (0x01); -    } - -    // Notify we attached by sending a stop packet. -    return SendStopReasonForState (m_debugged_process_sp->GetState ()); +  // Notify we attached by sending a stop packet. +  return SendStopReasonForState(m_debugged_process_sp->GetState());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS)); +GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -    StopSTDIOForwarding(); +  StopSTDIOForwarding(); -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__); -        return SendErrorResponse (0x15); -    } - -    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - -    // Consume the ';' after D. -    packet.SetFilePos (1); -    if (packet.GetBytesLeft ()) -    { -        if (packet.GetChar () != ';') -            return SendIllFormedResponse (packet, "D missing expected ';'"); - -        // Grab the PID from which we will detach (assume hex encoding). -        pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16); -        if (pid == LLDB_INVALID_PROCESS_ID) -            return SendIllFormedResponse (packet, "D failed to parse the process id"); -    } +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) { +    if (log) +      log->Printf( +          "GDBRemoteCommunicationServerLLGS::%s failed, no process available", +          __FUNCTION__); +    return SendErrorResponse(0x15); +  } + +  lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + +  // Consume the ';' after D. +  packet.SetFilePos(1); +  if (packet.GetBytesLeft()) { +    if (packet.GetChar() != ';') +      return SendIllFormedResponse(packet, "D missing expected ';'"); + +    // Grab the PID from which we will detach (assume hex encoding). +    pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); +    if (pid == LLDB_INVALID_PROCESS_ID) +      return SendIllFormedResponse(packet, "D failed to parse the process id"); +  } -    if (pid != LLDB_INVALID_PROCESS_ID && -        m_debugged_process_sp->GetID () != pid) -    { -        return SendIllFormedResponse (packet, "Invalid pid"); -    } +  if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_sp->GetID() != pid) { +    return SendIllFormedResponse(packet, "Invalid pid"); +  } -    const Error error = m_debugged_process_sp->Detach (); -    if (error.Fail ()) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to detach from pid %" PRIu64 ": %s\n", -                         __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ()); -        return SendErrorResponse (0x01); -    } +  const Error error = m_debugged_process_sp->Detach(); +  if (error.Fail()) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from " +                  "pid %" PRIu64 ": %s\n", +                  __FUNCTION__, m_debugged_process_sp->GetID(), +                  error.AsCString()); +    return SendErrorResponse(0x01); +  } -    return SendOKResponse (); +  return SendOKResponse();  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo (StringExtractorGDBRemote &packet) -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - -    packet.SetFilePos (strlen("qThreadStopInfo")); -    const lldb::tid_t tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID); -    if (tid == LLDB_INVALID_THREAD_ID) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse thread id from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ()); -        return SendErrorResponse (0x15); -    } -    return SendStopReplyPacketForThread (tid); +GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( +    StringExtractorGDBRemote &packet) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  packet.SetFilePos(strlen("qThreadStopInfo")); +  const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID); +  if (tid == LLDB_INVALID_THREAD_ID) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not " +                  "parse thread id from request \"%s\"", +                  __FUNCTION__, packet.GetStringRef().c_str()); +    return SendErrorResponse(0x15); +  } +  return SendStopReplyPacketForThread(tid);  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo (StringExtractorGDBRemote &) -{ -    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); - -    // Ensure we have a debugged process. -    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) -        return SendErrorResponse (50); - -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64, +GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( +    StringExtractorGDBRemote &) { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); + +  // Ensure we have a debugged process. +  if (!m_debugged_process_sp || +      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) +    return SendErrorResponse(50); + +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid " +                "%" PRIu64,                  __FUNCTION__, m_debugged_process_sp->GetID()); +  StreamString response; +  const bool threads_with_valid_stop_info_only = false; +  JSONArray::SP threads_array_sp = GetJSONThreadsInfo( +      *m_debugged_process_sp, threads_with_valid_stop_info_only); +  if (!threads_array_sp) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a " +                  "packet for pid %" PRIu64, +                  __FUNCTION__, m_debugged_process_sp->GetID()); +    return SendErrorResponse(52); +  } -    StreamString response; -    const bool threads_with_valid_stop_info_only = false; -    JSONArray::SP threads_array_sp = GetJSONThreadsInfo(*m_debugged_process_sp, -                                                        threads_with_valid_stop_info_only); -    if (! threads_array_sp) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a packet for pid %" PRIu64, -                    __FUNCTION__, m_debugged_process_sp->GetID()); -        return SendErrorResponse(52); -    } - -    threads_array_sp->Write(response); -    StreamGDBRemote escaped_response; -    escaped_response.PutEscapedBytes(response.GetData(), response.GetSize()); -    return SendPacketNoLock (escaped_response.GetData(), escaped_response.GetSize()); +  threads_array_sp->Write(response); +  StreamGDBRemote escaped_response; +  escaped_response.PutEscapedBytes(response.GetData(), response.GetSize()); +  return SendPacketNoLock(escaped_response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet) -{ -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || -            m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID) -        return SendErrorResponse (68); - -    packet.SetFilePos(strlen("qWatchpointSupportInfo")); -    if (packet.GetBytesLeft() == 0) -        return SendOKResponse(); -    if (packet.GetChar() != ':') -        return SendErrorResponse(67); +GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( +    StringExtractorGDBRemote &packet) { +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID) +    return SendErrorResponse(68); + +  packet.SetFilePos(strlen("qWatchpointSupportInfo")); +  if (packet.GetBytesLeft() == 0) +    return SendOKResponse(); +  if (packet.GetChar() != ':') +    return SendErrorResponse(67); -    uint32_t num = m_debugged_process_sp->GetMaxWatchpoints(); -    StreamGDBRemote response; -    response.Printf ("num:%d;", num); -    return SendPacketNoLock(response.GetData(), response.GetSize()); +  uint32_t num = m_debugged_process_sp->GetMaxWatchpoints(); +  StreamGDBRemote response; +  response.Printf("num:%d;", num); +  return SendPacketNoLock(response.GetString());  }  GDBRemoteCommunication::PacketResult -GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress (StringExtractorGDBRemote &packet) -{ -    // Fail if we don't have a current process. -    if (!m_debugged_process_sp || -            m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID) -        return SendErrorResponse(67); +GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( +    StringExtractorGDBRemote &packet) { +  // Fail if we don't have a current process. +  if (!m_debugged_process_sp || +      m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID) +    return SendErrorResponse(67); -    packet.SetFilePos(strlen("qFileLoadAddress:")); -    if (packet.GetBytesLeft() == 0) -        return SendErrorResponse(68); +  packet.SetFilePos(strlen("qFileLoadAddress:")); +  if (packet.GetBytesLeft() == 0) +    return SendErrorResponse(68); -    std::string file_name; -    packet.GetHexByteString(file_name); +  std::string file_name; +  packet.GetHexByteString(file_name); -    lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS; -    Error error = m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address); -    if (error.Fail()) -        return SendErrorResponse(69); +  lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS; +  Error error = +      m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address); +  if (error.Fail()) +    return SendErrorResponse(69); -    if (file_load_address == LLDB_INVALID_ADDRESS) -        return SendErrorResponse(1); // File not loaded +  if (file_load_address == LLDB_INVALID_ADDRESS) +    return SendErrorResponse(1); // File not loaded -    StreamGDBRemote response; -    response.PutHex64(file_load_address); -    return SendPacketNoLock(response.GetData(), response.GetSize()); -} - -void -GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection () -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - -    // Tell the stdio connection to shut down. -    if (m_stdio_communication.IsConnected()) -    { -        auto connection = m_stdio_communication.GetConnection(); -        if (connection) -        { -            Error error; -            connection->Disconnect (&error); - -            if (error.Success ()) -            { -                if (log) -                    log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - SUCCESS", __FUNCTION__); -            } -            else -            { -                if (log) -                    log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - FAIL: %s", __FUNCTION__, error.AsCString ()); -            } -        } -    } +  StreamGDBRemote response; +  response.PutHex64(file_load_address); +  return SendPacketNoLock(response.GetString());  } +void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); -NativeThreadProtocolSP -GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix (StringExtractorGDBRemote &packet) -{ -    NativeThreadProtocolSP thread_sp; +  // Tell the stdio connection to shut down. +  if (m_stdio_communication.IsConnected()) { +    auto connection = m_stdio_communication.GetConnection(); +    if (connection) { +      Error error; +      connection->Disconnect(&error); -    // We have no thread if we don't have a process. -    if (!m_debugged_process_sp || m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID) -        return thread_sp; - -    // If the client hasn't asked for thread suffix support, there will not be a thread suffix. -    // Use the current thread in that case. -    if (!m_thread_suffix_supported) -    { -        const lldb::tid_t current_tid = GetCurrentThreadID (); -        if (current_tid == LLDB_INVALID_THREAD_ID) -            return thread_sp; -        else if (current_tid == 0) -        { -            // Pick a thread. -            return m_debugged_process_sp->GetThreadAtIndex (0); -        } -        else -            return m_debugged_process_sp->GetThreadByID (current_tid); +      if (error.Success()) { +        if (log) +          log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process " +                      "terminal stdio - SUCCESS", +                      __FUNCTION__); +      } else { +        if (log) +          log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process " +                      "terminal stdio - FAIL: %s", +                      __FUNCTION__, error.AsCString()); +      }      } +  } +} -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); +NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( +    StringExtractorGDBRemote &packet) { +  NativeThreadProtocolSP thread_sp; -    // Parse out the ';'. -    if (packet.GetBytesLeft () < 1 || packet.GetChar () != ';') -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected ';' prior to start of thread suffix: packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ()); -        return thread_sp; -    } +  // We have no thread if we don't have a process. +  if (!m_debugged_process_sp || +      m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID) +    return thread_sp; -    if (!packet.GetBytesLeft ()) -        return thread_sp; +  // If the client hasn't asked for thread suffix support, there will not be a +  // thread suffix. +  // Use the current thread in that case. +  if (!m_thread_suffix_supported) { +    const lldb::tid_t current_tid = GetCurrentThreadID(); +    if (current_tid == LLDB_INVALID_THREAD_ID) +      return thread_sp; +    else if (current_tid == 0) { +      // Pick a thread. +      return m_debugged_process_sp->GetThreadAtIndex(0); +    } else +      return m_debugged_process_sp->GetThreadByID(current_tid); +  } + +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + +  // Parse out the ';'. +  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " +                  "error: expected ';' prior to start of thread suffix: packet " +                  "contents = '%s'", +                  __FUNCTION__, packet.GetStringRef().c_str()); +    return thread_sp; +  } -    // Parse out thread: portion. -    if (strncmp (packet.Peek (), "thread:", strlen("thread:")) != 0) -    { -        if (log) -            log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not found, packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ()); -        return thread_sp; -    } -    packet.SetFilePos (packet.GetFilePos () + strlen("thread:")); -    const lldb::tid_t tid = packet.GetHexMaxU64(false, 0); -    if (tid != 0) -        return m_debugged_process_sp->GetThreadByID (tid); +  if (!packet.GetBytesLeft()) +    return thread_sp; +  // Parse out thread: portion. +  if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) { +    if (log) +      log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " +                  "error: expected 'thread:' but not found, packet contents = " +                  "'%s'", +                  __FUNCTION__, packet.GetStringRef().c_str());      return thread_sp; +  } +  packet.SetFilePos(packet.GetFilePos() + strlen("thread:")); +  const lldb::tid_t tid = packet.GetHexMaxU64(false, 0); +  if (tid != 0) +    return m_debugged_process_sp->GetThreadByID(tid); + +  return thread_sp;  } -lldb::tid_t -GDBRemoteCommunicationServerLLGS::GetCurrentThreadID () const -{ -    if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) -    { -        // Use whatever the debug process says is the current thread id -        // since the protocol either didn't specify or specified we want -        // any/all threads marked as the current thread. -        if (!m_debugged_process_sp) -            return LLDB_INVALID_THREAD_ID; -        return m_debugged_process_sp->GetCurrentThreadID (); -    } -    // Use the specific current thread id set by the gdb remote protocol. -    return m_current_tid; +lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const { +  if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) { +    // Use whatever the debug process says is the current thread id +    // since the protocol either didn't specify or specified we want +    // any/all threads marked as the current thread. +    if (!m_debugged_process_sp) +      return LLDB_INVALID_THREAD_ID; +    return m_debugged_process_sp->GetCurrentThreadID(); +  } +  // Use the specific current thread id set by the gdb remote protocol. +  return m_current_tid;  } -uint32_t -GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID () -{ -    std::lock_guard<std::mutex> guard(m_saved_registers_mutex); -    return m_next_saved_registers_id++; +uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() { +  std::lock_guard<std::mutex> guard(m_saved_registers_mutex); +  return m_next_saved_registers_id++;  } -void -GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData () -{ -    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|GDBR_LOG_PROCESS)); -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__); +void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { +  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | GDBR_LOG_PROCESS)); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__); -    // Clear any auxv cached data. -    // *BSD impls should be able to do this too. +// Clear any auxv cached data. +// *BSD impls should be able to do this too.  #if defined(__linux__) -    if (log) -        log->Printf ("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer (previously %s)", -                     __FUNCTION__, -                     m_active_auxv_buffer_sp ? "was set" : "was not set"); -    m_active_auxv_buffer_sp.reset (); +  if (log) +    log->Printf("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer " +                "(previously %s)", +                __FUNCTION__, +                m_active_auxv_buffer_sp ? "was set" : "was not set"); +  m_active_auxv_buffer_sp.reset();  #endif  }  FileSpec -GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string& module_path, -                                                 const ArchSpec& arch) -{ -    if (m_debugged_process_sp) -    { -        FileSpec file_spec; -        if (m_debugged_process_sp->GetLoadedModuleFileSpec(module_path.c_str(), file_spec).Success()) -        { -            if (file_spec.Exists()) -                return file_spec; -        } -    } - -    return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch); +GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, +                                                 const ArchSpec &arch) { +  if (m_debugged_process_sp) { +    FileSpec file_spec; +    if (m_debugged_process_sp +            ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) +            .Success()) { +      if (file_spec.Exists()) +        return file_spec; +    } +  } + +  return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);  } | 
