1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
"""Test Python APIs for target (launch and attach), breakpoint, and process."""
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class HelloWorldTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find a couple of the line numbers within main.c.
self.line1 = line_number("main.c", "// Set break point at this line.")
self.line2 = line_number("main.c", "// Waiting to be attached...")
def tearDown(self):
# Destroy process before TestBase.tearDown()
self.dbg.GetSelectedTarget().GetProcess().Destroy()
# Call super's tearDown().
TestBase.tearDown(self)
@skipIfiOSSimulator
def test_with_process_launch_api(self):
"""Create target, breakpoint, launch a process, and then kill it."""
# Get the full path to our executable to be attached/debugged.
exe = "%s_%d" % (self.getBuildArtifact(self.testMethodName), os.getpid())
d = {"EXE": exe}
self.build(dictionary=d)
self.setTearDownCleanup(dictionary=d)
target = self.dbg.CreateTarget(exe)
breakpoint = target.BreakpointCreateByLocation("main.c", self.line1)
# The default state after breakpoint creation should be enabled.
self.assertTrue(
breakpoint.IsEnabled(), "Breakpoint should be enabled after creation"
)
breakpoint.SetEnabled(False)
self.assertTrue(
not breakpoint.IsEnabled(), "Breakpoint.SetEnabled(False) works"
)
breakpoint.SetEnabled(True)
self.assertTrue(breakpoint.IsEnabled(), "Breakpoint.SetEnabled(True) works")
# rdar://problem/8364687
# SBTarget.Launch() issue (or is there some race condition)?
process = target.LaunchSimple(None, None, self.get_process_working_directory())
# The following isn't needed anymore, rdar://8364687 is fixed.
#
# Apply some dances after LaunchProcess() in order to break at "main".
# It only works sometimes.
# self.breakAfterLaunch(process, "main")
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
self.assertIsNotNone(thread)
# The breakpoint should have a hit count of 1.
self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE)
@skipIfiOSSimulator
def test_with_attach_to_process_with_id_api(self):
"""Create target, spawn a process, and attach to it with process id."""
exe = "%s_%d" % (self.testMethodName, os.getpid())
d = {"EXE": exe}
self.build(dictionary=d)
self.setTearDownCleanup(dictionary=d)
target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
# Spawn a new process
token = exe + ".token"
if not lldb.remote_platform:
token = self.getBuildArtifact(token)
if os.path.exists(token):
os.remove(token)
popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
lldbutil.wait_for_file_on_target(self, token)
listener = lldb.SBListener("my.attach.listener")
error = lldb.SBError()
process = target.AttachToProcessWithID(listener, popen.pid, error)
self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
# Let's check the stack traces of the attached process.
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(
stacktraces, exe=False, substrs=["main.c:%d" % self.line2, "(int)argc=2"]
)
@skipIfiOSSimulator
@skipIfAsan # FIXME: Hangs indefinitely.
def test_with_attach_to_process_with_name_api(self):
"""Create target, spawn a process, and attach to it with process name."""
exe = "%s_%d" % (self.testMethodName, os.getpid())
d = {"EXE": exe}
self.build(dictionary=d)
self.setTearDownCleanup(dictionary=d)
target = self.dbg.CreateTarget(self.getBuildArtifact(exe))
# Spawn a new process.
token = exe + ".token"
if not lldb.remote_platform:
token = self.getBuildArtifact(token)
if os.path.exists(token):
os.remove(token)
popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token])
lldbutil.wait_for_file_on_target(self, token)
listener = lldb.SBListener("my.attach.listener")
error = lldb.SBError()
# Pass 'False' since we don't want to wait for new instance of
# "hello_world" to be launched.
name = os.path.basename(exe)
# While we're at it, make sure that passing a None as the process name
# does not hang LLDB.
target.AttachToProcessWithName(listener, None, False, error)
# Also boundary condition test ConnectRemote(), too.
target.ConnectRemote(listener, None, None, error)
process = target.AttachToProcessWithName(listener, name, False, error)
self.assertSuccess(error)
self.assertTrue(process, PROCESS_IS_VALID)
# Verify that after attach, our selected target indeed matches name.
self.expect(
self.dbg.GetSelectedTarget().GetExecutable().GetFilename(),
exe=False,
startstr=name,
)
# Let's check the stack traces of the attached process.
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(
stacktraces, exe=False, substrs=["main.c:%d" % self.line2, "(int)argc=2"]
)
|