[Lldb-commits] [lldb] r307390 - Add a NativeProcessProtocol Factory class

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri Jul 7 04:02:20 PDT 2017


Author: labath
Date: Fri Jul  7 04:02:19 2017
New Revision: 307390

URL: http://llvm.org/viewvc/llvm-project?rev=307390&view=rev
Log:
Add a NativeProcessProtocol Factory class

Summary:
This replaces the static functions used for creating
NativeProcessProtocol instances with a factory pattern, and modernizes
the interface of the new class in the process -- I use llvm::Expected
instead of the Status+value combo. I also move some of the common code
(like the Delegate registration into the base class). The new
arrangement has multiple benefits:
- it removes the NativeProcess*** dependency from Process/gdb-remote
  (which for example means that liblldb no longer pulls in this code).
- it enables unit testing of the GDBRemoteCommunicationServerLLGS class
  (by providing a mock Native Process).
- serves as another example on how to use the llvm::Expected class (I
  couldn't get rid of the Initialize-type functions completely here
  because of the use of shared_from_this, but that's the next thing on
  my list here)

Tests still pass on Linux and I've made sure NetBSD compiles after this.

Reviewers: zturner, eugene, krytarowski

Subscribers: srhines, lldb-commits, mgorny

Differential Revision: https://reviews.llvm.org/D33778

Modified:
    lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h
    lldb/trunk/source/Host/common/NativeProcessProtocol.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
    lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
    lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
    lldb/trunk/source/Plugins/Process/gdb-remote/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
    lldb/trunk/tools/lldb-server/CMakeLists.txt
    lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp

Modified: lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h (original)
+++ lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h Fri Jul  7 04:02:19 2017
@@ -19,6 +19,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <vector>
 
@@ -244,68 +245,57 @@ public:
   virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
                                     lldb::addr_t &load_addr) = 0;
 
-  //------------------------------------------------------------------
-  /// Launch a process for debugging. This method will create an concrete
-  /// instance of NativeProcessProtocol, based on the host platform.
-  /// (e.g. NativeProcessLinux on linux, etc.)
-  ///
-  /// @param[in] launch_info
-  ///     Information required to launch the process.
-  ///
-  /// @param[in] native_delegate
-  ///     The delegate that will receive messages regarding the
-  ///     inferior.  Must outlive the NativeProcessProtocol
-  ///     instance.
-  ///
-  /// @param[in] mainloop
-  ///     The mainloop instance with which the process can register
-  ///     callbacks. Must outlive the NativeProcessProtocol
-  ///     instance.
-  ///
-  /// @param[out] process_sp
-  ///     On successful return from the method, this parameter
-  ///     contains the shared pointer to the
-  ///     NativeProcessProtocol that can be used to manipulate
-  ///     the native process.
-  ///
-  /// @return
-  ///     An error object indicating if the operation succeeded,
-  ///     and if not, what error occurred.
-  //------------------------------------------------------------------
-  static Status Launch(ProcessLaunchInfo &launch_info,
-                       NativeDelegate &native_delegate, MainLoop &mainloop,
-                       NativeProcessProtocolSP &process_sp);
-
-  //------------------------------------------------------------------
-  /// Attach to an existing process. This method will create an concrete
-  /// instance of NativeProcessProtocol, based on the host platform.
-  /// (e.g. NativeProcessLinux on linux, etc.)
-  ///
-  /// @param[in] pid
-  ///     pid of the process locatable
-  ///
-  /// @param[in] native_delegate
-  ///     The delegate that will receive messages regarding the
-  ///     inferior.  Must outlive the NativeProcessProtocol
-  ///     instance.
-  ///
-  /// @param[in] mainloop
-  ///     The mainloop instance with which the process can register
-  ///     callbacks. Must outlive the NativeProcessProtocol
-  ///     instance.
-  ///
-  /// @param[out] process_sp
-  ///     On successful return from the method, this parameter
-  ///     contains the shared pointer to the
-  ///     NativeProcessProtocol that can be used to manipulate
-  ///     the native process.
-  ///
-  /// @return
-  ///     An error object indicating if the operation succeeded,
-  ///     and if not, what error occurred.
-  //------------------------------------------------------------------
-  static Status Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
-                       MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+  class Factory {
+  public:
+    virtual ~Factory();
+    //------------------------------------------------------------------
+    /// Launch a process for debugging.
+    ///
+    /// @param[in] launch_info
+    ///     Information required to launch the process.
+    ///
+    /// @param[in] native_delegate
+    ///     The delegate that will receive messages regarding the
+    ///     inferior.  Must outlive the NativeProcessProtocol
+    ///     instance.
+    ///
+    /// @param[in] mainloop
+    ///     The mainloop instance with which the process can register
+    ///     callbacks. Must outlive the NativeProcessProtocol
+    ///     instance.
+    ///
+    /// @return
+    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
+    ///     an error object if it failed.
+    //------------------------------------------------------------------
+    virtual llvm::Expected<NativeProcessProtocolSP>
+    Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+           MainLoop &mainloop) const = 0;
+
+    //------------------------------------------------------------------
+    /// Attach to an existing process.
+    ///
+    /// @param[in] pid
+    ///     pid of the process locatable
+    ///
+    /// @param[in] native_delegate
+    ///     The delegate that will receive messages regarding the
+    ///     inferior.  Must outlive the NativeProcessProtocol
+    ///     instance.
+    ///
+    /// @param[in] mainloop
+    ///     The mainloop instance with which the process can register
+    ///     callbacks. Must outlive the NativeProcessProtocol
+    ///     instance.
+    ///
+    /// @return
+    ///     A NativeProcessProtocol shared pointer if the operation succeeded or
+    ///     an error object if it failed.
+    //------------------------------------------------------------------
+    virtual llvm::Expected<NativeProcessProtocolSP>
+    Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+           MainLoop &mainloop) const = 0;
+  };
 
   //------------------------------------------------------------------
   /// StartTracing API for starting a tracing instance with the
@@ -413,10 +403,10 @@ protected:
   lldb::pid_t m_pid;
 
   std::vector<NativeThreadProtocolSP> m_threads;
-  lldb::tid_t m_current_thread_id;
+  lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
   mutable std::recursive_mutex m_threads_mutex;
 
-  lldb::StateType m_state;
+  lldb::StateType m_state = lldb::eStateInvalid;
   mutable std::recursive_mutex m_state_mutex;
 
   llvm::Optional<WaitStatus> m_exit_status;
@@ -427,7 +417,7 @@ protected:
   NativeWatchpointList m_watchpoint_list;
   HardwareBreakpointMap m_hw_breakpoints_map;
   int m_terminal_fd;
-  uint32_t m_stop_id;
+  uint32_t m_stop_id = 0;
 
   // Set of signal numbers that LLDB directly injects back to inferior
   // without stopping it.
@@ -438,7 +428,8 @@ protected:
   // then the process should be attached to. When attaching to a process
   // lldb_private::Host calls should be used to locate the process to attach to,
   // and then this function should be called.
-  NativeProcessProtocol(lldb::pid_t pid);
+  NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
+                        NativeDelegate &delegate);
 
   // -----------------------------------------------------------
   // Internal interface for state handling

Modified: lldb/trunk/source/Host/common/NativeProcessProtocol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/NativeProcessProtocol.cpp?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/NativeProcessProtocol.cpp (original)
+++ lldb/trunk/source/Host/common/NativeProcessProtocol.cpp Fri Jul  7 04:02:19 2017
@@ -29,11 +29,13 @@ using namespace lldb_private;
 // NativeProcessProtocol Members
 // -----------------------------------------------------------------------------
 
-NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid)
-    : m_pid(pid), m_threads(), m_current_thread_id(LLDB_INVALID_THREAD_ID),
-      m_threads_mutex(), m_state(lldb::eStateInvalid), m_state_mutex(),
-      m_delegates_mutex(), m_delegates(), m_breakpoint_list(),
-      m_watchpoint_list(), m_terminal_fd(-1), m_stop_id(0) {}
+NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
+                                             NativeDelegate &delegate)
+    : m_pid(pid), m_terminal_fd(terminal_fd) {
+  bool registered = RegisterNativeDelegate(delegate);
+  assert(registered);
+  (void)registered;
+}
 
 lldb_private::Status NativeProcessProtocol::Interrupt() {
   Status error;
@@ -488,23 +490,4 @@ Status NativeProcessProtocol::ResolvePro
         "failed to retrieve a valid architecture from the exe module");
 }
 
-#if !defined(__linux__) && !defined(__NetBSD__)
-// These need to be implemented to support lldb-gdb-server on a given platform.
-// Stubs are
-// provided to make the rest of the code link on non-supported platforms.
-
-Status NativeProcessProtocol::Launch(ProcessLaunchInfo &launch_info,
-                                     NativeDelegate &native_delegate,
-                                     MainLoop &mainloop,
-                                     NativeProcessProtocolSP &process_sp) {
-  llvm_unreachable("Platform has no NativeProcessProtocol support");
-}
-
-Status NativeProcessProtocol::Attach(lldb::pid_t pid,
-                                     NativeDelegate &native_delegate,
-                                     MainLoop &mainloop,
-                                     NativeProcessProtocolSP &process_sp) {
-  llvm_unreachable("Platform has no NativeProcessProtocol support");
-}
-
-#endif
+NativeProcessProtocol::Factory::~Factory() = default;

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Fri Jul  7 04:02:19 2017
@@ -214,207 +214,122 @@ static Status EnsureFDFlags(int fd, int
 // Public Static Methods
 // -----------------------------------------------------------------------------
 
-Status NativeProcessProtocol::Launch(
-    ProcessLaunchInfo &launch_info,
-    NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
-    NativeProcessProtocolSP &native_process_sp) {
+llvm::Expected<NativeProcessProtocolSP>
+NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
+                                    NativeDelegate &native_delegate,
+                                    MainLoop &mainloop) const {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
-  Status error;
+  MaybeLogLaunchInfo(launch_info);
 
-  // Verify the working directory is valid if one was specified.
-  FileSpec working_dir{launch_info.GetWorkingDirectory()};
-  if (working_dir && (!working_dir.ResolvePath() ||
-                      !llvm::sys::fs::is_directory(working_dir.GetPath()))) {
-    error.SetErrorStringWithFormat("No such file or directory: %s",
-                                   working_dir.GetCString());
-    return error;
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+                    .LaunchProcess(launch_info, status)
+                    .GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+    LLDB_LOG(log, "failed to launch process: {0}", status);
+    return status.ToError();
   }
 
-  // Create the NativeProcessLinux in launch mode.
-  native_process_sp.reset(new NativeProcessLinux());
-
-  if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
-    native_process_sp.reset();
-    error.SetErrorStringWithFormat("failed to register the native delegate");
-    return error;
+  // Wait for the child process to trap on its call to execve.
+  int wstatus;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  (void)wpid;
+  if (!WIFSTOPPED(wstatus)) {
+    LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+             WaitStatus::Decode(wstatus));
+    return llvm::make_error<StringError>("Could not sync with inferior process",
+                                         llvm::inconvertibleErrorCode());
   }
+  LLDB_LOG(log, "inferior started, now in stopped state");
 
-  error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)
-              ->LaunchInferior(mainloop, launch_info);
+  ArchSpec arch;
+  if ((status = ResolveProcessArchitecture(pid, arch)).Fail())
+    return status.ToError();
 
-  if (error.Fail()) {
-    native_process_sp.reset();
-    LLDB_LOG(log, "failed to launch process: {0}", error);
-    return error;
-  }
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+           arch.GetArchitectureName());
 
-  launch_info.SetProcessID(native_process_sp->GetID());
+  status = SetDefaultPtraceOpts(pid);
+  if (status.Fail()) {
+    LLDB_LOG(log, "failed to set default ptrace options: {0}", status);
+    return status.ToError();
+  }
 
-  return error;
+  std::shared_ptr<NativeProcessLinux> process_sp(new NativeProcessLinux(
+      pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
+      arch, mainloop));
+  process_sp->InitializeThreads({pid});
+  return process_sp;
 }
 
-Status NativeProcessProtocol::Attach(
+llvm::Expected<NativeProcessProtocolSP> NativeProcessLinux::Factory::Attach(
     lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
-    MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+    MainLoop &mainloop) const {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
   LLDB_LOG(log, "pid = {0:x}", pid);
 
   // Retrieve the architecture for the running process.
-  ArchSpec process_arch;
-  Status error = ResolveProcessArchitecture(pid, process_arch);
-  if (!error.Success())
-    return error;
-
-  std::shared_ptr<NativeProcessLinux> native_process_linux_sp(
-      new NativeProcessLinux());
-
-  if (!native_process_linux_sp->RegisterNativeDelegate(native_delegate)) {
-    error.SetErrorStringWithFormat("failed to register the native delegate");
-    return error;
-  }
-
-  native_process_linux_sp->AttachToInferior(mainloop, pid, error);
-  if (!error.Success())
-    return error;
-
-  native_process_sp = native_process_linux_sp;
-  return error;
+  ArchSpec arch;
+  Status status = ResolveProcessArchitecture(pid, arch);
+  if (!status.Success())
+    return status.ToError();
+
+  auto tids_or = NativeProcessLinux::Attach(pid);
+  if (!tids_or)
+    return tids_or.takeError();
+
+  std::shared_ptr<NativeProcessLinux> process_sp(
+      new NativeProcessLinux(pid, -1, native_delegate, arch, mainloop));
+  process_sp->InitializeThreads(*tids_or);
+  return process_sp;
 }
 
 // -----------------------------------------------------------------------------
 // Public Instance Methods
 // -----------------------------------------------------------------------------
 
-NativeProcessLinux::NativeProcessLinux()
-    : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
-      m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache(),
-      m_pending_notification_tid(LLDB_INVALID_THREAD_ID),
-      m_pt_proces_trace_id(LLDB_INVALID_UID) {}
-
-void NativeProcessLinux::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
-                                          Status &error) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOG(log, "pid = {0:x}", pid);
+NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
+                                       NativeDelegate &delegate,
+                                       const ArchSpec &arch, MainLoop &mainloop)
+    : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+  if (m_terminal_fd != -1) {
+    Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+    assert(status.Success());
+  }
 
+  Status status;
   m_sigchld_handle = mainloop.RegisterSignal(
-      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
-  if (!m_sigchld_handle)
-    return;
-
-  error = ResolveProcessArchitecture(pid, m_arch);
-  if (!error.Success())
-    return;
-
-  // Set the architecture to the exe architecture.
-  LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
-           m_arch.GetArchitectureName());
-  m_pid = pid;
-  SetState(eStateAttaching);
-
-  Attach(pid, error);
+      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
 }
 
-Status NativeProcessLinux::LaunchInferior(MainLoop &mainloop,
-                                          ProcessLaunchInfo &launch_info) {
-  Status error;
-  m_sigchld_handle = mainloop.RegisterSignal(
-      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
-  if (!m_sigchld_handle)
-    return error;
-
-  SetState(eStateLaunching);
-
-  MaybeLogLaunchInfo(launch_info);
-
-  ::pid_t pid =
-      ProcessLauncherPosixFork().LaunchProcess(launch_info, error).GetProcessId();
-  if (error.Fail())
-    return error;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  // Wait for the child process to trap on its call to execve.
-  ::pid_t wpid;
-  int status;
-  if ((wpid = waitpid(pid, &status, 0)) < 0) {
-    error.SetErrorToErrno();
-    LLDB_LOG(log, "waitpid for inferior failed with %s", error);
-
-    // Mark the inferior as invalid.
-    // FIXME this could really use a new state - eStateLaunchFailure.  For now,
-    // using eStateInvalid.
-    SetState(StateType::eStateInvalid);
-
-    return error;
-  }
-  assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
-         "Could not sync with inferior process.");
-
-  LLDB_LOG(log, "inferior started, now in stopped state");
-  error = SetDefaultPtraceOpts(pid);
-  if (error.Fail()) {
-    LLDB_LOG(log, "failed to set default ptrace options: {0}", error);
-
-    // Mark the inferior as invalid.
-    // FIXME this could really use a new state - eStateLaunchFailure.  For now,
-    // using eStateInvalid.
-    SetState(StateType::eStateInvalid);
-
-    return error;
-  }
-
-  // Release the master terminal descriptor and pass it off to the
-  // NativeProcessLinux instance.  Similarly stash the inferior pid.
-  m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
-  m_pid = pid;
-  launch_info.SetProcessID(pid);
-
-  if (m_terminal_fd != -1) {
-    error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
-    if (error.Fail()) {
-      LLDB_LOG(log,
-               "inferior EnsureFDFlags failed for ensuring terminal "
-               "O_NONBLOCK setting: {0}",
-               error);
-
-      // Mark the inferior as invalid.
-      // FIXME this could really use a new state - eStateLaunchFailure.  For
-      // now, using eStateInvalid.
-      SetState(StateType::eStateInvalid);
-
-      return error;
-    }
+void NativeProcessLinux::InitializeThreads(llvm::ArrayRef<::pid_t> tids) {
+  for (const auto &tid : tids) {
+    NativeThreadLinuxSP thread_sp = AddThread(tid);
+    assert(thread_sp && "AddThread() returned a nullptr thread");
+    thread_sp->SetStoppedBySignal(SIGSTOP);
+    ThreadWasCreated(*thread_sp);
   }
 
-  LLDB_LOG(log, "adding pid = {0}", pid);
-  ResolveProcessArchitecture(m_pid, m_arch);
-  NativeThreadLinuxSP thread_sp = AddThread(pid);
-  assert(thread_sp && "AddThread() returned a nullptr thread");
-  thread_sp->SetStoppedBySignal(SIGSTOP);
-  ThreadWasCreated(*thread_sp);
-
   // Let our process instance know the thread has stopped.
-  SetCurrentThreadID(thread_sp->GetID());
-  SetState(StateType::eStateStopped);
+  SetCurrentThreadID(tids[0]);
+  SetState(StateType::eStateStopped, false);
 
-  if (error.Fail())
-    LLDB_LOG(log, "inferior launching failed {0}", error);
-  return error;
+  // Proccess any signals we received before installing our handler
+  SigchldHandler();
 }
 
-::pid_t NativeProcessLinux::Attach(lldb::pid_t pid, Status &error) {
+llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
+  Status status;
   // Use a map to keep track of the threads which we have attached/need to
   // attach.
   Host::TidMap tids_to_attach;
-  if (pid <= 1) {
-    error.SetErrorToGenericError();
-    error.SetErrorString("Attaching to process 1 is not allowed.");
-    return -1;
-  }
-
   while (Host::FindProcessThreads(pid, tids_to_attach)) {
     for (Host::TidMap::iterator it = tids_to_attach.begin();
          it != tids_to_attach.end();) {
@@ -423,48 +338,36 @@ Status NativeProcessLinux::LaunchInferio
 
         // Attach to the requested process.
         // An attach will cause the thread to stop with a SIGSTOP.
-        error = PtraceWrapper(PTRACE_ATTACH, tid);
-        if (error.Fail()) {
+        if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
           // No such thread. The thread may have exited.
           // More error handling may be needed.
-          if (error.GetError() == ESRCH) {
+          if (status.GetError() == ESRCH) {
             it = tids_to_attach.erase(it);
             continue;
-          } else
-            return -1;
+          }
+          return status.ToError();
         }
 
-        int status;
+        int wpid =
+            llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, nullptr, __WALL);
         // Need to use __WALL otherwise we receive an error with errno=ECHLD
         // At this point we should have a thread stopped if waitpid succeeds.
-        if ((status = waitpid(tid, NULL, __WALL)) < 0) {
+        if (wpid < 0) {
           // No such thread. The thread may have exited.
           // More error handling may be needed.
           if (errno == ESRCH) {
             it = tids_to_attach.erase(it);
             continue;
-          } else {
-            error.SetErrorToErrno();
-            return -1;
           }
+          return llvm::errorCodeToError(
+              std::error_code(errno, std::generic_category()));
         }
 
-        error = SetDefaultPtraceOpts(tid);
-        if (error.Fail())
-          return -1;
+        if ((status = SetDefaultPtraceOpts(tid)).Fail())
+          return status.ToError();
 
         LLDB_LOG(log, "adding tid = {0}", tid);
         it->second = true;
-
-        // Create the thread, mark it as stopped.
-        NativeThreadLinuxSP thread_sp(AddThread(static_cast<lldb::tid_t>(tid)));
-        assert(thread_sp && "AddThread() returned a nullptr");
-
-        // This will notify this is a new thread and tell the system it is
-        // stopped.
-        thread_sp->SetStoppedBySignal(SIGSTOP);
-        ThreadWasCreated(*thread_sp);
-        SetCurrentThreadID(thread_sp->GetID());
       }
 
       // move the loop forward
@@ -472,17 +375,16 @@ Status NativeProcessLinux::LaunchInferio
     }
   }
 
-  if (tids_to_attach.size() > 0) {
-    m_pid = pid;
-    // Let our process instance know the thread has stopped.
-    SetState(StateType::eStateStopped);
-  } else {
-    error.SetErrorToGenericError();
-    error.SetErrorString("No such process.");
-    return -1;
-  }
-
-  return pid;
+  size_t tid_count = tids_to_attach.size();
+  if (tid_count == 0)
+    return llvm::make_error<StringError>("No such process",
+                                         llvm::inconvertibleErrorCode());
+
+  std::vector<::pid_t> tids;
+  tids.reserve(tid_count);
+  for (const auto &p : tids_to_attach)
+    tids.push_back(p.first);
+  return std::move(tids);
 }
 
 Status NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h Fri Jul  7 04:02:19 2017
@@ -39,15 +39,18 @@ namespace process_linux {
 ///
 /// Changes in the inferior process state are broadcasted.
 class NativeProcessLinux : public NativeProcessProtocol {
-  friend Status NativeProcessProtocol::Launch(
-      ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
-      MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
-
-  friend Status NativeProcessProtocol::Attach(
-      lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
-      MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
-
 public:
+  class Factory : public NativeProcessProtocol::Factory {
+  public:
+    llvm::Expected<NativeProcessProtocolSP>
+    Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+           MainLoop &mainloop) const override;
+
+    llvm::Expected<NativeProcessProtocolSP>
+    Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+           MainLoop &mainloop) const override;
+  };
+
   // ---------------------------------------------------------------------
   // NativeProcessProtocol Interface
   // ---------------------------------------------------------------------
@@ -144,10 +147,10 @@ private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
 
-  LazyBool m_supports_mem_region;
+  LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 
-  lldb::tid_t m_pending_notification_tid;
+  lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
 
   // List of thread ids stepping with a breakpoint with the address of
   // the relevan breakpoint
@@ -156,19 +159,15 @@ private:
   // ---------------------------------------------------------------------
   // Private Instance Methods
   // ---------------------------------------------------------------------
-  NativeProcessLinux();
-
-  Status LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
-
-  /// Attaches to an existing process.  Forms the
-  /// implementation of Process::DoAttach
-  void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
+  NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
+                     const ArchSpec &arch, MainLoop &mainloop);
 
-  ::pid_t Attach(lldb::pid_t pid, Status &error);
+  // Returns a list of process threads that we have attached to.
+  static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
 
   static Status SetDefaultPtraceOpts(const lldb::pid_t);
 
-  static void *MonitorThread(void *baton);
+  void InitializeThreads(llvm::ArrayRef<::pid_t> tids);
 
   void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
 
@@ -280,7 +279,7 @@ private:
   // same process user id.
   llvm::DenseSet<lldb::tid_t> m_pt_traced_thread_group;
 
-  lldb::user_id_t m_pt_proces_trace_id;
+  lldb::user_id_t m_pt_proces_trace_id = LLDB_INVALID_UID;
   TraceOptions m_pt_process_trace_config;
 };
 

Modified: lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp (original)
+++ lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp Fri Jul  7 04:02:19 2017
@@ -64,81 +64,101 @@ static Status EnsureFDFlags(int fd, int
 // Public Static Methods
 // -----------------------------------------------------------------------------
 
-Status NativeProcessProtocol::Launch(
-    ProcessLaunchInfo &launch_info,
-    NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
-    NativeProcessProtocolSP &native_process_sp) {
+llvm::Expected<NativeProcessProtocolSP>
+NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
+                                     NativeDelegate &native_delegate,
+                                     MainLoop &mainloop) const {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
-  Status error;
+  Status status;
+  ::pid_t pid = ProcessLauncherPosixFork()
+                    .LaunchProcess(launch_info, status)
+                    .GetProcessId();
+  LLDB_LOG(log, "pid = {0:x}", pid);
+  if (status.Fail()) {
+    LLDB_LOG(log, "failed to launch process: {0}", status);
+    return status.ToError();
+  }
 
-  // Verify the working directory is valid if one was specified.
-  FileSpec working_dir{launch_info.GetWorkingDirectory()};
-  if (working_dir && (!working_dir.ResolvePath() ||
-                      !llvm::sys::fs::is_directory(working_dir.GetPath()))) {
-    error.SetErrorStringWithFormat("No such file or directory: %s",
-                                   working_dir.GetCString());
-    return error;
+  // Wait for the child process to trap on its call to execve.
+  int wstatus;
+  ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+  assert(wpid == pid);
+  (void)wpid;
+  if (!WIFSTOPPED(wstatus)) {
+    LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+             WaitStatus::Decode(wstatus));
+    return llvm::make_error<StringError>("Could not sync with inferior process",
+                                         llvm::inconvertibleErrorCode());
   }
+  LLDB_LOG(log, "inferior started, now in stopped state");
 
-  // Create the NativeProcessNetBSD in launch mode.
-  native_process_sp.reset(new NativeProcessNetBSD());
+  ArchSpec arch;
+  if ((status = ResolveProcessArchitecture(pid, arch)).Fail())
+    return status.ToError();
 
-  if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
-    native_process_sp.reset();
-    error.SetErrorStringWithFormat("failed to register the native delegate");
-    return error;
-  }
+  // Set the architecture to the exe architecture.
+  LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+           arch.GetArchitectureName());
 
-  error = std::static_pointer_cast<NativeProcessNetBSD>(native_process_sp)
-              ->LaunchInferior(mainloop, launch_info);
+  std::shared_ptr<NativeProcessNetBSD> process_sp(new NativeProcessNetBSD(
+      pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
+      arch, mainloop));
 
-  if (error.Fail()) {
-    native_process_sp.reset();
-    LLDB_LOG(log, "failed to launch process: {0}", error);
-    return error;
-  }
+  status = process_sp->ReinitializeThreads();
+  if (status.Fail())
+    return status.ToError();
 
-  launch_info.SetProcessID(native_process_sp->GetID());
+  for (const auto &thread_sp : process_sp->m_threads) {
+    static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+        SIGSTOP);
+  }
+  process_sp->SetState(StateType::eStateStopped);
 
-  return error;
+  return process_sp;
 }
 
-Status NativeProcessProtocol::Attach(
+llvm::Expected<NativeProcessProtocolSP> NativeProcessNetBSD::Factory::Attach(
     lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
-    MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+    MainLoop &mainloop) const {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
   LLDB_LOG(log, "pid = {0:x}", pid);
 
   // Retrieve the architecture for the running process.
-  ArchSpec process_arch;
-  Status error = ResolveProcessArchitecture(pid, process_arch);
-  if (!error.Success())
-    return error;
-
-  std::shared_ptr<NativeProcessNetBSD> native_process_netbsd_sp(
-      new NativeProcessNetBSD());
-
-  if (!native_process_netbsd_sp->RegisterNativeDelegate(native_delegate)) {
-    error.SetErrorStringWithFormat("failed to register the native delegate");
-    return error;
-  }
-
-  native_process_netbsd_sp->AttachToInferior(mainloop, pid, error);
-  if (!error.Success())
-    return error;
+  ArchSpec arch;
+  Status status = ResolveProcessArchitecture(pid, arch);
+  if (!status.Success())
+    return status.ToError();
+
+  std::shared_ptr<NativeProcessNetBSD> process_sp(
+      new NativeProcessNetBSD(pid, -1, native_delegate, arch, mainloop));
+
+  status = process_sp->Attach();
+  if (!status.Success())
+    return status.ToError();
 
-  native_process_sp = native_process_netbsd_sp;
-  return error;
+  return process_sp;
 }
 
 // -----------------------------------------------------------------------------
 // Public Instance Methods
 // -----------------------------------------------------------------------------
 
-NativeProcessNetBSD::NativeProcessNetBSD()
-    : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
-      m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache() {}
+NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
+                                         NativeDelegate &delegate,
+                                         const ArchSpec &arch,
+                                         MainLoop &mainloop)
+    : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+  if (m_terminal_fd != -1) {
+    Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+    assert(status.Success());
+  }
+
+  Status status;
+  m_sigchld_handle = mainloop.RegisterSignal(
+      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+  assert(m_sigchld_handle && status.Success());
+}
 
 // Handles all waitpid events from the inferior process.
 void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) {
@@ -710,113 +730,6 @@ Status NativeProcessNetBSD::GetFileLoadA
   return Status();
 }
 
-Status NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
-                                           ProcessLaunchInfo &launch_info) {
-  Status error;
-  m_sigchld_handle = mainloop.RegisterSignal(
-      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
-  if (!m_sigchld_handle)
-    return error;
-
-  SetState(eStateLaunching);
-
-  ::pid_t pid = ProcessLauncherPosixFork()
-                    .LaunchProcess(launch_info, error)
-                    .GetProcessId();
-  if (error.Fail())
-    return error;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  // Wait for the child process to trap on its call to execve.
-  ::pid_t wpid;
-  int status;
-  if ((wpid = waitpid(pid, &status, 0)) < 0) {
-    error.SetErrorToErrno();
-    LLDB_LOG(log, "waitpid for inferior failed with %s", error);
-
-    // Mark the inferior as invalid.
-    // FIXME this could really use a new state - eStateLaunchFailure.  For
-    // now, using eStateInvalid.
-    SetState(StateType::eStateInvalid);
-
-    return error;
-  }
-  assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
-         "Could not sync with inferior process.");
-
-  LLDB_LOG(log, "inferior started, now in stopped state");
-
-  // Release the master terminal descriptor and pass it off to the
-  // NativeProcessNetBSD instance.  Similarly stash the inferior pid.
-  m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
-  m_pid = pid;
-  launch_info.SetProcessID(pid);
-
-  if (m_terminal_fd != -1) {
-    error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
-    if (error.Fail()) {
-      LLDB_LOG(log,
-               "inferior EnsureFDFlags failed for ensuring terminal "
-               "O_NONBLOCK setting: {0}",
-               error);
-
-      // Mark the inferior as invalid.
-      // FIXME this could really use a new state - eStateLaunchFailure.  For
-      // now, using eStateInvalid.
-      SetState(StateType::eStateInvalid);
-
-      return error;
-    }
-  }
-
-  LLDB_LOG(log, "adding pid = {0}", pid);
-
-  ResolveProcessArchitecture(m_pid, m_arch);
-
-  error = ReinitializeThreads();
-  if (error.Fail()) {
-    SetState(StateType::eStateInvalid);
-    return error;
-  }
-
-  for (const auto &thread_sp : m_threads) {
-    static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
-        SIGSTOP);
-  }
-
-  /* Set process stopped */
-  SetState(StateType::eStateStopped);
-
-  if (error.Fail())
-    LLDB_LOG(log, "inferior launching failed {0}", error);
-  return error;
-}
-
-void NativeProcessNetBSD::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
-                                           Status &error) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOG(log, "pid = {0:x}", pid);
-
-  m_sigchld_handle = mainloop.RegisterSignal(
-      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
-  if (!m_sigchld_handle)
-    return;
-
-  error = ResolveProcessArchitecture(pid, m_arch);
-  if (!error.Success())
-    return;
-
-  // Set the architecture to the exe architecture.
-  LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
-           m_arch.GetArchitectureName());
-
-  m_pid = pid;
-  SetState(eStateAttaching);
-
-  Attach(pid, error);
-}
-
 void NativeProcessNetBSD::SigchldHandler() {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
   // Process all pending waitpid notifications.
@@ -879,33 +792,23 @@ NativeThreadNetBSDSP NativeProcessNetBSD
   return thread_sp;
 }
 
-::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Status &error) {
-  if (pid <= 1) {
-    error.SetErrorToGenericError();
-    error.SetErrorString("Attaching to process 1 is not allowed.");
-    return -1;
-  }
-
+Status NativeProcessNetBSD::Attach() {
   // Attach to the requested process.
   // An attach will cause the thread to stop with a SIGSTOP.
-  error = PtraceWrapper(PT_ATTACH, pid);
-  if (error.Fail())
-    return -1;
+  Status status = PtraceWrapper(PT_ATTACH, m_pid);
+  if (status.Fail())
+    return status;
 
-  int status;
+  int wstatus;
   // Need to use WALLSIG otherwise we receive an error with errno=ECHLD
   // At this point we should have a thread stopped if waitpid succeeds.
-  if ((status = waitpid(pid, NULL, WALLSIG)) < 0)
-    return -1;
-
-  m_pid = pid;
+  if ((wstatus = waitpid(m_pid, NULL, WALLSIG)) < 0)
+    return Status(errno, eErrorTypePOSIX);
 
   /* Initialize threads */
-  error = ReinitializeThreads();
-  if (error.Fail()) {
-    SetState(StateType::eStateInvalid);
-    return -1;
-  }
+  status = ReinitializeThreads();
+  if (status.Fail())
+    return status;
 
   for (const auto &thread_sp : m_threads) {
     static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
@@ -914,8 +817,7 @@ NativeThreadNetBSDSP NativeProcessNetBSD
 
   // Let our process instance know the thread has stopped.
   SetState(StateType::eStateStopped);
-
-  return pid;
+  return Status();
 }
 
 Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf,

Modified: lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h (original)
+++ lldb/trunk/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h Fri Jul  7 04:02:19 2017
@@ -31,15 +31,18 @@ namespace process_netbsd {
 ///
 /// Changes in the inferior process state are broadcasted.
 class NativeProcessNetBSD : public NativeProcessProtocol {
-  friend Status NativeProcessProtocol::Launch(
-      ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
-      MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
-
-  friend Status NativeProcessProtocol::Attach(
-      lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
-      MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
-
 public:
+  class Factory : public NativeProcessProtocol::Factory {
+  public:
+    llvm::Expected<NativeProcessProtocolSP>
+    Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+           MainLoop &mainloop) const override;
+
+    llvm::Expected<NativeProcessProtocolSP>
+    Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+           MainLoop &mainloop) const override;
+  };
+
   // ---------------------------------------------------------------------
   // NativeProcessProtocol Interface
   // ---------------------------------------------------------------------
@@ -107,21 +110,19 @@ protected:
 private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
-  LazyBool m_supports_mem_region;
+  LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 
   // ---------------------------------------------------------------------
   // Private Instance Methods
   // ---------------------------------------------------------------------
-  NativeProcessNetBSD();
+  NativeProcessNetBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
+                      const ArchSpec &arch, MainLoop &mainloop);
 
   bool HasThreadNoLock(lldb::tid_t thread_id);
 
   NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id);
 
-  Status LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
-  void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
-
   void MonitorCallback(lldb::pid_t pid, int signal);
   void MonitorExited(lldb::pid_t pid, WaitStatus status);
   void MonitorSIGSTOP(lldb::pid_t pid);
@@ -133,8 +134,7 @@ private:
   Status PopulateMemoryRegionCache();
   void SigchldHandler();
 
-  ::pid_t Attach(lldb::pid_t pid, Status &error);
-
+  Status Attach();
   Status ReinitializeThreads();
 };
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/CMakeLists.txt?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/CMakeLists.txt Fri Jul  7 04:02:19 2017
@@ -7,14 +7,6 @@ set(LLDB_PLUGINS
   lldbPluginPlatformMacOSX
 )
 
-if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
-  list(APPEND LLDB_PLUGINS lldbPluginProcessLinux)
-endif()
-
-if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
-  list(APPEND LLDB_PLUGINS lldbPluginProcessNetBSD)
-endif()
-
 add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
   GDBRemoteClientBase.cpp
   GDBRemoteCommunication.cpp

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp Fri Jul  7 04:02:19 2017
@@ -1046,14 +1046,9 @@ GDBRemoteCommunicationServerCommon::Hand
 
   if (success) {
     m_process_launch_error = LaunchProcess();
-    if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+    if (m_process_launch_error.Success())
       return SendOKResponse();
-    } else {
-      Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-      if (log)
-        log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
-                    __FUNCTION__, m_process_launch_error.AsCString());
-    }
+    LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
   }
   return SendErrorResponse(8);
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Fri Jul  7 04:02:19 2017
@@ -73,15 +73,11 @@ enum GDBRemoteServerError {
 // GDBRemoteCommunicationServerLLGS constructor
 //----------------------------------------------------------------------
 GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
-    MainLoop &mainloop)
+    MainLoop &mainloop, const NativeProcessProtocol::Factory &process_factory)
     : 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_saved_registers_map(), m_next_saved_registers_id(1),
-      m_handshake_completed(false) {
+      m_mainloop(mainloop), m_process_factory(process_factory),
+      m_stdio_communication("process.stdio") {
   RegisterPacketHandlers();
 }
 
@@ -241,19 +237,20 @@ Status GDBRemoteCommunicationServerLLGS:
   const bool default_to_use_pty = true;
   m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
 
-  Status 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;
+    auto process_or =
+        m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
+    if (!process_or) {
+      Status status(process_or.takeError());
+      llvm::errs() << llvm::formatv(
+          "failed to launch executable `{0}`: {1}",
+          m_process_launch_info.GetArguments().GetArgumentAtIndex(0), status);
+      return status;
+    }
+    m_debugged_process_sp = *process_or;
   }
 
   // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
@@ -279,9 +276,9 @@ Status GDBRemoteCommunicationServerLLGS:
         log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
                     "inferior STDIO fd to %d",
                     __FUNCTION__, terminal_fd);
-      error = SetSTDIOFileDescriptor(terminal_fd);
-      if (error.Fail())
-        return error;
+      Status status = SetSTDIOFileDescriptor(terminal_fd);
+      if (status.Fail())
+        return status;
     } else {
       if (log)
         log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
@@ -298,14 +295,12 @@ Status GDBRemoteCommunicationServerLLGS:
 
   printf("Launched '%s' as process %" PRIu64 "...\n",
          m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
-         m_process_launch_info.GetProcessID());
+         m_debugged_process_sp->GetID());
 
-  return error;
+  return Status();
 }
 
 Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
-  Status error;
-
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
   if (log)
     log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
@@ -321,13 +316,14 @@ Status GDBRemoteCommunicationServerLLGS:
                   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;
+  auto process_or = m_process_factory.Attach(pid, *this, m_mainloop);
+  if (!process_or) {
+    Status status(process_or.takeError());
+    llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}", pid,
+                                  status);
+    return status;
   }
+  m_debugged_process_sp = *process_or;
 
   // Setup stdout/stderr mapping from inferior.
   auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
@@ -336,9 +332,9 @@ Status GDBRemoteCommunicationServerLLGS:
       log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
                   "inferior STDIO fd to %d",
                   __FUNCTION__, terminal_fd);
-    error = SetSTDIOFileDescriptor(terminal_fd);
-    if (error.Fail())
-      return error;
+    Status status = SetSTDIOFileDescriptor(terminal_fd);
+    if (status.Fail())
+      return status;
   } else {
     if (log)
       log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
@@ -347,8 +343,7 @@ Status GDBRemoteCommunicationServerLLGS:
   }
 
   printf("Attached to process %" PRIu64 "...\n", pid);
-
-  return error;
+  return Status();
 }
 
 void GDBRemoteCommunicationServerLLGS::InitializeDelegate(

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h Fri Jul  7 04:02:19 2017
@@ -39,7 +39,9 @@ public:
   //------------------------------------------------------------------
   // Constructors and Destructors
   //------------------------------------------------------------------
-  GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
+  GDBRemoteCommunicationServerLLGS(
+      MainLoop &mainloop,
+      const NativeProcessProtocol::Factory &process_factory);
 
   //------------------------------------------------------------------
   /// Specify the program to launch and its arguments.
@@ -108,20 +110,21 @@ public:
 protected:
   MainLoop &m_mainloop;
   MainLoop::ReadHandleUP m_network_handle_up;
-  lldb::tid_t m_current_tid;
-  lldb::tid_t m_continue_tid;
+  const NativeProcessProtocol::Factory &m_process_factory;
+  lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID;
+  lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID;
   std::recursive_mutex m_debugged_process_mutex;
   NativeProcessProtocolSP m_debugged_process_sp;
 
   Communication m_stdio_communication;
   MainLoop::ReadHandleUP m_stdio_handle_up;
 
-  lldb::StateType m_inferior_prev_state;
+  lldb::StateType m_inferior_prev_state = lldb::StateType::eStateInvalid;
   std::unique_ptr<llvm::MemoryBuffer> m_active_auxv_buffer_up;
   std::mutex m_saved_registers_mutex;
   std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
-  uint32_t m_next_saved_registers_id;
-  bool m_handshake_completed : 1;
+  uint32_t m_next_saved_registers_id = 1;
+  bool m_handshake_completed = false;
 
   PacketResult SendONotification(const char *buffer, uint32_t len);
 

Modified: lldb/trunk/tools/lldb-server/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/CMakeLists.txt?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-server/CMakeLists.txt (original)
+++ lldb/trunk/tools/lldb-server/CMakeLists.txt Fri Jul  7 04:02:19 2017
@@ -59,6 +59,16 @@ if (LLVM_BUILD_STATIC)
   endif()
 endif()
 
+set(LLDB_PLUGINS)
+
+if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
+  list(APPEND LLDB_PLUGINS lldbPluginProcessLinux)
+endif()
+
+if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+  list(APPEND LLDB_PLUGINS lldbPluginProcessNetBSD)
+endif()
+
 add_lldb_tool(lldb-server INCLUDE_IN_FRAMEWORK
     Acceptor.cpp
     lldb-gdbserver.cpp
@@ -72,7 +82,7 @@ add_lldb_tool(lldb-server INCLUDE_IN_FRA
       lldbHost
       lldbInitialization
       lldbInterpreter
-      ${EXTRA_LLDB_LIBS}
+      ${LLDB_PLUGINS}
       ${LLDB_SYSTEM_LIBS}
 
     LINK_COMPONENTS

Modified: lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp?rev=307390&r1=307389&r2=307390&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp (original)
+++ lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp Fri Jul  7 04:02:19 2017
@@ -33,10 +33,17 @@
 #include "lldb/Host/Pipe.h"
 #include "lldb/Host/Socket.h"
 #include "lldb/Host/StringConvert.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
 #include "lldb/Utility/Status.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errno.h"
 
+#if defined(__linux__)
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#elif defined(__NetBSD__)
+#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h"
+#endif
+
 #ifndef LLGS_PROGRAM_NAME
 #define LLGS_PROGRAM_NAME "lldb-server"
 #endif
@@ -51,6 +58,30 @@ using namespace lldb_private;
 using namespace lldb_private::lldb_server;
 using namespace lldb_private::process_gdb_remote;
 
+namespace {
+#if defined(__linux__)
+typedef process_linux::NativeProcessLinux::Factory NativeProcessFactory;
+#elif defined(__NetBSD__)
+typedef process_netbsd::NativeProcessNetBSD::Factory NativeProcessFactory;
+#else
+// Dummy implementation to make sure the code compiles
+class NativeProcessFactory : public NativeProcessProtocol::Factory {
+public:
+  llvm::Expected<NativeProcessProtocolSP>
+  Launch(ProcessLaunchInfo &launch_info,
+         NativeProcessProtocol::NativeDelegate &delegate,
+         MainLoop &mainloop) const override {
+    llvm_unreachable("Not implemented");
+  }
+  llvm::Expected<NativeProcessProtocolSP>
+  Attach(lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &delegate,
+         MainLoop &mainloop) const override {
+    llvm_unreachable("Not implemented");
+  }
+};
+#endif
+}
+
 //----------------------------------------------------------------------
 // option descriptors for getopt_long_only()
 //----------------------------------------------------------------------
@@ -446,7 +477,8 @@ int main_gdbserver(int argc, char *argv[
     exit(255);
   }
 
-  GDBRemoteCommunicationServerLLGS gdb_server(mainloop);
+  NativeProcessFactory factory;
+  GDBRemoteCommunicationServerLLGS gdb_server(mainloop, factory);
 
   const char *const host_and_port = argv[0];
   argc -= 1;




More information about the lldb-commits mailing list