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