[Lldb-commits] [lldb] r133006 - in /lldb/trunk/source/Plugins/Process/Linux: ProcessLinux.cpp ProcessMonitor.cpp ProcessMonitor.h
Johnny Chen
johnny.chen at apple.com
Tue Jun 14 12:19:50 PDT 2011
Author: johnny
Date: Tue Jun 14 14:19:50 2011
New Revision: 133006
URL: http://llvm.org/viewvc/llvm-project?rev=133006&view=rev
Log:
Primitive attach support for linux
This patch is a starting point for the attach functionality.
Signed-off-by: Johnny Chen <johnny.chen at apple.com>
Modified:
lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h
Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp?rev=133006&r1=133005&r2=133006&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp Tue Jun 14 14:19:50 2011
@@ -105,7 +105,16 @@
Error
ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid)
{
- return Error(1, eErrorTypeGeneric);
+ Error error;
+ assert(m_monitor == NULL);
+
+ m_monitor = new ProcessMonitor(this, pid, error);
+
+ if (!error.Success())
+ return error;
+
+ SetID(pid);
+ return error;
}
Error
Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp?rev=133006&r1=133005&r2=133006&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp Tue Jun 14 14:19:50 2011
@@ -524,6 +524,17 @@
m_result = true;
}
+ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
+ : m_monitor(monitor)
+{
+ sem_init(&m_semaphore, 0, 0);
+}
+
+ProcessMonitor::OperationArgs::~OperationArgs()
+{
+ sem_destroy(&m_semaphore);
+}
+
ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
lldb_private::Module *module,
char const **argv,
@@ -531,21 +542,23 @@
const char *stdin_path,
const char *stdout_path,
const char *stderr_path)
- : m_monitor(monitor),
+ : OperationArgs(monitor),
m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
- m_stderr_path(stderr_path)
-{
- sem_init(&m_semaphore, 0, 0);
-}
+ m_stderr_path(stderr_path) { }
ProcessMonitor::LaunchArgs::~LaunchArgs()
-{
- sem_destroy(&m_semaphore);
-}
+{ }
+
+ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor,
+ lldb::pid_t pid)
+ : OperationArgs(monitor), m_pid(pid) { }
+
+ProcessMonitor::AttachArgs::~AttachArgs()
+{ }
//------------------------------------------------------------------------------
/// The basic design of the ProcessMonitor is built around two threads.
@@ -587,7 +600,7 @@
error.SetErrorString("Monitor failed to initialize.");
}
- StartOperationThread(args.get(), error);
+ StartLaunchOpThread(args.get(), error);
if (!error.Success())
return;
@@ -607,7 +620,7 @@
// Check that the launch was a success.
if (!args->m_error.Success())
{
- StopOperationThread();
+ StopLaunchOpThread();
error = args->m_error;
return;
}
@@ -623,6 +636,64 @@
}
}
+ProcessMonitor::ProcessMonitor(ProcessLinux *process,
+ lldb::pid_t pid,
+ lldb_private::Error &error)
+ : m_process(process),
+ m_operation_thread(LLDB_INVALID_HOST_THREAD),
+ m_pid(LLDB_INVALID_PROCESS_ID),
+ m_terminal_fd(-1),
+ m_monitor_thread(LLDB_INVALID_HOST_THREAD),
+ m_client_fd(-1),
+ m_server_fd(-1)
+{
+ std::auto_ptr<AttachArgs> args;
+
+ args.reset(new AttachArgs(this, pid));
+
+ // Server/client descriptors.
+ if (!EnableIPC())
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Monitor failed to initialize.");
+ }
+
+ StartAttachOpThread(args.get(), error);
+ if (!error.Success())
+ return;
+
+WAIT_AGAIN:
+ // Wait for the operation thread to initialize.
+ if (sem_wait(&args->m_semaphore))
+ {
+ if (errno == EINTR)
+ goto WAIT_AGAIN;
+ else
+ {
+ error.SetErrorToErrno();
+ return;
+ }
+ }
+
+ // Check that the launch was a success.
+ if (!args->m_error.Success())
+ {
+ StopAttachOpThread();
+ error = args->m_error;
+ return;
+ }
+
+ // Finally, start monitoring the child process for change in state.
+ m_monitor_thread = Host::StartMonitoringChildProcess(
+ ProcessMonitor::MonitorCallback, this, GetPID(), true);
+ if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread))
+ {
+ error.SetErrorToGenericError();
+ error.SetErrorString("Process attach failed.");
+ return;
+ }
+}
+
ProcessMonitor::~ProcessMonitor()
{
StopMonitor();
@@ -631,7 +702,7 @@
//------------------------------------------------------------------------------
// Thread setup and tear down.
void
-ProcessMonitor::StartOperationThread(LaunchArgs *args, Error &error)
+ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error)
{
static const char *g_thread_name = "lldb.process.linux.operation";
@@ -639,11 +710,11 @@
return;
m_operation_thread =
- Host::ThreadCreate(g_thread_name, OperationThread, args, &error);
+ Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error);
}
void
-ProcessMonitor::StopOperationThread()
+ProcessMonitor::StopLaunchOpThread()
{
lldb::thread_result_t result;
@@ -655,7 +726,7 @@
}
void *
-ProcessMonitor::OperationThread(void *arg)
+ProcessMonitor::LaunchOpThread(void *arg)
{
LaunchArgs *args = static_cast<LaunchArgs*>(arg);
@@ -833,6 +904,80 @@
return true;
}
+void
+ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error)
+{
+ static const char *g_thread_name = "lldb.process.linux.operation";
+
+ if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
+ return;
+
+ m_operation_thread =
+ Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error);
+}
+
+void
+ProcessMonitor::StopAttachOpThread()
+{
+ assert(!"Not implemented yet!!!");
+}
+
+void *
+ProcessMonitor::AttachOpThread(void *arg)
+{
+ AttachArgs *args = static_cast<AttachArgs*>(arg);
+
+ if (!Attach(args))
+ return NULL;
+
+ ServeOperation(args);
+ return NULL;
+}
+
+bool
+ProcessMonitor::Attach(AttachArgs *args)
+{
+ lldb::pid_t pid = args->m_pid;
+
+ ProcessMonitor *monitor = args->m_monitor;
+ ProcessLinux &process = monitor->GetProcess();
+
+ lldb::ThreadSP inferior;
+
+ if (pid <= 1)
+ {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
+ goto FINISH;
+ }
+
+ // Attach to the requested process.
+ if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
+ {
+ args->m_error.SetErrorToErrno();
+ goto FINISH;
+ }
+
+ int status;
+ if ((status = waitpid(pid, NULL, 0)) < 0)
+ {
+ args->m_error.SetErrorToErrno();
+ goto FINISH;
+ }
+
+ // Update the process thread list with the attached thread and
+ // mark it as current.
+ inferior.reset(new LinuxThread(process, pid));
+ process.GetThreadList().AddThread(inferior);
+ process.GetThreadList().SetSelectedThreadByID(pid);
+
+ // Let our process instance know the thread has stopped.
+ process.SendMessage(ProcessMessage::Trace(pid));
+
+ FINISH:
+ return args->m_error.Success();
+}
+
bool
ProcessMonitor::MonitorCallback(void *callback_baton,
lldb::pid_t pid,
@@ -1094,10 +1239,11 @@
}
void
-ProcessMonitor::ServeOperation(LaunchArgs *args)
+ProcessMonitor::ServeOperation(OperationArgs *args)
{
int status;
pollfd fdset;
+
ProcessMonitor *monitor = args->m_monitor;
fdset.fd = monitor->m_server_fd;
@@ -1326,7 +1472,7 @@
ProcessMonitor::StopMonitor()
{
StopMonitoringChildProcess();
- StopOperationThread();
+ StopLaunchOpThread();
CloseFD(m_terminal_fd);
CloseFD(m_client_fd);
CloseFD(m_server_fd);
Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h?rev=133006&r1=133005&r2=133006&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h Tue Jun 14 14:19:50 2011
@@ -56,6 +56,10 @@
const char *stderr_path,
lldb_private::Error &error);
+ ProcessMonitor(ProcessLinux *process,
+ lldb::pid_t pid,
+ lldb_private::Error &error);
+
~ProcessMonitor();
/// Provides the process number of debugee.
@@ -169,11 +173,22 @@
int m_client_fd;
int m_server_fd;
+ struct OperationArgs
+ {
+ OperationArgs(ProcessMonitor *monitor);
+
+ ~OperationArgs();
+
+ ProcessMonitor *m_monitor; // The monitor performing the attach.
+ sem_t m_semaphore; // Posted to once operation complete.
+ lldb_private::Error m_error; // Set if process operation failed.
+ };
+
/// @class LauchArgs
///
/// @brief Simple structure to pass data to the thread responsible for
/// launching a child process.
- struct LaunchArgs
+ struct LaunchArgs : OperationArgs
{
LaunchArgs(ProcessMonitor *monitor,
lldb_private::Module *module,
@@ -192,18 +207,16 @@
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
- sem_t m_semaphore; // Posted to once launch complete.
- lldb_private::Error m_error; // Set if process launch failed.
};
void
- StartOperationThread(LaunchArgs *args, lldb_private::Error &error);
+ StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
void
- StopOperationThread();
+ StopLaunchOpThread();
static void *
- OperationThread(void *arg);
+ LaunchOpThread(void *arg);
static bool
Launch(LaunchArgs *args);
@@ -211,8 +224,30 @@
bool
EnableIPC();
+ struct AttachArgs : OperationArgs
+ {
+ AttachArgs(ProcessMonitor *monitor,
+ lldb::pid_t pid);
+
+ ~AttachArgs();
+
+ lldb::pid_t m_pid; // pid of the process to be attached.
+ };
+
+ void
+ StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
+
+ void
+ StopAttachOpThread();
+
+ static void *
+ AttachOpThread(void *args);
+
+ static bool
+ Attach(AttachArgs *args);
+
static void
- ServeOperation(LaunchArgs *args);
+ ServeOperation(OperationArgs *args);
static bool
DupDescriptor(const char *path, int fd, int flags);
More information about the lldb-commits
mailing list