summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp191
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.h9
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp14
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h4
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp67
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h7
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp49
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeThreadLinux.h2
8 files changed, 195 insertions, 148 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");
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index a2ffd6cb68b..07220e97e3a 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -296,6 +296,15 @@ namespace lldb_private
MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid);
void
+ MonitorTrace(lldb::pid_t pid, NativeThreadProtocolSP thread_sp);
+
+ void
+ MonitorBreakpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp);
+
+ void
+ MonitorWatchpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp, uint32_t wp_index);
+
+ void
MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited);
#if 0
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 67363ca6bbc..3d798e6e0f9 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -155,19 +155,17 @@ NativeRegisterContextLinux_mips64::WriteAllRegisterValues (const lldb::DataBuffe
}
Error
-NativeRegisterContextLinux_mips64::IsWatchpointHit (uint8_t wp_index)
+NativeRegisterContextLinux_mips64::IsWatchpointHit (uint32_t wp_index, bool &is_hit)
{
- Error error;
- error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointHit not implemented");
- return error;
+ is_hit = false;
+ return Error("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointHit not implemented");
}
Error
-NativeRegisterContextLinux_mips64::IsWatchpointVacant (uint32_t wp_index)
+NativeRegisterContextLinux_mips64::IsWatchpointVacant (uint32_t wp_index, bool &is_vacant)
{
- Error error;
- error.SetErrorString ("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointVacant not implemented");
- return error;
+ is_vacant = false;
+ return Error("MIPS TODO: NativeRegisterContextLinux_mips64::IsWatchpointVacant not implemented");
}
bool
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
index b7833438ae0..35218b7eb58 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -91,10 +91,10 @@ namespace lldb_private
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
Error
- IsWatchpointHit (uint8_t wp_index) override;
+ IsWatchpointHit (uint32_t wp_index, bool &is_hit) override;
Error
- IsWatchpointVacant (uint32_t wp_index) override;
+ IsWatchpointVacant (uint32_t wp_index, bool &is_vacant) override;
bool
ClearHardwareWatchpoint (uint32_t wp_index) override;
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index fa6dfd64b88..06ad5f296ec 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -9,6 +9,7 @@
#include "NativeRegisterContextLinux_x86_64.h"
+#include "lldb/Core/Log.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
@@ -1046,39 +1047,61 @@ NativeRegisterContextLinux_x86_64::WriteGPR()
}
Error
-NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint8_t wp_index)
+NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
{
if (wp_index >= NumSupportedHardwareWatchpoints())
- return Error ("Watchpoint index out of range");
+ return Error("Watchpoint index out of range");
RegisterValue reg_value;
Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) return error;
+ if (error.Fail())
+ {
+ is_hit = false;
+ return error;
+ }
uint64_t status_bits = reg_value.GetAsUInt64();
- bool is_hit = status_bits & (1 << wp_index);
-
- error.SetError (!is_hit, lldb::eErrorTypeInvalid);
+ is_hit = status_bits & (1 << wp_index);
return error;
}
Error
-NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index)
+NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(uint32_t &wp_index) {
+ uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
+ for (wp_index = 0; wp_index < num_hw_wps; ++wp_index)
+ {
+ bool is_hit;
+ Error error = IsWatchpointHit(wp_index, is_hit);
+ if (error.Fail()) {
+ wp_index = LLDB_INVALID_INDEX32;
+ return error;
+ } else if (is_hit) {
+ return error;
+ }
+ }
+ wp_index = LLDB_INVALID_INDEX32;
+ return Error();
+}
+
+Error
+NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index, bool &is_vacant)
{
if (wp_index >= NumSupportedHardwareWatchpoints())
return Error ("Watchpoint index out of range");
RegisterValue reg_value;
Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) return error;
+ if (error.Fail())
+ {
+ is_vacant = false;
+ return error;
+ }
uint64_t control_bits = reg_value.GetAsUInt64();
- bool is_vacant = !(control_bits & (1 << (2 * wp_index)));
-
- error.SetError (!is_vacant, lldb::eErrorTypeInvalid);
+ is_vacant = !(control_bits & (1 << (2 * wp_index)));
return error;
}
@@ -1096,8 +1119,10 @@ NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
if (size != 1 && size != 2 && size != 4 && size != 8)
return Error ("Invalid size for watchpoint");
- Error error = IsWatchpointVacant (wp_index);
+ bool is_vacant;
+ Error error = IsWatchpointVacant (wp_index, is_vacant);
if (error.Fail()) return error;
+ if (!is_vacant) return Error("Watchpoint index not vacant");
RegisterValue reg_value;
error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
@@ -1184,14 +1209,24 @@ uint32_t
NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
lldb::addr_t addr, size_t size, uint32_t watch_flags)
{
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index)
- if (IsWatchpointVacant(wp_index).Success())
+ {
+ bool is_vacant;
+ Error error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant)
{
- if (SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index).Fail())
- continue;
- return wp_index;
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
}
+ if (error.Fail() && log)
+ {
+ log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ }
return LLDB_INVALID_INDEX32;
}
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index 0e9d721959b..e183118e8d4 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -46,10 +46,13 @@ namespace lldb_private
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
Error
- IsWatchpointHit(uint8_t wp_index) override;
+ IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
Error
- IsWatchpointVacant(uint32_t wp_index) override;
+ GetWatchpointHitIndex(uint32_t &wp_index) override;
+
+ Error
+ IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
bool
ClearHardwareWatchpoint(uint32_t wp_index) override;
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 148f55f8033..51597f8dd17 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -22,6 +22,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostNativeThread.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/SmallString.h"
@@ -379,53 +380,23 @@ NativeThreadLinux::SetStoppedByBreakpoint ()
}
void
-NativeThreadLinux::SetStoppedByWatchpoint ()
+NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
{
- Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
- if (log)
- {
- NativeProcessProtocolSP process_sp = m_process_wp.lock ();
- if (process_sp)
- pid = process_sp->GetID ();
- }
-
const StateType new_state = StateType::eStateStopped;
MaybeLogStateChange (new_state);
m_state = new_state;
-
- NativeRegisterContextSP reg_ctx = GetRegisterContext ();
- const uint32_t num_hw_watchpoints = reg_ctx->NumSupportedHardwareWatchpoints ();
-
m_stop_description.clear ();
- for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index)
- {
- if (reg_ctx->IsWatchpointHit (wp_index).Success())
- {
- if (log)
- log->Printf ("NativeThreadLinux:%s (pid=%" PRIu64 ", tid=%" PRIu64 ") watchpoint found with idx: %u",
- __FUNCTION__, pid, GetID (), wp_index);
-
- std::ostringstream ostr;
- ostr << reg_ctx->GetWatchpointAddress (wp_index) << " " << wp_index;
- m_stop_description = ostr.str();
-
- m_stop_info.reason = StopReason::eStopReasonWatchpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
- return;
- }
- }
- // The process reported a watchpoint was hit, but we haven't found the
- // watchpoint. Assume that a stopped by trace is reported as a hardware
- // watchpoint what happens on some linux kernels (e.g.: android-arm64
- // platfrom-21).
+ lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
+ "wp_index cannot be invalid");
- if (log)
- log->Printf ("NativeThreadLinux:%s (pid=%" PRIu64 ", tid=%" PRIu64 ") none of the watchpoint was hit.",
- __FUNCTION__, pid, GetID ());
+ std::ostringstream ostr;
+ ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << wp_index;
+ m_stop_description = ostr.str();
- SetStoppedByTrace ();
+ m_stop_info.reason = StopReason::eStopReasonWatchpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
}
bool
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
index 2519b5b1da0..c77dcbe093f 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -76,7 +76,7 @@ namespace lldb_private
SetStoppedByBreakpoint ();
void
- SetStoppedByWatchpoint ();
+ SetStoppedByWatchpoint (uint32_t wp_index);
bool
IsStoppedAtBreakpoint ();
OpenPOWER on IntegriCloud