summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2015-05-29 10:13:03 +0000
committerPavel Labath <labath@google.com>2015-05-29 10:13:03 +0000
commitc4e25c96483643748e6fcf669a776603697365ef (patch)
tree8234c8e68e0e3ee4f7ea7aedf0629623f3171c93 /lldb/source/Plugins/Process
parent43a298cb36f8e05e9335bd3deb3214ef5bb99df8 (diff)
downloadbcm5719-llvm-c4e25c96483643748e6fcf669a776603697365ef.tar.gz
bcm5719-llvm-c4e25c96483643748e6fcf669a776603697365ef.zip
Report inferior SIGSEGV as a signal instead of an exception on linux
Summary: Previously, we reported inferior receiving SIGSEGV (or SIGILL, SIGFPE, SIGBUS) as an "exception" to LLDB, presumably to match OSX behaviour. Beside the fact that we were basically lying to the user, this was also causing problems with inferiors which handle SIGSEGV by themselves, since LLDB was unable to reinject this signal back into the inferior. This commit changes LLGS to report SIGSEGV as a signal. This has necessitated some changes in the test-suite, which had previously used eStopReasonException to locate threads that crashed. Now it uses platform-specific logic, which in the case of linux searches for eStopReasonSignaled with signal=SIGSEGV. I have also added the ability to set the description of StopInfoUnixSignal using the description field of the gdb-remote packet. The linux stub uses this to display additional information about the segfault (invalid address, address access protected, etc.). Test Plan: All tests pass on linux and osx. Reviewers: ovyalov, clayborg, emaste Subscribers: emaste, lldb-commits Differential Revision: http://reviews.llvm.org/D10057 llvm-svn: 238549
Diffstat (limited to 'lldb/source/Plugins/Process')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp20
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp40
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeThreadLinux.h2
-rw-r--r--lldb/source/Plugins/Process/POSIX/CrashReason.cpp42
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp4
5 files changed, 43 insertions, 65 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 489890aa513..ec286b055c4 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -2177,7 +2177,7 @@ NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool e
// leave the signal intact if this is the thread that was chosen as the
// triggering thread.
if (m_pending_notification_up && m_pending_notification_up->triggering_tid == pid)
- linux_thread_sp->SetStoppedBySignal(SIGSTOP);
+ linux_thread_sp->SetStoppedBySignal(SIGSTOP, info);
else
linux_thread_sp->SetStoppedBySignal(0);
@@ -2217,22 +2217,8 @@ NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool e
// This thread is stopped.
ThreadDidStop (pid, false);
- switch (signo)
- {
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- if (thread_sp)
- std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetCrashedWithException (*info);
- break;
- default:
- // This is just a pre-signal-delivery notification of the incoming signal.
- if (thread_sp)
- std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedBySignal (signo);
-
- break;
- }
+ if (thread_sp)
+ std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedBySignal(signo, info);
// Send a stop to the debugger after we get all other threads to stop.
StopRunningThreads (pid);
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index cd0dd7edc51..8950702c532 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -125,15 +125,7 @@ NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& descri
if (log)
LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
stop_info = m_stop_info;
- switch (m_stop_info.reason)
- {
- case StopReason::eStopReasonException:
- case StopReason::eStopReasonBreakpoint:
- case StopReason::eStopReasonWatchpoint:
- description = m_stop_description;
- default:
- break;
- }
+ description = m_stop_description;
if (log)
LogThreadStopInfo (*log, stop_info, "returned stop_info:");
@@ -250,7 +242,7 @@ NativeThreadLinux::SetStepping ()
}
void
-NativeThreadLinux::SetStoppedBySignal (uint32_t signo)
+NativeThreadLinux::SetStoppedBySignal(uint32_t signo, const siginfo_t *info)
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
if (log)
@@ -262,6 +254,20 @@ NativeThreadLinux::SetStoppedBySignal (uint32_t signo)
m_stop_info.reason = StopReason::eStopReasonSignal;
m_stop_info.details.signal.signo = signo;
+
+ m_stop_description.clear();
+ switch (signo)
+ {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGILL:
+ if (! info)
+ break;
+ const auto reason = GetCrashReason(*info);
+ m_stop_description = GetCrashReasonString(reason, reinterpret_cast<uintptr_t>(info->si_addr));
+ break;
+ }
}
bool
@@ -356,20 +362,6 @@ NativeThreadLinux::SetStoppedByTrace ()
}
void
-NativeThreadLinux::SetCrashedWithException (const siginfo_t& info)
-{
- const StateType new_state = StateType::eStateCrashed;
- MaybeLogStateChange (new_state);
- m_state = new_state;
-
- m_stop_info.reason = StopReason::eStopReasonException;
- m_stop_info.details.signal.signo = info.si_signo;
-
- const auto reason = GetCrashReason (info);
- m_stop_description = GetCrashReasonString (reason, reinterpret_cast<uintptr_t>(info.si_addr));
-}
-
-void
NativeThreadLinux::SetSuspended ()
{
const StateType new_state = StateType::eStateSuspended;
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
index d78e99c166c..289387bad72 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -60,7 +60,7 @@ namespace process_linux {
SetStepping ();
void
- SetStoppedBySignal (uint32_t signo);
+ SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
/// Return true if the thread is stopped.
/// If stopped by a signal, indicate the signo in the signo argument.
diff --git a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
index 4dd91a6f1de..6de13f470c5 100644
--- a/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -134,69 +134,69 @@ GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr)
break;
case CrashReason::eInvalidAddress:
- str = "invalid address";
+ str = "signal SIGSEGV: invalid address";
AppendFaultAddr (str, fault_addr);
break;
case CrashReason::ePrivilegedAddress:
- str = "address access protected";
+ str = "signal SIGSEGV: address access protected";
AppendFaultAddr (str, fault_addr);
break;
case CrashReason::eIllegalOpcode:
- str = "illegal instruction";
+ str = "signal SIGILL: illegal instruction";
break;
case CrashReason::eIllegalOperand:
- str = "illegal instruction operand";
+ str = "signal SIGILL: illegal instruction operand";
break;
case CrashReason::eIllegalAddressingMode:
- str = "illegal addressing mode";
+ str = "signal SIGILL: illegal addressing mode";
break;
case CrashReason::eIllegalTrap:
- str = "illegal trap";
+ str = "signal SIGILL: illegal trap";
break;
case CrashReason::ePrivilegedOpcode:
- str = "privileged instruction";
+ str = "signal SIGILL: privileged instruction";
break;
case CrashReason::ePrivilegedRegister:
- str = "privileged register";
+ str = "signal SIGILL: privileged register";
break;
case CrashReason::eCoprocessorError:
- str = "coprocessor error";
+ str = "signal SIGILL: coprocessor error";
break;
case CrashReason::eInternalStackError:
- str = "internal stack error";
+ str = "signal SIGILL: internal stack error";
break;
case CrashReason::eIllegalAlignment:
- str = "illegal alignment";
+ str = "signal SIGBUS: illegal alignment";
break;
case CrashReason::eIllegalAddress:
- str = "illegal address";
+ str = "signal SIGBUS: illegal address";
break;
case CrashReason::eHardwareError:
- str = "hardware error";
+ str = "signal SIGBUS: hardware error";
break;
case CrashReason::eIntegerDivideByZero:
- str = "integer divide by zero";
+ str = "signal SIGFPE: integer divide by zero";
break;
case CrashReason::eIntegerOverflow:
- str = "integer overflow";
+ str = "signal SIGFPE: integer overflow";
break;
case CrashReason::eFloatDivideByZero:
- str = "floating point divide by zero";
+ str = "signal SIGFPE: floating point divide by zero";
break;
case CrashReason::eFloatOverflow:
- str = "floating point overflow";
+ str = "signal SIGFPE: floating point overflow";
break;
case CrashReason::eFloatUnderflow:
- str = "floating point underflow";
+ str = "signal SIGFPE: floating point underflow";
break;
case CrashReason::eFloatInexactResult:
- str = "inexact floating point result";
+ str = "signal SIGFPE: inexact floating point result";
break;
case CrashReason::eFloatInvalidOperation:
- str = "invalid floating point operation";
+ str = "signal SIGFPE: invalid floating point operation";
break;
case CrashReason::eFloatSubscriptRange:
- str = "invalid floating point subscript range";
+ str = "signal SIGFPE: invalid floating point subscript range";
break;
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 61cc89dc71b..8d01d003592 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -2080,11 +2080,11 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
if (thread_sp->GetTemporaryResumeState() == eStateStepping)
thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
else
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo, description.c_str()));
}
}
if (!handled)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo, description.c_str()));
}
if (!description.empty())
OpenPOWER on IntegriCloud