diff options
author | Chaoren Lin <chaorenl@google.com> | 2015-03-19 23:28:10 +0000 |
---|---|---|
committer | Chaoren Lin <chaorenl@google.com> | 2015-03-19 23:28:10 +0000 |
commit | c16f5dca27c693f934b12c948b7d53e98ce9111d (patch) | |
tree | 7e0049694785f47b4700df8c65117bf9b06dc56e /lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp | |
parent | d83003ea59ca5592580fa2e0ef27c3cac907aa8f (diff) | |
download | bcm5719-llvm-c16f5dca27c693f934b12c948b7d53e98ce9111d.tar.gz bcm5719-llvm-c16f5dca27c693f934b12c948b7d53e98ce9111d.zip |
Report watchpoint hits during single stepping.
Summary:
Reorganized NativeProcessLinux::MonitorSIGTRAP to check for watchpoint hits on
TRAP_TRACE.
Added test for stepping over watchpoints.
https://llvm.org/bugs/show_bug.cgi?id=22814
Reviewers: ovyalov, tberghammer, vharron, clayborg
Subscribers: jingham, labath, lldb-commits
Differential Revision: http://reviews.llvm.org/D8404
llvm-svn: 232784
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp | 67 |
1 files changed, 51 insertions, 16 deletions
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; } |