diff options
author | Enrico Granata <egranata@apple.com> | 2012-07-13 23:18:48 +0000 |
---|---|---|
committer | Enrico Granata <egranata@apple.com> | 2012-07-13 23:18:48 +0000 |
commit | f04a21917cf35874c849abbe4f57b6eab67c8d39 (patch) | |
tree | 7ab27ee7f9ba23c47166d4d91349e9bba9f5a093 /lldb/source/Plugins/Process/gdb-remote | |
parent | 7298ea18711e103d96b41146978458aeeaf1f943 (diff) | |
download | bcm5719-llvm-f04a21917cf35874c849abbe4f57b6eab67c8d39.tar.gz bcm5719-llvm-f04a21917cf35874c849abbe4f57b6eab67c8d39.zip |
<rdar://problem/11782789> Changes to the watchpoint implementation on ARM so that we single-step before stopping at the WP. This is necessary because on ARM the WP triggers before the opcode is actually executed, so we would be unable to continue since we would keep hitting the WP. We work around this by disabling the WP, single stepping and then putting the WP back in place.
llvm-svn: 160199
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
5 files changed, 58 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 83d2843309a..4fac83d334c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -49,6 +49,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : m_supports_alloc_dealloc_memory (eLazyBoolCalculate), m_supports_memory_region_info (eLazyBoolCalculate), m_supports_watchpoint_support_info (eLazyBoolCalculate), + m_watchpoints_trigger_after_instruction(eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -1019,6 +1020,17 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force) if (m_os_version_major != UINT32_MAX) ++num_keys_decoded; } + else if (name.compare("watchpoint_exceptions_received") == 0) + { + ++num_keys_decoded; + if (strcmp(value.c_str(),"before") == 0) + m_watchpoints_trigger_after_instruction = eLazyBoolNo; + else if (strcmp(value.c_str(),"after") == 0) + m_watchpoints_trigger_after_instruction = eLazyBoolYes; + else + --num_keys_decoded; + } + } if (num_keys_decoded > 0) @@ -1352,6 +1364,30 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num) } +lldb_private::Error +GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after) +{ + Error error(GetWatchpointSupportInfo(num)); + if (error.Success()) + error = GetWatchpointsTriggerAfterInstruction(after); + return error; +} + +lldb_private::Error +GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after) +{ + Error error; + + // we assume watchpoints will happen after running the relevant opcode + // and we only want to override this behavior if we have explicitly + // received a qHostInfo telling us otherwise + if (m_qHostInfo_is_valid != eLazyBoolYes) + after = true; + else + after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); + return error; +} + int GDBRemoteCommunicationClient::SetSTDIN (char const *path) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index fb578001dc3..a283389d220 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -209,6 +209,12 @@ public: lldb_private::Error GetWatchpointSupportInfo (uint32_t &num); + lldb_private::Error + GetWatchpointSupportInfo (uint32_t &num, bool& after); + + lldb_private::Error + GetWatchpointsTriggerAfterInstruction (bool &after); + const lldb_private::ArchSpec & GetHostArchitecture (); @@ -358,6 +364,7 @@ protected: lldb_private::LazyBool m_supports_alloc_dealloc_memory; lldb_private::LazyBool m_supports_memory_region_info; lldb_private::LazyBool m_supports_watchpoint_support_info; + lldb_private::LazyBool m_watchpoints_trigger_after_instruction; bool m_supports_qProcessInfoPID:1, diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 3f8677d1c7e..70d73d3c38a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -223,6 +223,11 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet if (sub != LLDB_INVALID_CPUTYPE) response.Printf ("cpusubtype:%u;", sub); + if (cpu == CPU_TYPE_ARM) + response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. + else + response.Printf("watchpoint_exceptions_received:after;"); + switch (lldb::endian::InlHostByteOrder()) { case eByteOrderBig: response.PutCString ("endian:big;"); break; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index e0d22360156..06d19e40033 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -2015,6 +2015,13 @@ ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num) } Error +ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num, bool& after) +{ + Error error (m_gdb_comm.GetWatchpointSupportInfo (num, after)); + return error; +} + +Error ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr) { Error error; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 04d6ff2e7a8..563b89963fa 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -207,6 +207,9 @@ public: virtual lldb_private::Error GetWatchpointSupportInfo (uint32_t &num); + virtual lldb_private::Error + GetWatchpointSupportInfo (uint32_t &num, bool& after); + virtual bool StartNoticingNewThreads(); |