blob: effcb8205e3b9b5762de2492748f18f2d7234885 [file]
"""
Test process attach.
"""
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
exe_name = "ProcessAttach" # Must match Makefile
@requireNotWasm("attaching requires launching the inferior as a host process")
class ProcessAttachTestCase(TestBase):
SHARED_BUILD_TESTCASE = False
NO_DEBUG_INFO_TESTCASE = True
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break for main.c.
self.line = line_number("main.cpp", "// Waiting to be attached...")
@skipIfiOSSimulator
def test_attach_to_process_by_id(self):
"""Test attach by process id"""
self.build()
exe = self.getBuildArtifact(exe_name)
# Spawn a new process
popen = self.spawnSubprocess(exe)
self.runCmd("process attach -p " + str(popen.pid))
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
@skipIfiOSSimulator
def test_attach_to_process_by_id_autocontinue(self):
"""Test attach by process id"""
self.build()
exe = self.getBuildArtifact(exe_name)
# Spawn a new process
popen = self.spawnSubprocess(exe)
# Don't wait for the continue to finish.
self.setAsync(True)
self.runCmd("process attach -c -p " + str(popen.pid))
target = self.dbg.GetSelectedTarget()
# Start listening to process events.
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
broadcaster = process.GetBroadcaster()
listener = self.dbg.GetListener()
state = process.GetState()
self.assertEqual(
state, lldb.eStateStopped, "The attach stopped before continuing"
)
# Listen for events until we see the process continue.
event = lldb.SBEvent()
got_running = False
got_event = False
timeout = 180
while listener.WaitForEventForBroadcaster(timeout, broadcaster, event):
state = process.GetState()
got_event = True
if state == lldb.eStateRunning:
got_running = True
break
self.assertTrue(got_event, "Didn't receive any events after attaching")
self.assertTrue(got_running, "Process didn't auto-continue")
def test_attach_to_process_from_different_dir_by_id(self):
"""Test attach by process id"""
newdir = self.getBuildArtifact("newdir")
os.makedirs(newdir, exist_ok=True)
testdir = self.getBuildDir()
exe = os.path.join(newdir, "proc_attach")
self.buildProgram("main.cpp", exe)
# Spawn a new process
popen = self.spawnSubprocess(exe)
os.chdir(newdir)
sourcedir = self.getSourceDir()
self.addTearDownHook(lambda: os.chdir(sourcedir))
self.runCmd("process attach -p " + str(popen.pid))
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
def test_attach_to_process_by_name(self):
"""Test attach by process name"""
self.build()
exe = self.getBuildArtifact(exe_name)
# Spawn a new process
popen = self.spawnSubprocess(exe)
self.runCmd("process attach -n " + exe_name)
target = self.dbg.GetSelectedTarget()
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
@expectedFailureNetBSD
def test_attach_to_process_by_id_correct_executable_offset(self):
"""
Test that after attaching to a process the executable offset
is determined correctly on FreeBSD. This is a regression test
for dyld plugin getting the correct executable path,
and therefore being able to identify it in the module list.
"""
self.build()
exe = self.getBuildArtifact(exe_name)
# In order to reproduce, we must spawn using a relative path.
os.chdir(self.getBuildDir())
sourcedir = self.getSourceDir()
self.addTearDownHook(lambda: os.chdir(sourcedir))
popen = self.spawnSubprocess(os.path.join(os.curdir, os.path.basename(exe)))
self.runCmd("process attach -p " + str(popen.pid))
# Make sure we did not attach too early.
lldbutil.run_break_set_by_file_and_line(
self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False
)
self.runCmd("process continue")
self.expect("v g_val", substrs=["12345"])