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