diff options
author | Pavel Labath <labath@google.com> | 2015-05-29 10:13:03 +0000 |
---|---|---|
committer | Pavel Labath <labath@google.com> | 2015-05-29 10:13:03 +0000 |
commit | c4e25c96483643748e6fcf669a776603697365ef (patch) | |
tree | 8234c8e68e0e3ee4f7ea7aedf0629623f3171c93 /lldb/source/Plugins/Process | |
parent | 43a298cb36f8e05e9335bd3deb3214ef5bb99df8 (diff) | |
download | bcm5719-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')
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()) |