forked from OSchip/llvm-project
Fix error propagation from the Z0 packet in gdb-remote breakpoint setting.
The error was not getting propagated to the caller, so the higher layers thought the breakpoint was successfully set & resolved. I added a testcase, but it assumes 0x0 is not a valid place to set a breakpoint. On most systems that is true, but if it isn't true of your system, either find another good place and add it to the test, or x-fail the test. <rdar://problem/26345962> llvm-svn: 270014
This commit is contained in:
parent
4fcff19ff5
commit
906d91e762
|
@ -0,0 +1,77 @@
|
|||
"""
|
||||
Test that breakpoints set on a bad address say they are bad.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
|
||||
import os, time
|
||||
import re
|
||||
import lldb
|
||||
import lldbsuite.test.lldbutil as lldbutil
|
||||
from lldbsuite.test.lldbtest import *
|
||||
|
||||
class BadAddressBreakpointTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
def test_bad_address_breakpoints (self):
|
||||
"""Test that breakpoints set on a bad address say they are bad."""
|
||||
self.build()
|
||||
self.address_breakpoints()
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
|
||||
def address_breakpoints(self):
|
||||
"""Test that breakpoints set on a bad address say they are bad."""
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
|
||||
# Create a target by the debugger.
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
# Now create a breakpoint on main.c by name 'c'.
|
||||
breakpoint = target.BreakpointCreateBySourceRegex("Set a breakpoint here", lldb.SBFileSpec("main.c"))
|
||||
self.assertTrue(breakpoint and
|
||||
breakpoint.GetNumLocations() == 1,
|
||||
VALID_BREAKPOINT)
|
||||
|
||||
# Get the breakpoint location from breakpoint after we verified that,
|
||||
# indeed, it has one location.
|
||||
location = breakpoint.GetLocationAtIndex(0)
|
||||
self.assertTrue(location and
|
||||
location.IsEnabled(),
|
||||
VALID_BREAKPOINT_LOCATION)
|
||||
|
||||
launch_info = lldb.SBLaunchInfo(None)
|
||||
|
||||
error = lldb.SBError()
|
||||
|
||||
process = target.Launch (launch_info, error)
|
||||
self.assertTrue(process, PROCESS_IS_VALID)
|
||||
|
||||
# Did we hit our breakpoint?
|
||||
from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
|
||||
threads = get_threads_stopped_at_breakpoint (process, breakpoint)
|
||||
self.assertTrue(len(threads) == 1, "There should be a thread stopped at our breakpoint")
|
||||
|
||||
# The hit count for the breakpoint should be 1.
|
||||
self.assertTrue(breakpoint.GetHitCount() == 1)
|
||||
|
||||
# Now see if we can read from 0. If I can't do that, I don't have a good way to know
|
||||
# what an illegal address is...
|
||||
error.Clear()
|
||||
|
||||
ptr = process.ReadPointerFromMemory(0x0, error)
|
||||
|
||||
if not error.Success():
|
||||
bkpt = target.BreakpointCreateByAddress(0x0)
|
||||
for bp_loc in bkpt:
|
||||
self.assertTrue(bp_loc.IsResolved() == False)
|
||||
else:
|
||||
self.fail("Could not find an illegal address at which to set a bad breakpoint.")
|
||||
|
||||
|
|
@ -3307,7 +3307,8 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
|
|||
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) && (!bp_site->HardwareRequired()))
|
||||
{
|
||||
// Try to send off a software breakpoint packet ($Z0)
|
||||
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size) == 0)
|
||||
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size);
|
||||
if (error_no == 0)
|
||||
{
|
||||
// The breakpoint was placed successfully
|
||||
bp_site->SetEnabled(true);
|
||||
|
@ -3323,7 +3324,13 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
|
|||
// with the error code. If they are now unsupported, then we would like to fall through
|
||||
// and try another form of breakpoint.
|
||||
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
|
||||
{
|
||||
if (error_no != UINT8_MAX)
|
||||
error.SetErrorStringWithFormat("error: %d sending the breakpoint request", errno);
|
||||
else
|
||||
error.SetErrorString("error sending the breakpoint request");
|
||||
return error;
|
||||
}
|
||||
|
||||
// We reach here when software breakpoints have been found to be unsupported. For future
|
||||
// calls to set a breakpoint, we will not attempt to set a breakpoint with a type that is
|
||||
|
@ -3340,7 +3347,8 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
|
|||
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
|
||||
{
|
||||
// Try to send off a hardware breakpoint packet ($Z1)
|
||||
if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size) == 0)
|
||||
uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size);
|
||||
if (error_no == 0)
|
||||
{
|
||||
// The breakpoint was placed successfully
|
||||
bp_site->SetEnabled(true);
|
||||
|
@ -3352,7 +3360,13 @@ ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
|
|||
if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
|
||||
{
|
||||
// Unable to set this hardware breakpoint
|
||||
error.SetErrorString("failed to set hardware breakpoint (hardware breakpoint resources might be exhausted or unavailable)");
|
||||
if (error_no != UINT8_MAX)
|
||||
error.SetErrorStringWithFormat("error: %d sending the hardware breakpoint request "
|
||||
"(hardware breakpoint resources might be exhausted or unavailable)",
|
||||
error_no);
|
||||
else
|
||||
error.SetErrorString("error sending the hardware breakpoint request (hardware breakpoint resources "
|
||||
"might be exhausted or unavailable)");
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue