[Lldb-commits] [lldb] r185442 - Sync parts of FreeBSD Process plugin with Linux
Ed Maste
emaste at freebsd.org
Tue Jul 2 09:45:16 PDT 2013
Author: emaste
Date: Tue Jul 2 11:45:16 2013
New Revision: 185442
URL: http://llvm.org/viewvc/llvm-project?rev=185442&view=rev
Log:
Sync parts of FreeBSD Process plugin with Linux
* Use PseudoTerminal to fix stdio handling / passthrough to the inferior
process.
* Add log messages equivalent to the Linux ones.
* Port changes relating to process creation / termination.
This revision contains changes equivalent to (parts of) SVN revisions
109318 142384 166055 168503 169645 177116 182809.
Modified:
lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h
Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=185442&r1=185441&r2=185442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Tue Jul 2 11:45:16 2013
@@ -11,6 +11,7 @@
#include <errno.h>
#include <poll.h>
#include <string.h>
+#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ptrace.h>
@@ -474,7 +475,13 @@ ResumeOperation::Execute(ProcessMonitor
data = m_signo;
if (PTRACE(PT_CONTINUE, m_tid, (caddr_t)1, data))
+ {
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+ if (log)
+ log->Printf ("ResumeOperation (%" PRIu64 ") failed: %s", m_tid, strerror(errno));
m_result = false;
+ }
else
m_result = true;
}
@@ -601,7 +608,7 @@ KillOperation::Execute(ProcessMonitor *m
}
//------------------------------------------------------------------------------
-/// @class KillOperation
+/// @class DetachOperation
/// @brief Implements ProcessMonitor::BringProcessIntoLimbo.
class DetachOperation : public Operation
{
@@ -725,7 +732,7 @@ WAIT_AGAIN:
// Check that the launch was a success.
if (!args->m_error.Success())
{
- StopLaunchOpThread();
+ StopOpThread();
error = args->m_error;
return;
}
@@ -781,10 +788,10 @@ WAIT_AGAIN:
}
}
- // Check that the launch was a success.
+ // Check that the attach was a success.
if (!args->m_error.Success())
{
- StopAttachOpThread();
+ StopOpThread();
error = args->m_error;
return;
}
@@ -819,18 +826,6 @@ ProcessMonitor::StartLaunchOpThread(Laun
Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error);
}
-void
-ProcessMonitor::StopLaunchOpThread()
-{
- lldb::thread_result_t result;
-
- if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
- return;
-
- Host::ThreadCancel(m_operation_thread, NULL);
- Host::ThreadJoin(m_operation_thread, &result, NULL);
-}
-
void *
ProcessMonitor::LaunchOpThread(void *arg)
{
@@ -857,14 +852,34 @@ ProcessMonitor::Launch(LaunchArgs *args)
const char *stdout_path = args->m_stdout_path;
const char *stderr_path = args->m_stderr_path;
const char *working_dir = args->m_working_dir;
+
+ lldb_utility::PseudoTerminal terminal;
+ const size_t err_len = 1024;
+ char err_str[err_len];
lldb::pid_t pid;
lldb::ThreadSP inferior;
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
// Propagate the environment if one is not supplied.
if (envp == NULL || envp[0] == NULL)
envp = const_cast<const char **>(environ);
+ // Pseudo terminal setup.
+ if (!terminal.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, err_str, err_len))
+ {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Could not open controlling TTY.");
+ goto FINISH;
+ }
+
+ if ((pid = terminal.Fork(err_str, err_len)) == -1)
+ {
+ args->m_error.SetErrorToGenericError();
+ args->m_error.SetErrorString("Process fork failed.");
+ goto FINISH;
+ }
+
// Recognized child exit status codes.
enum {
ePtraceFailed = 1,
@@ -875,8 +890,6 @@ ProcessMonitor::Launch(LaunchArgs *args)
eExecFailed
};
- pid = fork();
-
// Child process.
if (pid == 0)
{
@@ -968,10 +981,9 @@ ProcessMonitor::Launch(LaunchArgs *args)
goto FINISH;
}
#endif
- // XXX - Release the master terminal descriptor and pass it off to the
- // XXX - ProcessMonitor instance. Similarly stash the inferior pid.
- // For now just use stdin fd
- monitor->m_terminal_fd = ::dup(STDIN_FILENO);
+ // Release the master terminal descriptor and pass it off to the
+ // ProcessMonitor instance. Similarly stash the inferior pid.
+ monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
monitor->m_pid = pid;
// Set the terminal fd to be in non blocking mode (it simplifies the
@@ -982,6 +994,8 @@ ProcessMonitor::Launch(LaunchArgs *args)
// Update the process thread list with this new thread.
inferior.reset(new POSIXThread(*processSP, pid));
+ if (log)
+ log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
process.GetThreadList().AddThread(inferior);
// Let our process instance know the thread has stopped.
@@ -1016,12 +1030,6 @@ ProcessMonitor::StartAttachOpThread(Atta
Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error);
}
-void
-ProcessMonitor::StopAttachOpThread()
-{
- assert(!"Not implemented yet!!!");
-}
-
void *
ProcessMonitor::AttachOpThread(void *arg)
{
@@ -1087,10 +1095,22 @@ ProcessMonitor::MonitorCallback(void *ca
ProcessMessage message;
ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton);
ProcessFreeBSD *process = monitor->m_process;
+ assert(process);
bool stop_monitoring;
siginfo_t info;
int ptrace_err;
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+ if (exited)
+ {
+ if (log)
+ log->Printf ("ProcessMonitor::%s() got exit signal, tid = %" PRIu64, __FUNCTION__, pid);
+ message = ProcessMessage::Exit(pid, status);
+ process->SendMessage(message);
+ return pid == process->GetID();
+ }
+
if (!monitor->GetSignalInfo(pid, &info, ptrace_err))
stop_monitoring = true; // pid is gone. Bail.
else {
@@ -1118,6 +1138,8 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
{
ProcessMessage message;
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
assert(monitor);
assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
@@ -1135,17 +1157,23 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
unsigned long data = 0;
if (!monitor->GetEventMessage(pid, &data))
data = -1;
+ if (log)
+ log->Printf ("ProcessMonitor::%s() received exit? event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
message = ProcessMessage::Limbo(pid, (data >> 8));
break;
}
case 0:
case TRAP_TRACE:
+ if (log)
+ log->Printf ("ProcessMonitor::%s() received trace event, pid = %" PRIu64, __FUNCTION__, pid);
message = ProcessMessage::Trace(pid);
break;
case SI_KERNEL:
case TRAP_BRKPT:
+ if (log)
+ log->Printf ("ProcessMonitor::%s() received breakpoint event, pid = %" PRIu64, __FUNCTION__, pid);
message = ProcessMessage::Break(pid);
break;
}
@@ -1160,6 +1188,8 @@ ProcessMonitor::MonitorSignal(ProcessMon
ProcessMessage message;
int signo = info->si_signo;
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
// POSIX says that process behaviour is undefined after it ignores a SIGFPE,
// SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
// kill(2) or raise(3). Similarly for tgkill(2) on FreeBSD.
@@ -1170,12 +1200,21 @@ ProcessMonitor::MonitorSignal(ProcessMon
// Similarly, ACK signals generated by this monitor.
if (info->si_code == SI_USER)
{
+ if (log)
+ log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d",
+ __FUNCTION__,
+ monitor->m_process->GetUnixSignals().GetSignalAsCString (signo),
+ "SI_USER",
+ info->si_pid);
if (info->si_pid == getpid())
return ProcessMessage::SignalDelivered(pid, signo);
else
return ProcessMessage::Signal(pid, signo);
}
+ if (log)
+ log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo));
+
if (signo == SIGSEGV) {
lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
@@ -1384,7 +1423,8 @@ ProcessMonitor::ServeOperation(Operation
assert(errno == EINTR);
goto READ_AGAIN;
}
-
+ if (status == 0)
+ continue; // Poll again. The connection probably terminated.
assert(status == sizeof(op));
op->Execute(monitor);
write(fdset.fd, &op, sizeof(op));
@@ -1509,8 +1549,15 @@ bool
ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)
{
bool result;
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+ if (log)
+ log->Printf ("ProcessMonitor::%s() resuming thread = %" PRIu64 " with signal %s", __FUNCTION__, tid,
+ m_process->GetUnixSignals().GetSignalAsCString (signo));
ResumeOperation op(tid, signo, result);
DoOperation(&op);
+ if (log)
+ log->Printf ("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false");
return result;
}
@@ -1550,14 +1597,16 @@ ProcessMonitor::GetEventMessage(lldb::ti
return result;
}
-Error
+lldb_private::Error
ProcessMonitor::Detach(lldb::tid_t tid)
{
- Error result;
- DetachOperation op(result);
- DoOperation(&op);
- StopMonitor();
- return result;
+ lldb_private::Error error;
+ if (tid != LLDB_INVALID_THREAD_ID)
+ {
+ DetachOperation op(error);
+ DoOperation(&op);
+ }
+ return error;
}
bool
@@ -1588,13 +1637,26 @@ void
ProcessMonitor::StopMonitor()
{
StopMonitoringChildProcess();
- StopLaunchOpThread();
+ StopOpThread();
CloseFD(m_terminal_fd);
CloseFD(m_client_fd);
CloseFD(m_server_fd);
}
void
+ProcessMonitor::StopOpThread()
+{
+ lldb::thread_result_t result;
+
+ if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
+ return;
+
+ Host::ThreadCancel(m_operation_thread, NULL);
+ Host::ThreadJoin(m_operation_thread, &result, NULL);
+ m_operation_thread = LLDB_INVALID_HOST_THREAD;
+}
+
+void
ProcessMonitor::CloseFD(int &fd)
{
if (fd != -1)
Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h?rev=185442&r1=185441&r2=185442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h Tue Jul 2 11:45:16 2013
@@ -244,9 +244,6 @@ private:
void
StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
- void
- StopLaunchOpThread();
-
static void *
LaunchOpThread(void *arg);
@@ -269,9 +266,6 @@ private:
void
StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
- void
- StopAttachOpThread();
-
static void *
AttachOpThread(void *args);
@@ -318,6 +312,10 @@ private:
void
StopMonitor();
+ /// Stops the operation thread used to attach/launch a process.
+ void
+ StopOpThread();
+
void
CloseFD(int &fd);
};
More information about the lldb-commits
mailing list