summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2018-11-09 22:33:26 +0000
committerJason Molenda <jmolenda@apple.com>2018-11-09 22:33:26 +0000
commitc0e793d6543fc97c328dd3cf1b6f0708f3ec11be (patch)
treef5613921b2827a22276ef4bdcc5755b6adb7e7b7
parent6c0bb3758e291ff34cd0cde885eae9b5f6f288f7 (diff)
downloadbcm5719-llvm-c0e793d6543fc97c328dd3cf1b6f0708f3ec11be.tar.gz
bcm5719-llvm-c0e793d6543fc97c328dd3cf1b6f0708f3ec11be.zip
Work with a gdb-remote target that doesn't handle the
qWatchpointSupportInfo packet correctly. In GDBRemoteCommunicationClient::GetWatchpointSupportInfo, if the response to qWatchpointSupportInfo does not include the 'num' field, then we did not get an answer we understood, mark this target as not supporting that packet. In Target.cpp, rename the very confusingly named CheckIfWatchpointsExhausted to CheckIfWatchpointsSupported, and check the error status returned by Process::GetWatchpointSupportInfo. If we cannot determine what the number of supported watchpoints are, assume that they will work. We'll handle the failure later when we try to create/enable the watchpoint if the Z2 packet isn't supported. Add a gdb_remote_client test case. <rdar://problem/42621432> llvm-svn: 346561
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py64
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp5
-rw-r--r--lldb/source/Target/Target.cpp10
3 files changed, 77 insertions, 2 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py
new file mode 100644
index 00000000000..66a271e126d
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py
@@ -0,0 +1,64 @@
+from __future__ import print_function
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+class TestNoWatchpointSupportInfo(GDBRemoteTestBase):
+
+ @skipIfXmlSupportMissing
+ @skipIfRemote
+ def test(self):
+ """
+ Test lldb's parsing of the <architecture> tag in the target.xml register
+ description packet.
+ """
+ class MyResponder(MockGDBServerResponder):
+
+ def haltReason(self):
+ return "T02thread:1ff0d;thread-pcs:10001bc00;"
+
+ def threadStopInfo(self, threadnum):
+ if threadnum == 0x1ff0d:
+ return "T02thread:1ff0d;thread-pcs:10001bc00;"
+
+ def setBreakpoint(self, packet):
+ if packet.startswith("Z2,"):
+ return "OK"
+
+ def qXferRead(self, obj, annex, offset, length):
+ if annex == "target.xml":
+ return """<?xml version="1.0"?>
+ <target version="1.0">
+ <architecture>i386:x86-64</architecture>
+ <feature name="org.gnu.gdb.i386.core">
+ <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
+ </feature>
+ </target>""", False
+ else:
+ return None, False
+
+ self.server.responder = MyResponder()
+ if self.TraceOn():
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ interp.HandleCommand("log enable gdb-remote packets", result)
+ self.dbg.SetDefaultArchitecture("x86_64")
+ target = self.dbg.CreateTargetWithFileAndArch(None, None)
+
+ process = self.connect(target)
+
+ if self.TraceOn():
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ interp.HandleCommand("target list", result)
+ print(result.GetOutput())
+
+
+ err = lldb.SBError()
+ wp = target.WatchAddress(0x100, 8, False, True, err)
+ if self.TraceOn() and (err.Fail() or wp.IsValid == False):
+ strm = lldb.SBStream()
+ err.GetDescription(strm)
+ print("watchpoint failed: %s" % strm.GetData())
+ self.assertTrue(wp.IsValid())
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index f7551f342f6..021198bffaf 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1689,12 +1689,17 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
m_supports_watchpoint_support_info = eLazyBoolYes;
llvm::StringRef name;
llvm::StringRef value;
+ bool found_num_field = false;
while (response.GetNameColonValue(name, value)) {
if (name.equals("num")) {
value.getAsInteger(0, m_num_supported_hardware_watchpoints);
num = m_num_supported_hardware_watchpoints;
+ found_num_field = true;
}
}
+ if (found_num_field == false) {
+ m_supports_watchpoint_support_info = eLazyBoolNo;
+ }
} else {
m_supports_watchpoint_support_info = eLazyBoolNo;
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 5e175d633ba..203355f7657 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -772,10 +772,16 @@ bool Target::ProcessIsValid() {
return (m_process_sp && m_process_sp->IsAlive());
}
-static bool CheckIfWatchpointsExhausted(Target *target, Status &error) {
+static bool CheckIfWatchpointsSupported(Target *target, Status &error) {
uint32_t num_supported_hardware_watchpoints;
Status rc = target->GetProcessSP()->GetWatchpointSupportInfo(
num_supported_hardware_watchpoints);
+
+ // If unable to determine the # of watchpoints available,
+ // assume they are supported.
+ if (rc.Fail())
+ return true;
+
if (num_supported_hardware_watchpoints == 0) {
error.SetErrorStringWithFormat(
"Target supports (%u) hardware watchpoint slots.\n",
@@ -814,7 +820,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind);
}
- if (!CheckIfWatchpointsExhausted(this, error))
+ if (!CheckIfWatchpointsSupported(this, error))
return wp_sp;
// Currently we only support one watchpoint per address, with total number of
OpenPOWER on IntegriCloud