and FreeBSD/ProcessMonitor.
http://reviews.llvm.org/D6240
llvm-svn: 222372
{
AttachArgs *args = static_cast<AttachArgs*>(arg);
- if (!Attach(args))
- return NULL;
+ Attach(args);
ServeOperation(args);
return NULL;
}
-bool
+void
ProcessMonitor::Attach(AttachArgs *args)
{
lldb::pid_t pid = args->m_pid;
{
args->m_error.SetErrorToGenericError();
args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
- goto FINISH;
+ return;
}
// Attach to the requested process.
if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0)
{
args->m_error.SetErrorToErrno();
- goto FINISH;
+ return;
}
int status;
if ((status = waitpid(pid, NULL, 0)) < 0)
{
args->m_error.SetErrorToErrno();
- goto FINISH;
+ return;
}
process.SendMessage(ProcessMessage::Attach(pid));
-
-FINISH:
- return args->m_error.Success();
}
size_t
static void *
AttachOpThread(void *args);
- static bool
+ static void
Attach(AttachArgs *args);
static void
{
assert(m_monitor);
m_exit_now = true;
+ if (GetID() == LLDB_INVALID_PROCESS_ID)
+ {
+ error.SetErrorString("invalid process id");
+ return error;
+ }
if (!m_monitor->Kill())
{
error.SetErrorToErrno();
else
{
if (GetID() != LLDB_INVALID_PROCESS_ID)
- {
SetID (LLDB_INVALID_PROCESS_ID);
- const char *error_string = error.AsCString();
- if (error_string == NULL)
- error_string = "attach failed";
- SetExitStatus(-1, error_string);
- }
+ const char *error_string = error.AsCString();
+ if (error_string == NULL)
+ error_string = "attach failed";
+
+ SetExitStatus(-1, error_string);
}
}
}
--- /dev/null
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+EXE := AttachDenied
+
+include $(LEVEL)/Makefile.rules
--- /dev/null
+"""
+Test denied process attach.
+"""
+
+import os
+import shutil
+import tempfile
+import unittest2
+import lldb
+from lldbtest import *
+
+exe_name = 'AttachDenied' # Must match Makefile
+
+class AttachDeniedTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @skipIfWindows
+ def test_attach_to_process_by_id_denied(self):
+ """Test attach by process id denied"""
+
+ self.buildDefault()
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ temp_dir = tempfile.mkdtemp()
+ self.addTearDownHook(lambda: shutil.rmtree(temp_dir))
+
+ # Use named pipe as a synchronization point between test and inferior.
+ pid_pipe_path = os.path.join(temp_dir, "pid_pipe")
+ os.mkfifo(pid_pipe_path)
+
+ # Spawn a new process
+ popen = self.spawnSubprocess(exe, [pid_pipe_path])
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ pid_pipe = open(pid_pipe_path, 'r')
+ self.addTearDownHook(lambda: pid_pipe.close())
+ pid = pid_pipe.read()
+
+ self.expect('process attach -p ' + pid,
+ startstr = 'error: attach failed:',
+ error = True)
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
--- /dev/null
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#if defined(PTRACE_ATTACH)
+#define ATTACH_REQUEST PTRACE_ATTACH
+#define DETACH_REQUEST PTRACE_DETACH
+#elif defined(PT_ATTACH)
+#define ATTACH_REQUEST PT_ATTACH
+#define DETACH_REQUEST PT_DETACH
+#else
+#error "Unsupported platform"
+#endif
+
+bool writePid (const char* file_name, const pid_t pid)
+{
+ int fd = open (file_name, O_WRONLY);
+ if (fd == -1)
+ {
+ fprintf (stderr, "open(%s) failed: %s\n", file_name, strerror (errno));
+ return false;
+ }
+ char buffer[64];
+ snprintf (buffer, sizeof(buffer), "%ld", (long)pid);
+
+ bool res = true;
+ if (write (fd, buffer, strlen (buffer)) == -1)
+ {
+ fprintf (stderr, "write(%s) failed: %s\n", buffer, strerror (errno));
+ res = false;
+ }
+ close (fd);
+ return res;
+}
+
+void sigterm_handler (int)
+{
+}
+
+int main (int argc, char const *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf (stderr, "invalid number of command line arguments\n");
+ return 1;
+ }
+
+ const pid_t pid = fork ();
+ if (pid == -1)
+ {
+ fprintf (stderr, "fork failed: %s\n", strerror (errno));
+ return 1;
+ }
+
+ if (pid > 0)
+ {
+ // Make pause call to return when SIGTERM is received.
+ signal (SIGTERM, sigterm_handler);
+ if (ptrace (ATTACH_REQUEST, pid, NULL, 0) == -1)
+ {
+ fprintf (stderr, "ptrace(ATTACH) failed: %s\n", strerror (errno));
+ }
+ else
+ {
+ if (writePid (argv[1], pid))
+ pause (); // Waiting for the debugger trying attach to the child.
+
+ if (ptrace (DETACH_REQUEST, pid, NULL, 0) != 0)
+ fprintf (stderr, "ptrace(DETACH) failed: %s\n", strerror (errno));
+ }
+
+ kill (pid, SIGTERM);
+ int status = 0;
+ if (waitpid (pid, &status, 0) == -1)
+ fprintf (stderr, "waitpid failed: %s\n", strerror (errno));
+ }
+ else
+ {
+ // child inferior.
+ pause ();
+ }
+
+ printf ("Exiting now\n");
+ return 0;
+}