1"""
2Test whether a process started by lldb has no extra file descriptors open.
3"""
4
5
6
7import lldb
8from lldbsuite.test import lldbutil
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test.decorators import *
11
12
13class AvoidsFdLeakTestCase(TestBase):
14
15    NO_DEBUG_INFO_TESTCASE = True
16
17    # The check for descriptor leakage needs to be implemented differently
18    # here.
19    @skipIfWindows
20    @skipIfTargetAndroid()  # Android have some other file descriptors open by the shell
21    @skipIfDarwinEmbedded # <rdar://problem/33888742>  # debugserver on ios has an extra fd open on launch
22    def test_fd_leak_basic(self):
23        self.do_test([])
24
25    # The check for descriptor leakage needs to be implemented differently
26    # here.
27    @skipIfWindows
28    @skipIfTargetAndroid()  # Android have some other file descriptors open by the shell
29    @skipIfDarwinEmbedded # <rdar://problem/33888742>  # debugserver on ios has an extra fd open on launch
30    def test_fd_leak_log(self):
31        self.do_test(["log enable -f '/dev/null' lldb commands"])
32
33    def do_test(self, commands):
34        self.build()
35        exe = self.getBuildArtifact("a.out")
36
37        for c in commands:
38            self.runCmd(c)
39
40        target = self.dbg.CreateTarget(exe)
41
42        process = target.LaunchSimple(
43            None, None, self.get_process_working_directory())
44        self.assertTrue(process, PROCESS_IS_VALID)
45
46        self.assertEqual(
47            process.GetState(), lldb.eStateExited,
48            "Process should have exited.")
49        self.assertEqual(
50            process.GetExitStatus(), 0,
51            "Process returned non-zero status. Were incorrect file descriptors passed?")
52
53    # The check for descriptor leakage needs to be implemented differently
54    # here.
55    @skipIfWindows
56    @skipIfTargetAndroid()  # Android have some other file descriptors open by the shell
57    @skipIfDarwinEmbedded # <rdar://problem/33888742>  # debugserver on ios has an extra fd open on launch
58    def test_fd_leak_multitarget(self):
59        self.build()
60        exe = self.getBuildArtifact("a.out")
61
62        target = self.dbg.CreateTarget(exe)
63        breakpoint = target.BreakpointCreateBySourceRegex(
64            'Set breakpoint here', lldb.SBFileSpec("main.c", False))
65        self.assertTrue(breakpoint, VALID_BREAKPOINT)
66
67        process1 = target.LaunchSimple(
68            None, None, self.get_process_working_directory())
69        self.assertTrue(process1, PROCESS_IS_VALID)
70        self.assertEqual(
71            process1.GetState(), lldb.eStateStopped,
72            "Process should have been stopped.")
73
74        target2 = self.dbg.CreateTarget(exe)
75        process2 = target2.LaunchSimple(
76            None, None, self.get_process_working_directory())
77        self.assertTrue(process2, PROCESS_IS_VALID)
78
79        self.assertEqual(
80            process2.GetState(), lldb.eStateExited,
81            "Process should have exited.")
82        self.assertEqual(
83            process2.GetExitStatus(), 0,
84            "Process returned non-zero status. Were incorrect file descriptors passed?")
85