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