diff options
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 |