92 lines · python
1"""Test that we handle inferiors which change their process group"""2 3 4import os5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class ChangeProcessGroupTestCase(TestBase):12 NO_DEBUG_INFO_TESTCASE = True13 14 def setUp(self):15 # Call super's setUp().16 TestBase.setUp(self)17 # Find the line number to break for main.c.18 self.line = line_number("main.c", "// Set breakpoint here")19 20 @skipIfFreeBSD # Times out on FreeBSD llvm.org/pr2373121 @skipIfWindows # setpgid call does not exist on Windows22 @expectedFailureAndroid("http://llvm.org/pr23762", api_levels=[16])23 @expectedFailureNetBSD24 @skipIftvOS # fork not available on tvOS.25 @skipIfwatchOS # fork not available on watchOS.26 def test_setpgid(self):27 self.build()28 exe = self.getBuildArtifact("a.out")29 30 # Use a file as a synchronization point between test and inferior.31 pid_file_path = lldbutil.append_to_process_working_directory(32 self, "pid_file_%d" % (int(time.time()))33 )34 self.addTearDownHook(35 lambda: self.run_platform_command("rm %s" % (pid_file_path))36 )37 38 popen = self.spawnSubprocess(exe, [pid_file_path])39 40 pid = lldbutil.wait_for_file_on_target(self, pid_file_path)41 42 # make sure we cleanup the forked child also43 def cleanupChild():44 if lldb.remote_platform:45 lldb.remote_platform.Kill(int(pid))46 else:47 if os.path.exists("/proc/" + pid):48 os.kill(int(pid), signal.SIGKILL)49 50 self.addTearDownHook(cleanupChild)51 52 # Create a target by the debugger.53 target = self.dbg.CreateTarget(exe)54 self.assertTrue(target, VALID_TARGET)55 56 listener = lldb.SBListener("my.attach.listener")57 error = lldb.SBError()58 process = target.AttachToProcessWithID(listener, int(pid), error)59 self.assertTrue(error.Success() and process, PROCESS_IS_VALID)60 61 # set a breakpoint just before the setpgid() call62 lldbutil.run_break_set_by_file_and_line(63 self, "main.c", self.line, num_expected_locations=-164 )65 66 thread = process.GetSelectedThread()67 68 # release the child from its loop69 value = thread.GetSelectedFrame().EvaluateExpression("release_child_flag = 1")70 self.assertTrue(value.IsValid())71 self.assertEqual(value.GetValueAsUnsigned(0), 1)72 process.Continue()73 74 # make sure the child's process group id is different from its pid75 value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")76 self.assertTrue(value.IsValid())77 self.assertNotEqual(value.GetValueAsUnsigned(0), int(pid))78 79 # step over the setpgid() call80 thread.StepOver()81 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonPlanComplete)82 83 # verify that the process group has been set correctly84 # this also checks that we are still in full control of the child85 value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")86 self.assertTrue(value.IsValid())87 self.assertEqual(value.GetValueAsUnsigned(0), int(pid))88 89 # run to completion90 process.Continue()91 self.assertState(process.GetState(), lldb.eStateExited)92