summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp191
1 files changed, 111 insertions, 80 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index b0a2d6c5c4b..fd3a62eab42 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -39,6 +39,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/PseudoTerminal.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
@@ -2251,93 +2252,31 @@ NativeProcessLinux::MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid)
}
case 0:
- case TRAP_TRACE:
- // We receive this on single stepping.
- if (log)
- log->Printf ("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)", __FUNCTION__, pid);
-
+ case TRAP_TRACE: // We receive this on single stepping.
+ case TRAP_HWBKPT: // We receive this on watchpoint hit
if (thread_sp)
{
- std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedByTrace ();
- }
-
- // This thread is currently stopped.
- NotifyThreadStop (pid);
-
- // Here we don't have to request the rest of the threads to stop or request a deferred stop.
- // This would have already happened at the time the Resume() with step operation was signaled.
- // At this point, we just need to say we stopped, and the deferred notifcation will fire off
- // once all running threads have checked in as stopped.
- SetCurrentThreadID (pid);
- // Tell the process we have a stop (from software breakpoint).
- CallAfterRunningThreadsStop (pid,
- [=] (lldb::tid_t signaling_tid)
- {
- SetState (StateType::eStateStopped, true);
- });
- break;
-
- case SI_KERNEL:
- case TRAP_BRKPT:
- if (log)
- log->Printf ("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64, __FUNCTION__, pid);
-
- // This thread is currently stopped.
- NotifyThreadStop (pid);
-
- // Mark the thread as stopped at breakpoint.
- if (thread_sp)
- {
- std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedByBreakpoint ();
- Error error = FixupBreakpointPCAsNeeded (thread_sp);
- if (error.Fail ())
+ // If a watchpoint was hit, report it
+ uint32_t wp_index;
+ Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index);
+ if (error.Fail() && log)
+ log->Printf("NativeProcessLinux::%s() "
+ "received error while checking for watchpoint hits, "
+ "pid = %" PRIu64 " error = %s",
+ __FUNCTION__, pid, error.AsCString());
+ if (wp_index != LLDB_INVALID_INDEX32)
{
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s", __FUNCTION__, pid, error.AsCString ());
+ MonitorWatchpoint(pid, thread_sp, wp_index);
+ break;
}
}
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 ": warning, cannot process software breakpoint since no thread metadata", __FUNCTION__, pid);
- }
-
-
- // We need to tell all other running threads before we notify the delegate about this stop.
- CallAfterRunningThreadsStop (pid,
- [=](lldb::tid_t deferred_notification_tid)
- {
- SetCurrentThreadID (deferred_notification_tid);
- // Tell the process we have a stop (from software breakpoint).
- SetState (StateType::eStateStopped, true);
- });
+ // Otherwise, report step over
+ MonitorTrace(pid, thread_sp);
break;
- case TRAP_HWBKPT:
- if (log)
- log->Printf ("NativeProcessLinux::%s() received watchpoint event, pid = %" PRIu64, __FUNCTION__, pid);
-
- // This thread is currently stopped.
- NotifyThreadStop (pid);
-
- // Mark the thread as stopped at watchpoint.
- // The address is at (lldb::addr_t)info->si_addr if we need it.
- if (thread_sp)
- std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedByWatchpoint ();
- else
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ": warning, cannot process hardware breakpoint since no thread metadata", __FUNCTION__, GetID (), pid);
- }
-
- // We need to tell all other running threads before we notify the delegate about this stop.
- CallAfterRunningThreadsStop (pid,
- [=](lldb::tid_t deferred_notification_tid)
- {
- SetCurrentThreadID (deferred_notification_tid);
- // Tell the process we have a stop (from hardware breakpoint).
- SetState (StateType::eStateStopped, true);
- });
+ case SI_KERNEL:
+ case TRAP_BRKPT:
+ MonitorBreakpoint(pid, thread_sp);
break;
case SIGTRAP:
@@ -2371,6 +2310,98 @@ NativeProcessLinux::MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid)
}
void
+NativeProcessLinux::MonitorTrace(lldb::pid_t pid, NativeThreadProtocolSP thread_sp)
+{
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)",
+ __FUNCTION__, pid);
+
+ if (thread_sp)
+ std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByTrace();
+
+ // This thread is currently stopped.
+ NotifyThreadStop(pid);
+
+ // Here we don't have to request the rest of the threads to stop or request a deferred stop.
+ // This would have already happened at the time the Resume() with step operation was signaled.
+ // At this point, we just need to say we stopped, and the deferred notifcation will fire off
+ // once all running threads have checked in as stopped.
+ SetCurrentThreadID(pid);
+ // Tell the process we have a stop (from software breakpoint).
+ CallAfterRunningThreadsStop(pid,
+ [=](lldb::tid_t signaling_tid)
+ {
+ SetState(StateType::eStateStopped, true);
+ });
+}
+
+void
+NativeProcessLinux::MonitorBreakpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp)
+{
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64,
+ __FUNCTION__, pid);
+
+ // This thread is currently stopped.
+ NotifyThreadStop(pid);
+
+ // Mark the thread as stopped at breakpoint.
+ if (thread_sp)
+ {
+ std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByBreakpoint();
+ Error error = FixupBreakpointPCAsNeeded(thread_sp);
+ if (error.Fail())
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
+ __FUNCTION__, pid, error.AsCString());
+ }
+ else
+ if (log)
+ log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 ": "
+ "warning, cannot process software breakpoint since no thread metadata",
+ __FUNCTION__, pid);
+
+
+ // We need to tell all other running threads before we notify the delegate about this stop.
+ CallAfterRunningThreadsStop(pid,
+ [=](lldb::tid_t deferred_notification_tid)
+ {
+ SetCurrentThreadID(deferred_notification_tid);
+ // Tell the process we have a stop (from software breakpoint).
+ SetState(StateType::eStateStopped, true);
+ });
+}
+
+void
+NativeProcessLinux::MonitorWatchpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp, uint32_t wp_index)
+{
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf("NativeProcessLinux::%s() received watchpoint event, "
+ "pid = %" PRIu64 ", wp_index = %" PRIu32,
+ __FUNCTION__, pid, wp_index);
+
+ // This thread is currently stopped.
+ NotifyThreadStop(pid);
+
+ // Mark the thread as stopped at watchpoint.
+ // The address is at (lldb::addr_t)info->si_addr if we need it.
+ lldbassert(thread_sp && "thread_sp cannot be NULL");
+ std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByWatchpoint(wp_index);
+
+ // We need to tell all other running threads before we notify the delegate about this stop.
+ CallAfterRunningThreadsStop(pid,
+ [=](lldb::tid_t deferred_notification_tid)
+ {
+ SetCurrentThreadID(deferred_notification_tid);
+ // Tell the process we have a stop (from watchpoint).
+ SetState(StateType::eStateStopped, true);
+ });
+}
+
+void
NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited)
{
assert (info && "null info");
OpenPOWER on IntegriCloud