summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-08-12 17:02:07 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-08-12 17:02:07 +0000
commit58a2f6692bc3d140d2308549f5c0b96e72c0a034 (patch)
tree15889695196839cd13e19b4ff87c4ac017855896 /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
parent09d84addb77e7ddf6a430ea79174ec123e9d3581 (diff)
downloadbcm5719-llvm-58a2f6692bc3d140d2308549f5c0b96e72c0a034.tar.gz
bcm5719-llvm-58a2f6692bc3d140d2308549f5c0b96e72c0a034.zip
llgs: corrected Linux signal reception notification for SIGABRT, SIGSEGV and their ilk.
Added llgs/debugserver gdb-remote tests around SIGABRT and SIGSEGV signal reception notification. Found a few bugs in exception signal handling in Linux llgs. Fixed those. llvm-svn: 215458
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp165
1 files changed, 84 insertions, 81 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 284450f330b..f3ea9505ec4 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -2154,77 +2154,78 @@ NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool e
info->si_pid,
(info->si_pid == getpid ()) ? "is monitor" : "is not monitor",
pid);
+ }
- if ((info->si_pid == 0) && info->si_code == SI_USER)
- {
- // A new thread creation is being signaled. This is one of two parts that come in
- // a non-deterministic order. pid is the thread id.
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification",
- __FUNCTION__, GetID (), pid);
+ // Check for new thread notification.
+ if ((info->si_pid == 0) && (info->si_code == SI_USER))
+ {
+ // A new thread creation is being signaled. This is one of two parts that come in
+ // a non-deterministic order. pid is the thread id.
+ if (log)
+ log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification",
+ __FUNCTION__, GetID (), pid);
- // Did we already create the thread?
- bool already_tracked = false;
- thread_sp = GetOrCreateThread (pid, already_tracked);
- assert (thread_sp.get() && "failed to get or create the tracking data for newly created inferior thread");
+ // Did we already create the thread?
+ bool already_tracked = false;
+ thread_sp = GetOrCreateThread (pid, already_tracked);
+ assert (thread_sp.get() && "failed to get or create the tracking data for newly created inferior thread");
- // If the thread was already tracked, it means the main thread already received its SIGTRAP for the create.
- if (already_tracked)
- {
- // We can now resume this thread up since it is fully created.
- reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetRunning ();
- Resume (thread_sp->GetID (), LLDB_INVALID_SIGNAL_NUMBER);
- }
- else
- {
- // Mark the thread as currently launching. Need to wait for SIGTRAP clone on the main thread before
- // this thread is ready to go.
- reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetLaunching ();
- }
+ // If the thread was already tracked, it means the main thread already received its SIGTRAP for the create.
+ if (already_tracked)
+ {
+ // We can now resume this thread up since it is fully created.
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetRunning ();
+ Resume (thread_sp->GetID (), LLDB_INVALID_SIGNAL_NUMBER);
}
- else if (info->si_pid == getpid () && (signo == SIGSTOP))
+ else
{
- // This is a tgkill()-based stop.
- if (thread_sp)
- {
- // An inferior thread just stopped. Mark it as such.
- reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (signo);
- SetCurrentThreadID (thread_sp->GetID ());
+ // Mark the thread as currently launching. Need to wait for SIGTRAP clone on the main thread before
+ // this thread is ready to go.
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetLaunching ();
+ }
- // Remove this tid from the wait-for-stop set.
- Mutex::Locker locker (m_wait_for_stop_tids_mutex);
+ // Done handling.
+ return;
+ }
- auto removed_count = m_wait_for_stop_tids.erase (thread_sp->GetID ());
- if (removed_count < 1)
- {
- log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": tgkill()-stopped thread not in m_wait_for_stop_tids",
- __FUNCTION__, GetID (), thread_sp->GetID ());
+ // Check for thread stop notification.
+ if ((info->si_pid == getpid ()) && (info->si_code == SI_TKILL) && (signo == SIGSTOP))
+ {
+ // This is a tgkill()-based stop.
+ if (thread_sp)
+ {
+ // An inferior thread just stopped. Mark it as such.
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (signo);
+ SetCurrentThreadID (thread_sp->GetID ());
- }
+ // Remove this tid from the wait-for-stop set.
+ Mutex::Locker locker (m_wait_for_stop_tids_mutex);
+
+ auto removed_count = m_wait_for_stop_tids.erase (thread_sp->GetID ());
+ if (removed_count < 1)
+ {
+ log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": tgkill()-stopped thread not in m_wait_for_stop_tids",
+ __FUNCTION__, GetID (), thread_sp->GetID ());
- // If this is the last thread in the m_wait_for_stop_tids, we need to notify
- // the delegate that a stop has occurred now that every thread that was supposed
- // to stop has stopped.
- if (m_wait_for_stop_tids.empty ())
+ }
+
+ // If this is the last thread in the m_wait_for_stop_tids, we need to notify
+ // the delegate that a stop has occurred now that every thread that was supposed
+ // to stop has stopped.
+ if (m_wait_for_stop_tids.empty ())
+ {
+ if (log)
{
- if (log)
- {
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", setting process state to stopped now that all tids marked for stop have completed",
- __FUNCTION__,
- GetID (),
- pid);
- }
- SetState (StateType::eStateStopped, true);
+ log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", setting process state to stopped now that all tids marked for stop have completed",
+ __FUNCTION__,
+ GetID (),
+ pid);
}
+ SetState (StateType::eStateStopped, true);
}
}
- else
- {
- // Hmm, not sure what to do with this.
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " unsure how to handle SI_KILL or SI_USER signal", __FUNCTION__, GetID ());
- }
+ // Done handling.
return;
}
@@ -2265,38 +2266,40 @@ NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool e
}
break;
+ case SIGABRT:
case SIGILL:
- {
- // lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- // Can get the reason from here.
- // ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
- // FIXME save the crash reason
- SetState (StateType::eStateCrashed, true);
- }
- break;
-
case SIGFPE:
- {
- // lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- // Can get the crash reason from below.
- // ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
- // FIXME save the crash reason
- SetState (StateType::eStateCrashed, true);
- }
- break;
-
case SIGBUS:
{
- // lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- // Can get the crash reason from below.
- // ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
- // FIXME save the crash reason
- SetState (StateType::eStateCrashed);
+ // Break these out into separate cases once I have more data for each type of signal.
+ lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
+ if (!exited)
+ {
+ // This is just a pre-signal-delivery notification of the incoming signal.
+ // Send a stop to the debugger.
+ if (thread_sp)
+ {
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (signo);
+ SetCurrentThreadID (thread_sp->GetID ());
+ }
+ SetState (StateType::eStateStopped, true);
+ }
+ else
+ {
+ if (thread_sp)
+ {
+ // FIXME figure out how to report exit by signal correctly.
+ const uint64_t exception_type = static_cast<uint64_t> (SIGABRT);
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetCrashedWithException (exception_type, fault_addr);
+ }
+ SetState (StateType::eStateCrashed, true);
+ }
}
break;
default:
- // FIXME Stop all threads here.
+ if (log)
+ log->Printf ("NativeProcessLinux::%s unhandled signal %s (%d)", __FUNCTION__, GetUnixSignals ().GetSignalAsCString (signo), signo);
break;
}
}
OpenPOWER on IntegriCloud