[Lldb-commits] [lldb] r128547 - in /lldb/trunk/source/Plugins/Process/Linux: LinuxSignals.cpp LinuxSignals.h LinuxStopInfo.cpp LinuxStopInfo.h LinuxThread.cpp LinuxThread.h ProcessLinux.cpp ProcessLinux.h ProcessMessage.cpp ProcessMessage.h ProcessMonitor.cpp ProcessMonitor.h
Stephen Wilson
wilsons at start.ca
Wed Mar 30 08:55:53 PDT 2011
Author: wilsons
Date: Wed Mar 30 10:55:52 2011
New Revision: 128547
URL: http://llvm.org/viewvc/llvm-project?rev=128547&view=rev
Log:
linux: initial support for 'real' signal handling
This patch upgrades the Linux process plugin to handle a larger range of signal
events. For example, we can detect when the inferior has "crashed" and why,
interrupt a running process, deliver an arbitrary signal, and so on.
Added:
lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.cpp
lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.h
lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.cpp
lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.h
lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.cpp
Modified:
lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp
lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h
lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h
lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.h
lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h
Added: lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.cpp?rev=128547&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.cpp Wed Mar 30 10:55:52 2011
@@ -0,0 +1,67 @@
+//===-- LinuxSignals.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <signal.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "LinuxSignals.h"
+
+LinuxSignals::LinuxSignals()
+ : UnixSignals()
+{
+ Reset();
+}
+
+void
+LinuxSignals::Reset()
+{
+ m_signals.clear();
+
+#define ADDSIGNAL(S, SUPPRESS, STOP, NOTIFY, DESCRIPTION) \
+ AddSignal(SIG ## S, "SIG" #S, #S, SUPPRESS, STOP, NOTIFY, DESCRIPTION)
+
+ ADDSIGNAL(HUP, false, true, true, "hangup");
+ ADDSIGNAL(INT, true, true, true, "interrupt");
+ ADDSIGNAL(QUIT, false, true, true, "quit");
+ ADDSIGNAL(ILL, false, true, true, "illegal instruction");
+ ADDSIGNAL(TRAP, true, true, true, "trace trap (not reset when caught)");
+ ADDSIGNAL(ABRT, false, true, true, "abort");
+ ADDSIGNAL(IOT, false, true, true, "abort");
+ ADDSIGNAL(BUS, false, true, true, "bus error");
+ ADDSIGNAL(FPE, false, true, true, "floating point exception");
+ ADDSIGNAL(KILL, false, true, true, "kill");
+ ADDSIGNAL(USR1, false, true, true, "user defined signal 1");
+ ADDSIGNAL(SEGV, false, true, true, "segmentation violation");
+ ADDSIGNAL(USR2, false, true, true, "user defined signal 2");
+ ADDSIGNAL(PIPE, false, true, true, "write to pipe with reading end closed");
+ ADDSIGNAL(ALRM, false, false, true, "alarm");
+ ADDSIGNAL(TERM, false, true, true, "termination requested");
+ ADDSIGNAL(STKFLT, false, true, true, "stack fault");
+ ADDSIGNAL(CHLD, false, false, true, "child process exit");
+ ADDSIGNAL(CONT, false, true, true, "process continue");
+ ADDSIGNAL(STOP, false, true, true, "process stop");
+ ADDSIGNAL(TSTP, false, true, true, "tty stop");
+ ADDSIGNAL(TTIN, false, true, true, "background tty read");
+ ADDSIGNAL(TTOU, false, true, true, "background tty write");
+ ADDSIGNAL(URG, false, true, true, "urgent data on socket");
+ ADDSIGNAL(XCPU, false, true, true, "CPU resource exceeded");
+ ADDSIGNAL(XFSZ, false, true, true, "file size limit exceeded");
+ ADDSIGNAL(VTALRM, false, true, true, "virtual alarm");
+ ADDSIGNAL(PROF, false, true, true, "profiling alarm");
+ ADDSIGNAL(WINCH, false, true, true, "window size change");
+ ADDSIGNAL(POLL, false, true, true, "pollable event");
+ ADDSIGNAL(IO, false, true, true, "input/output ready");
+ ADDSIGNAL(PWR, false, true, true, "power failure");
+ ADDSIGNAL(SYS, false, true, true, "invalid system call");
+
+#undef ADDSIGNAL
+}
Added: lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.h?rev=128547&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.h (added)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxSignals.h Wed Mar 30 10:55:52 2011
@@ -0,0 +1,31 @@
+//===-- LinuxSignals.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LinuxSignals_H_
+#define liblldb_LinuxSignals_H_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/UnixSignals.h"
+
+/// Linux specific set of Unix signals.
+class LinuxSignals
+ : public lldb_private::UnixSignals
+{
+public:
+ LinuxSignals();
+
+private:
+ void
+ Reset();
+};
+
+#endif
Added: lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.cpp?rev=128547&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.cpp Wed Mar 30 10:55:52 2011
@@ -0,0 +1,60 @@
+//===-- LinuxStopInfo.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LinuxStopInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//===----------------------------------------------------------------------===//
+// LinuxLimboStopInfo
+
+LinuxLimboStopInfo::~LinuxLimboStopInfo() { }
+
+lldb::StopReason
+LinuxLimboStopInfo::GetStopReason() const
+{
+ return lldb::eStopReasonTrace;
+}
+
+const char *
+LinuxLimboStopInfo::GetDescription()
+{
+ return "thread exiting";
+}
+
+bool
+LinuxLimboStopInfo::ShouldStop(Event *event_ptr)
+{
+ return true;
+}
+
+bool
+LinuxLimboStopInfo::ShouldNotify(Event *event_ptr)
+{
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// LinuxCrashStopInfo
+
+LinuxCrashStopInfo::~LinuxCrashStopInfo() { }
+
+lldb::StopReason
+LinuxCrashStopInfo::GetStopReason() const
+{
+ return lldb::eStopReasonException;
+}
+
+const char *
+LinuxCrashStopInfo::GetDescription()
+{
+ return ProcessMessage::GetCrashReasonString(m_crash_reason);
+}
Added: lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.h?rev=128547&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.h (added)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxStopInfo.h Wed Mar 30 10:55:52 2011
@@ -0,0 +1,92 @@
+//===-- LinuxStopInfo.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LinuxStopInfo_H_
+#define liblldb_LinuxStopInfo_H_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/StopInfo.h"
+
+#include "LinuxThread.h"
+#include "ProcessMessage.h"
+
+//===----------------------------------------------------------------------===//
+/// @class LinuxStopInfo
+/// @brief Simple base class for all Linux-specific StopInfo objects.
+///
+class LinuxStopInfo
+ : public lldb_private::StopInfo
+{
+public:
+ LinuxStopInfo(lldb_private::Thread &thread, uint32_t status)
+ : StopInfo(thread, status)
+ { }
+};
+
+//===----------------------------------------------------------------------===//
+/// @class LinuxLimboStopInfo
+/// @brief Represents the stop state of a process ready to exit.
+///
+class LinuxLimboStopInfo
+ : public LinuxStopInfo
+{
+public:
+ LinuxLimboStopInfo(LinuxThread &thread)
+ : LinuxStopInfo(thread, 0)
+ { }
+
+ ~LinuxLimboStopInfo();
+
+ lldb::StopReason
+ GetStopReason() const;
+
+ const char *
+ GetDescription();
+
+ bool
+ ShouldStop(lldb_private::Event *event_ptr);
+
+ bool
+ ShouldNotify(lldb_private::Event *event_ptr);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// @class LinuxCrashStopInfo
+/// @brief Represents the stop state of process that is ready to crash.
+///
+class LinuxCrashStopInfo
+ : public LinuxStopInfo
+{
+public:
+ LinuxCrashStopInfo(LinuxThread &thread, uint32_t status,
+ ProcessMessage::CrashReason reason)
+ : LinuxStopInfo(thread, status),
+ m_crash_reason(reason)
+ { }
+
+ ~LinuxCrashStopInfo();
+
+ lldb::StopReason
+ GetStopReason() const;
+
+ const char *
+ GetDescription();
+
+ ProcessMessage::CrashReason
+ GetCrashReason() const;
+
+private:
+ ProcessMessage::CrashReason m_crash_reason;
+};
+
+#endif
Modified: lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp?rev=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp Wed Mar 30 10:55:52 2011
@@ -12,11 +12,13 @@
// C++ Includes
// Other libraries and framework includes
+// Project includes
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "LinuxStopInfo.h"
#include "LinuxThread.h"
#include "ProcessLinux.h"
#include "ProcessMonitor.h"
@@ -26,11 +28,10 @@
using namespace lldb_private;
+
LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
: Thread(process, tid),
- m_frame_ap(0),
- m_stop_info_id(0),
- m_note(eNone)
+ m_frame_ap(0)
{
}
@@ -49,7 +50,6 @@
void
LinuxThread::RefreshStateAfterStop()
{
- RefreshPrivateStopReason();
}
const char *
@@ -117,10 +117,6 @@
lldb::StopInfoSP
LinuxThread::GetPrivateStopReason()
{
- const uint32_t process_stop_id = GetProcess().GetStopID();
-
- if (m_stop_info_id != process_stop_id || !m_stop_info || !m_stop_info->IsValid())
- RefreshPrivateStopReason();
return m_stop_info;
}
@@ -152,34 +148,64 @@
ProcessMonitor &monitor = GetMonitor();
bool status;
- switch (GetResumeState())
+ switch (resume_state)
{
default:
assert(false && "Unexpected state for resume!");
status = false;
break;
- case lldb::eStateSuspended:
- // FIXME: Implement process suspension.
- status = false;
-
case lldb::eStateRunning:
SetState(resume_state);
- status = monitor.Resume(GetID());
+ status = monitor.Resume(GetID(), GetResumeSignal());
break;
case lldb::eStateStepping:
SetState(resume_state);
- status = monitor.SingleStep(GetID());
+ status = monitor.SingleStep(GetID(), GetResumeSignal());
break;
}
- m_note = eNone;
return status;
}
void
-LinuxThread::BreakNotify()
+LinuxThread::Notify(const ProcessMessage &message)
+{
+ switch (message.GetKind())
+ {
+ default:
+ assert(false && "Unexpected message kind!");
+ break;
+
+ case ProcessMessage::eLimboMessage:
+ LimboNotify(message);
+ break;
+
+ case ProcessMessage::eSignalMessage:
+ SignalNotify(message);
+ break;
+
+ case ProcessMessage::eSignalDeliveredMessage:
+ SignalDeliveredNotify(message);
+ break;
+
+ case ProcessMessage::eTraceMessage:
+ TraceNotify(message);
+ break;
+
+ case ProcessMessage::eBreakpointMessage:
+ BreakNotify(message);
+ break;
+
+ case ProcessMessage::eCrashMessage:
+ CrashNotify(message);
+ break;
+ }
+}
+
+void
+LinuxThread::BreakNotify(const ProcessMessage &message)
{
bool status;
@@ -190,47 +216,53 @@
// corresponding to our current PC.
lldb::addr_t pc = GetRegisterContext()->GetPC();
lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
+ lldb::break_id_t bp_id = bp_site->GetID();
assert(bp_site && bp_site->ValidForThisThread(this));
- m_note = eBreak;
+
m_breakpoint = bp_site;
+ m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
}
void
-LinuxThread::TraceNotify()
+LinuxThread::TraceNotify(const ProcessMessage &message)
{
- m_note = eTrace;
+ m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
}
void
-LinuxThread::ExitNotify()
+LinuxThread::LimboNotify(const ProcessMessage &message)
{
- m_note = eExit;
+ m_stop_info = lldb::StopInfoSP(new LinuxLimboStopInfo(*this));
}
void
-LinuxThread::RefreshPrivateStopReason()
+LinuxThread::SignalNotify(const ProcessMessage &message)
{
- m_stop_info_id = GetProcess().GetStopID();
+ int signo = message.GetSignal();
- switch (m_note) {
+ m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
+ SetResumeSignal(signo);
+}
- default:
- case eNone:
- m_stop_info.reset();
- break;
+void
+LinuxThread::SignalDeliveredNotify(const ProcessMessage &message)
+{
+ int signo = message.GetSignal();
- case eBreak:
- m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
- *this, m_breakpoint->GetID());
- break;
+ // Just treat debugger generated signal events like breakpoints for now.
+ m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
+ SetResumeSignal(signo);
+}
- case eTrace:
- m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
- break;
+void
+LinuxThread::CrashNotify(const ProcessMessage &message)
+{
+ int signo = message.GetSignal();
- case eExit:
- m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, SIGCHLD);
- break;
- }
+ assert(message.GetKind() == ProcessMessage::eCrashMessage);
+
+ m_stop_info = lldb::StopInfoSP(new LinuxCrashStopInfo(
+ *this, signo, message.GetCrashReason()));
+ SetResumeSignal(signo);
}
Modified: lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h?rev=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h Wed Mar 30 10:55:52 2011
@@ -17,6 +17,7 @@
// Other libraries and framework includes
#include "lldb/Target/Thread.h"
+class ProcessMessage;
class ProcessMonitor;
class RegisterContextLinux;
@@ -51,9 +52,7 @@
//
bool Resume();
- void BreakNotify();
- void TraceNotify();
- void ExitNotify();
+ void Notify(const ProcessMessage &message);
protected:
virtual bool
@@ -63,7 +62,6 @@
RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint);
private:
-
RegisterContextLinux *
GetRegisterContextLinux ()
{
@@ -77,26 +75,18 @@
lldb::BreakpointSiteSP m_breakpoint;
lldb::StopInfoSP m_stop_info;
- // Cached process stop id. Used to ensure we do not recalculate stop
- // information/state needlessly.
- uint32_t m_stop_info_id;
-
- enum Notification {
- eNone,
- eBreak,
- eTrace,
- eExit
- };
-
- Notification m_note;
-
- ProcessMonitor &GetMonitor();
+ ProcessMonitor &
+ GetMonitor();
lldb::StopInfoSP
GetPrivateStopReason();
- void
- RefreshPrivateStopReason();
+ void BreakNotify(const ProcessMessage &message);
+ void TraceNotify(const ProcessMessage &message);
+ void LimboNotify(const ProcessMessage &message);
+ void SignalNotify(const ProcessMessage &message);
+ void SignalDeliveredNotify(const ProcessMessage &message);
+ void CrashNotify(const ProcessMessage &message);
lldb_private::Unwind *
GetUnwinder();
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=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp Wed Mar 30 10:55:52 2011
@@ -72,7 +72,9 @@
ProcessLinux::ProcessLinux(Target& target, Listener &listener)
: Process(target, listener),
m_monitor(NULL),
- m_module(NULL)
+ m_module(NULL),
+ m_in_limbo(false),
+ m_exit_now(false)
{
// FIXME: Putting this code in the ctor and saving the byte order in a
// member variable is a hack to avoid const qual issues in GetByteOrder.
@@ -147,11 +149,20 @@
Error
ProcessLinux::DoResume()
{
- assert(GetPrivateState() == eStateStopped && "Bad state for DoResume!");
+ StateType state = GetPrivateState();
- // Set our state to running. This ensures inferior threads do not post a
- // state change first.
- SetPrivateState(eStateRunning);
+ assert(state == eStateStopped || state == eStateCrashed);
+
+ // We are about to resume a thread that will cause the process to exit so
+ // set our exit status now. Do not change our state if the inferior
+ // crashed.
+ if (state == eStateStopped)
+ {
+ if (m_in_limbo)
+ SetExitStatus(m_exit_status, NULL);
+ else
+ SetPrivateState(eStateRunning);
+ }
bool did_resume = false;
uint32_t thread_count = m_thread_list.GetSize(false);
@@ -182,7 +193,23 @@
Error
ProcessLinux::DoHalt(bool &caused_stop)
{
- return Error(1, eErrorTypeGeneric);
+ Error error;
+
+ if (IsStopped())
+ {
+ caused_stop = false;
+ }
+ else if (kill(GetID(), SIGSTOP))
+ {
+ caused_stop = false;
+ error.SetErrorToErrno();
+ }
+ else
+ {
+ caused_stop = true;
+ }
+
+ return error;
}
Error
@@ -194,7 +221,12 @@
Error
ProcessLinux::DoSignal(int signal)
{
- return Error(1, eErrorTypeGeneric);
+ Error error;
+
+ if (kill(GetID(), signal))
+ error.SetErrorToErrno();
+
+ return error;
}
Error
@@ -204,42 +236,19 @@
if (!HasExited())
{
- // Shut down the private state thread as we will synchronize with events
- // ourselves. Discard all current thread plans.
- PausePrivateStateThread();
- GetThreadList().DiscardThreadPlans();
-
- // Bringing the inferior into limbo will be caught by our monitor
- // thread, in turn updating the process state.
- if (!m_monitor->BringProcessIntoLimbo())
+ // Drive the exit event to completion (do not keep the inferior in
+ // limbo).
+ m_exit_now = true;
+
+ if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
{
- error.SetErrorToGenericError();
- error.SetErrorString("Process termination failed.");
+ error.SetErrorToErrno();
return error;
}
- // Wait for the event to arrive. This is guaranteed to be an exit event.
- StateType state;
- EventSP event;
- do {
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(2);
- state = WaitForStateChangedEventsPrivate(&timeout_time, event);
- } while (state != eStateExited && state != eStateInvalid);
-
- // Check if we timed out waiting for the exit event to arrive.
- if (state == eStateInvalid)
- error.SetErrorString("ProcessLinux::DoDestroy timed out.");
-
- // Restart standard event handling and send the process the final kill,
- // driving it out of limbo.
- ResumePrivateStateThread();
+ SetPrivateState(eStateExited);
}
- if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
- error.SetErrorToErrno();
-
return error;
}
@@ -251,18 +260,41 @@
switch (message.GetKind())
{
default:
- SetPrivateState(eStateStopped);
+ assert(false && "Unexpected process message!");
break;
case ProcessMessage::eInvalidMessage:
return;
+ case ProcessMessage::eLimboMessage:
+ m_in_limbo = true;
+ m_exit_status = message.GetExitStatus();
+ if (m_exit_now)
+ {
+ SetPrivateState(eStateExited);
+ m_monitor->Detach();
+ }
+ else
+ SetPrivateState(eStateStopped);
+ break;
+
case ProcessMessage::eExitMessage:
- SetExitStatus(message.GetExitStatus(), NULL);
+ m_exit_status = message.GetExitStatus();
+ SetExitStatus(m_exit_status, NULL);
+ break;
+
+ case ProcessMessage::eTraceMessage:
+ case ProcessMessage::eBreakpointMessage:
+ SetPrivateState(eStateStopped);
break;
case ProcessMessage::eSignalMessage:
- SetExitStatus(-1, NULL);
+ case ProcessMessage::eSignalDeliveredMessage:
+ SetPrivateState(eStateStopped);
+ break;
+
+ case ProcessMessage::eCrashMessage:
+ SetPrivateState(eStateCrashed);
break;
}
@@ -278,30 +310,12 @@
ProcessMessage &message = m_message_queue.front();
- // Resolve the thread this message corresponds to.
+ // Resolve the thread this message corresponds to and pass it along.
lldb::tid_t tid = message.GetTID();
LinuxThread *thread = static_cast<LinuxThread*>(
GetThreadList().FindThreadByID(tid, false).get());
- switch (message.GetKind())
- {
- default:
- assert(false && "Unexpected message kind!");
- break;
-
- case ProcessMessage::eExitMessage:
- case ProcessMessage::eSignalMessage:
- thread->ExitNotify();
- break;
-
- case ProcessMessage::eTraceMessage:
- thread->TraceNotify();
- break;
-
- case ProcessMessage::eBreakpointMessage:
- thread->BreakNotify();
- break;
- }
+ thread->Notify(message);
m_message_queue.pop();
}
@@ -432,6 +446,11 @@
return GetSTDOUT(buf, len, error);
}
+UnixSignals &
+ProcessLinux::GetUnixSignals()
+{
+ return m_linux_signals;
+}
//------------------------------------------------------------------------------
// ProcessInterface protocol.
@@ -482,8 +501,6 @@
default:
break;
- case eStateUnloaded:
- case eStateCrashed:
case eStateDetached:
case eStateExited:
return true;
@@ -491,3 +508,20 @@
return false;
}
+
+bool
+ProcessLinux::IsStopped()
+{
+ switch (GetPrivateState())
+ {
+ default:
+ break;
+
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ return true;
+ }
+
+ return false;
+}
Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h?rev=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h Wed Mar 30 10:55:52 2011
@@ -17,6 +17,7 @@
// Other libraries and framework includes
#include "lldb/Target/Process.h"
+#include "LinuxSignals.h"
#include "ProcessMessage.h"
class ProcessMonitor;
@@ -178,6 +179,9 @@
ProcessMonitor &GetMonitor() { return *m_monitor; }
+ lldb_private::UnixSignals &
+ GetUnixSignals();
+
private:
/// Target byte order.
lldb::ByteOrder m_byte_order;
@@ -192,6 +196,19 @@
lldb_private::Mutex m_message_mutex;
std::queue<ProcessMessage> m_message_queue;
+ /// True when the process has entered a state of "limbo".
+ ///
+ /// This flag qualifies eStateStopped. It lets us know that when we
+ /// continue from this state the process will exit. Also, when true,
+ /// Process::m_exit_status is set.
+ bool m_in_limbo;
+
+ /// Drive any exit events to completion.
+ bool m_exit_now;
+
+ /// Linux-specific signal set.
+ LinuxSignals m_linux_signals;
+
/// Updates the loaded sections provided by the executable.
///
/// FIXME: It would probably be better to delegate this task to the
@@ -200,6 +217,9 @@
/// Returns true if the process has exited.
bool HasExited();
+
+ /// Returns true if the process is stopped.
+ bool IsStopped();
};
#endif // liblldb_MacOSXProcess_H_
Added: lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.cpp?rev=128547&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.cpp Wed Mar 30 10:55:52 2011
@@ -0,0 +1,91 @@
+//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ProcessMessage.h"
+
+using namespace lldb_private;
+
+const char *
+ProcessMessage::GetCrashReasonString(CrashReason reason)
+{
+ const char *str = NULL;
+
+ switch (reason)
+ {
+ default:
+ assert(false && "invalid CrashReason");
+ break;
+
+ case eInvalidAddress:
+ str = "invalid address";
+ break;
+ case ePrivilegedAddress:
+ str = "address access protected";
+ break;
+ case eIllegalOpcode:
+ str = "illegal instruction";
+ break;
+ case eIllegalOperand:
+ str = "illegal instruction operand";
+ break;
+ case eIllegalAddressingMode:
+ str = "illegal addressing mode";
+ break;
+ case eIllegalTrap:
+ str = "illegal trap";
+ break;
+ case ePrivilegedOpcode:
+ str = "privileged instruction";
+ break;
+ case ePrivilegedRegister:
+ str = "privileged register";
+ break;
+ case eCoprocessorError:
+ str = "coprocessor error";
+ break;
+ case eInternalStackError:
+ str = "internal stack error";
+ break;
+ case eIllegalAlignment:
+ str = "illegal alignment";
+ break;
+ case eIllegalAddress:
+ str = "illegal address";
+ break;
+ case eHardwareError:
+ str = "hardware error";
+ break;
+ case eIntegerDivideByZero:
+ str = "integer divide by zero";
+ break;
+ case eIntegerOverflow:
+ str = "integer overflow";
+ break;
+ case eFloatDivideByZero:
+ str = "floating point divide by zero";
+ break;
+ case eFloatOverflow:
+ str = "floating point overflow";
+ break;
+ case eFloatUnderflow:
+ str = "floating point underflow";
+ break;
+ case eFloatInexactResult:
+ str = "inexact floating point result";
+ break;
+ case eFloatInvalidOperation:
+ str = "invalid floating point operation";
+ break;
+ case eFloatSubscriptRange:
+ str = "invalid floating point subscript range";
+ break;
+ }
+
+ return str;
+}
Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.h?rev=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMessage.h Wed Mar 30 10:55:52 2011
@@ -26,63 +26,134 @@
eExitMessage,
eLimboMessage,
eSignalMessage,
+ eSignalDeliveredMessage,
eTraceMessage,
- eBreakpointMessage
+ eBreakpointMessage,
+ eCrashMessage
+ };
+
+ enum CrashReason
+ {
+ eInvalidCrashReason,
+
+ // SIGSEGV crash reasons.
+ eInvalidAddress,
+ ePrivilegedAddress,
+
+ // SIGILL crash reasons.
+ eIllegalOpcode,
+ eIllegalOperand,
+ eIllegalAddressingMode,
+ eIllegalTrap,
+ ePrivilegedOpcode,
+ ePrivilegedRegister,
+ eCoprocessorError,
+ eInternalStackError,
+
+ // SIGBUS crash reasons,
+ eIllegalAlignment,
+ eIllegalAddress,
+ eHardwareError,
+
+ // SIGFPE crash reasons,
+ eIntegerDivideByZero,
+ eIntegerOverflow,
+ eFloatDivideByZero,
+ eFloatOverflow,
+ eFloatUnderflow,
+ eFloatInexactResult,
+ eFloatInvalidOperation,
+ eFloatSubscriptRange
};
ProcessMessage()
- : m_kind(eInvalidMessage),
- m_tid(LLDB_INVALID_PROCESS_ID),
- m_data(0) { }
+ : m_tid(LLDB_INVALID_PROCESS_ID),
+ m_kind(eInvalidMessage),
+ m_crash_reason(eInvalidCrashReason),
+ m_status(0),
+ m_addr(0) { }
Kind GetKind() const { return m_kind; }
lldb::tid_t GetTID() const { return m_tid; }
- static ProcessMessage Exit(lldb::tid_t tid, int status) {
- return ProcessMessage(tid, eExitMessage, status);
- }
-
+ /// Indicates that the thread @p tid is about to exit with status @p status.
static ProcessMessage Limbo(lldb::tid_t tid, int status) {
return ProcessMessage(tid, eLimboMessage, status);
}
+ /// Indicates that the thread @p tid had the signal @p signum delivered.
static ProcessMessage Signal(lldb::tid_t tid, int signum) {
return ProcessMessage(tid, eSignalMessage, signum);
}
+ /// Indicates that a signal @p signum generated by the debugging process was
+ /// delivered to the thread @p tid.
+ static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalDeliveredMessage, signum);
+ }
+
+ /// Indicates that the thread @p tid encountered a trace point.
static ProcessMessage Trace(lldb::tid_t tid) {
return ProcessMessage(tid, eTraceMessage);
}
+ /// Indicates that the thread @p tid encountered a break point.
static ProcessMessage Break(lldb::tid_t tid) {
return ProcessMessage(tid, eBreakpointMessage);
}
+ /// Indicates that the thread @p tid crashed.
+ static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
+ int signo, lldb::addr_t fault_addr) {
+ ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
+ message.m_crash_reason = reason;
+ return message;
+ }
+
int GetExitStatus() const {
assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
- return m_data;
+ return m_status;
}
int GetSignal() const {
- assert(GetKind() == eSignalMessage);
- return m_data;
+ assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
+ GetKind() == eSignalDeliveredMessage);
+ return m_status;
}
int GetStopStatus() const {
assert(GetKind() == eSignalMessage);
- return m_data;
+ return m_status;
+ }
+
+ CrashReason GetCrashReason() const {
+ assert(GetKind() == eCrashMessage);
+ return m_crash_reason;
}
+ lldb::addr_t GetFaultAddress() const {
+ assert(GetKind() == eCrashMessage);
+ return m_addr;
+ }
+
+ static const char *
+ GetCrashReasonString(CrashReason reason);
+
private:
- ProcessMessage(lldb::tid_t tid, Kind kind, int data = 0)
- : m_kind(kind),
- m_tid(tid),
- m_data(data) { }
+ ProcessMessage(lldb::tid_t tid, Kind kind,
+ int status = 0, lldb::addr_t addr = 0)
+ : m_tid(tid),
+ m_kind(kind),
+ m_crash_reason(eInvalidCrashReason),
+ m_status(status),
+ m_addr(addr) { }
- Kind m_kind;
lldb::tid_t m_tid;
- int m_data;
+ Kind m_kind : 8;
+ CrashReason m_crash_reason : 8;
+ int m_status;
+ lldb::addr_t m_addr;
};
#endif // #ifndef liblldb_ProcessMessage_H_
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=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp Wed Mar 30 10:55:52 2011
@@ -338,20 +338,26 @@
class ResumeOperation : public Operation
{
public:
- ResumeOperation(lldb::tid_t tid, bool &result) :
- m_tid(tid), m_result(result) { }
+ ResumeOperation(lldb::tid_t tid, uint32_t signo, bool &result) :
+ m_tid(tid), m_signo(signo), m_result(result) { }
void Execute(ProcessMonitor *monitor);
private:
lldb::tid_t m_tid;
+ uint32_t m_signo;
bool &m_result;
};
void
ResumeOperation::Execute(ProcessMonitor *monitor)
{
- if (ptrace(PTRACE_CONT, m_tid, NULL, NULL))
+ int data = 0;
+
+ if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = m_signo;
+
+ if (ptrace(PTRACE_CONT, m_tid, NULL, data))
m_result = false;
else
m_result = true;
@@ -363,20 +369,26 @@
class SingleStepOperation : public Operation
{
public:
- SingleStepOperation(lldb::tid_t tid, bool &result)
- : m_tid(tid), m_result(result) { }
+ SingleStepOperation(lldb::tid_t tid, uint32_t signo, bool &result)
+ : m_tid(tid), m_signo(signo), m_result(result) { }
void Execute(ProcessMonitor *monitor);
private:
lldb::tid_t m_tid;
+ uint32_t m_signo;
bool &m_result;
};
void
SingleStepOperation::Execute(ProcessMonitor *monitor)
{
- if (ptrace(PTRACE_SINGLESTEP, m_tid, NULL, NULL))
+ int data = 0;
+
+ if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
+ data = m_signo;
+
+ if (ptrace(PTRACE_SINGLESTEP, m_tid, NULL, data))
m_result = false;
else
m_result = true;
@@ -457,32 +469,6 @@
m_result = false;
else
m_result = true;
-
-#if 0
- // First, stop the inferior process.
- if (kill(pid, SIGSTOP))
- {
- m_result = false;
- return;
- }
-
- // Clear any ptrace options. When PTRACE_O_TRACEEXIT is set, a plain
- // PTRACE_KILL (or any termination signal) will not truely terminate the
- // inferior process. Instead, the process is left in a state of "limbo"
- // allowing us to interrogate its state. However in this case we really do
- // want the process gone.
- if (ptrace(PTRACE_SETOPTIONS, pid, NULL, 0UL))
- {
- m_result = false;
- return;
- }
-
- // Kill it.
- if (ptrace(PTRACE_KILL, pid, NULL, NULL))
- m_result = false;
- else
- m_result = true;
-#endif
}
ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
@@ -586,12 +572,7 @@
ProcessMonitor::~ProcessMonitor()
{
- StopMonitoringChildProcess();
- StopOperationThread();
-
- close(m_terminal_fd);
- close(m_client_fd);
- close(m_server_fd);
+ StopMonitor();
}
//------------------------------------------------------------------------------
@@ -768,50 +749,39 @@
ProcessMessage message;
ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton);
ProcessLinux *process = monitor->m_process;
+ bool stop_monitoring;
+ siginfo_t info;
- switch (signal)
- {
- case 0:
- // No signal. The child has exited normally.
- message = ProcessMessage::Exit(pid, status);
- break;
-
- case SIGTRAP:
- // Specially handle SIGTRAP and form the appropriate message.
- message = MonitorSIGTRAP(monitor, pid);
- break;
+ if (!monitor->GetSignalInfo(pid, &info))
+ stop_monitoring = true; // pid is gone. Bail.
+ else {
+ switch (info.si_signo)
+ {
+ case SIGTRAP:
+ message = MonitorSIGTRAP(monitor, &info, pid);
+ break;
+
+ default:
+ message = MonitorSignal(monitor, &info, pid);
+ break;
+ }
- default:
- // For all other signals simply notify the process instance. Note that
- // the process exit status is set when the signal resulted in
- // termination.
- //
- // FIXME: We need a specialized message to inform the process instance
- // about "crashes".
- if (status)
- message = ProcessMessage::Exit(pid, status);
- else
- message = ProcessMessage::Signal(pid, signal);
+ process->SendMessage(message);
+ stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
}
- process->SendMessage(message);
- bool stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
return stop_monitoring;
}
ProcessMessage
-ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, lldb::pid_t pid)
+ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
+ const struct siginfo *info, lldb::pid_t pid)
{
- siginfo_t info;
ProcessMessage message;
- bool status;
-
- status = monitor->GetSignalInfo(pid, &info);
- assert(status && "GetSignalInfo failed!");
- assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
+ assert(info->si_signo == SIGTRAP && "Unexpected child signal!");
- switch (info.si_code)
+ switch (info->si_code)
{
default:
assert(false && "Unexpected SIGTRAP code!");
@@ -825,7 +795,7 @@
unsigned long data = 0;
if (!monitor->GetEventMessage(pid, &data))
data = -1;
- message = ProcessMessage::Exit(pid, (data >> 8));
+ message = ProcessMessage::Limbo(pid, (data >> 8));
break;
}
@@ -843,6 +813,193 @@
return message;
}
+ProcessMessage
+ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
+ const struct siginfo *info, lldb::pid_t pid)
+{
+ ProcessMessage message;
+ int signo = info->si_signo;
+
+ // 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 Linux.
+ //
+ // IOW, user generated signals never generate what we consider to be a
+ // "crash".
+ //
+ // Similarly, ACK signals generated by this monitor.
+ if (info->si_code == SI_TKILL || info->si_code == SI_USER)
+ {
+ if (info->si_pid == getpid())
+ return ProcessMessage::SignalDelivered(pid, signo);
+ else
+ return ProcessMessage::Signal(pid, signo);
+ }
+
+ if (signo == SIGSEGV) {
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
+ return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+ }
+
+ if (signo == SIGILL) {
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
+ return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+ }
+
+ if (signo == SIGFPE) {
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
+ return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+ }
+
+ if (signo == SIGBUS) {
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
+ return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+ }
+
+ // Everything else is "normal" and does not require any special action on
+ // our part.
+ return ProcessMessage::Signal(pid, signo);
+}
+
+ProcessMessage::CrashReason
+ProcessMonitor::GetCrashReasonForSIGSEGV(const struct siginfo *info)
+{
+ ProcessMessage::CrashReason reason;
+ assert(info->si_signo == SIGSEGV);
+
+ reason = ProcessMessage::eInvalidCrashReason;
+
+ switch (info->si_code)
+ {
+ default:
+ assert(false && "unexpected si_code for SIGSEGV");
+ break;
+ case SEGV_MAPERR:
+ reason = ProcessMessage::eInvalidAddress;
+ break;
+ case SEGV_ACCERR:
+ reason = ProcessMessage::ePrivilegedAddress;
+ break;
+ }
+
+ return reason;
+}
+
+ProcessMessage::CrashReason
+ProcessMonitor::GetCrashReasonForSIGILL(const struct siginfo *info)
+{
+ ProcessMessage::CrashReason reason;
+ assert(info->si_signo == SIGILL);
+
+ reason = ProcessMessage::eInvalidCrashReason;
+
+ switch (info->si_code)
+ {
+ default:
+ assert(false && "unexpected si_code for SIGILL");
+ break;
+ case ILL_ILLOPC:
+ reason = ProcessMessage::eIllegalOpcode;
+ break;
+ case ILL_ILLOPN:
+ reason = ProcessMessage::eIllegalOperand;
+ break;
+ case ILL_ILLADR:
+ reason = ProcessMessage::eIllegalAddressingMode;
+ break;
+ case ILL_ILLTRP:
+ reason = ProcessMessage::eIllegalTrap;
+ break;
+ case ILL_PRVOPC:
+ reason = ProcessMessage::ePrivilegedOpcode;
+ break;
+ case ILL_PRVREG:
+ reason = ProcessMessage::ePrivilegedRegister;
+ break;
+ case ILL_COPROC:
+ reason = ProcessMessage::eCoprocessorError;
+ break;
+ case ILL_BADSTK:
+ reason = ProcessMessage::eInternalStackError;
+ break;
+ }
+
+ return reason;
+}
+
+ProcessMessage::CrashReason
+ProcessMonitor::GetCrashReasonForSIGFPE(const struct siginfo *info)
+{
+ ProcessMessage::CrashReason reason;
+ assert(info->si_signo == SIGFPE);
+
+ reason = ProcessMessage::eInvalidCrashReason;
+
+ switch (info->si_code)
+ {
+ default:
+ assert(false && "unexpected si_code for SIGFPE");
+ break;
+ case FPE_INTDIV:
+ reason = ProcessMessage::eIntegerDivideByZero;
+ break;
+ case FPE_INTOVF:
+ reason = ProcessMessage::eIntegerOverflow;
+ break;
+ case FPE_FLTDIV:
+ reason = ProcessMessage::eFloatDivideByZero;
+ break;
+ case FPE_FLTOVF:
+ reason = ProcessMessage::eFloatOverflow;
+ break;
+ case FPE_FLTUND:
+ reason = ProcessMessage::eFloatUnderflow;
+ break;
+ case FPE_FLTRES:
+ reason = ProcessMessage::eFloatInexactResult;
+ break;
+ case FPE_FLTINV:
+ reason = ProcessMessage::eFloatInvalidOperation;
+ break;
+ case FPE_FLTSUB:
+ reason = ProcessMessage::eFloatSubscriptRange;
+ break;
+ }
+
+ return reason;
+}
+
+ProcessMessage::CrashReason
+ProcessMonitor::GetCrashReasonForSIGBUS(const struct siginfo *info)
+{
+ ProcessMessage::CrashReason reason;
+ assert(info->si_signo == SIGBUS);
+
+ reason = ProcessMessage::eInvalidCrashReason;
+
+ switch (info->si_code)
+ {
+ default:
+ assert(false && "unexpected si_code for SIGBUS");
+ break;
+ case BUS_ADRALN:
+ reason = ProcessMessage::eIllegalAlignment;
+ break;
+ case BUS_ADRERR:
+ reason = ProcessMessage::eIllegalAddress;
+ break;
+ case BUS_OBJERR:
+ reason = ProcessMessage::eHardwareError;
+ break;
+ }
+
+ return reason;
+}
+
void
ProcessMonitor::ServeOperation(LaunchArgs *args)
{
@@ -976,19 +1133,19 @@
}
bool
-ProcessMonitor::Resume(lldb::tid_t tid)
+ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)
{
bool result;
- ResumeOperation op(tid, result);
+ ResumeOperation op(tid, signo, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::SingleStep(lldb::tid_t tid)
+ProcessMonitor::SingleStep(lldb::tid_t tid, uint32_t signo)
{
bool result;
- SingleStepOperation op(tid, result);
+ SingleStepOperation op(tid, signo, result);
DoOperation(&op);
return result;
}
@@ -1021,6 +1178,16 @@
}
bool
+ProcessMonitor::Detach()
+{
+ bool result;
+ KillOperation op(result);
+ DoOperation(&op);
+ StopMonitor();
+ return result;
+}
+
+bool
ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)
{
int target_fd = open(path, flags);
@@ -1043,3 +1210,23 @@
m_monitor_thread = LLDB_INVALID_HOST_THREAD;
}
}
+
+void
+ProcessMonitor::StopMonitor()
+{
+ StopMonitoringChildProcess();
+ StopOperationThread();
+ CloseFD(m_terminal_fd);
+ CloseFD(m_client_fd);
+ CloseFD(m_server_fd);
+}
+
+void
+ProcessMonitor::CloseFD(int &fd)
+{
+ if (fd != -1)
+ {
+ close(fd);
+ fd = -1;
+ }
+}
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=128547&r1=128546&r2=128547&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h Wed Mar 30 10:55:52 2011
@@ -12,6 +12,7 @@
// C Includes
#include <semaphore.h>
+#include <signal.h>
// C++ Includes
// Other libraries and framework includes
@@ -127,13 +128,15 @@
bool
GetEventMessage(lldb::tid_t tid, unsigned long *message);
- /// Resumes the given thread.
+ /// Resumes the given thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
bool
- Resume(lldb::tid_t tid);
+ Resume(lldb::tid_t tid, uint32_t signo);
- /// Single steps the given thread.
+ /// Single steps the given thread. If @p signo is anything but
+ /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
bool
- SingleStep(lldb::tid_t tid);
+ SingleStep(lldb::tid_t tid, uint32_t signo);
/// Sends the inferior process a PTRACE_KILL signal. The inferior will
/// still exists and can be interrogated. Once resumed it will exit as
@@ -141,6 +144,10 @@
bool
BringProcessIntoLimbo();
+ bool
+ Detach();
+
+
private:
ProcessLinux *m_process;
@@ -207,13 +214,37 @@
lldb::pid_t pid, int signal, int status);
static ProcessMessage
- MonitorSIGTRAP(ProcessMonitor *monitor, lldb::pid_t pid);
+ MonitorSIGTRAP(ProcessMonitor *monitor,
+ const struct siginfo *info, lldb::pid_t pid);
+
+ static ProcessMessage
+ MonitorSignal(ProcessMonitor *monitor,
+ const struct siginfo *info, lldb::pid_t pid);
+
+ static ProcessMessage::CrashReason
+ GetCrashReasonForSIGSEGV(const struct siginfo *info);
+
+ static ProcessMessage::CrashReason
+ GetCrashReasonForSIGILL(const struct siginfo *info);
+
+ static ProcessMessage::CrashReason
+ GetCrashReasonForSIGFPE(const struct siginfo *info);
+
+ static ProcessMessage::CrashReason
+ GetCrashReasonForSIGBUS(const struct siginfo *info);
void
DoOperation(Operation *op);
/// Stops the child monitor thread.
- void StopMonitoringChildProcess();
+ void
+ StopMonitoringChildProcess();
+
+ void
+ StopMonitor();
+
+ void
+ CloseFD(int &fd);
};
#endif // #ifndef liblldb_ProcessMonitor_H_
More information about the lldb-commits
mailing list