xref: /llvm-project/lldb/test/API/macosx/profile_vrs_detach/TestDetachVrsProfile.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
1"""
2debugserver used to block replying to the 'D' packet
3till it had joined the profiling thread.  If the profiling interval
4was too long, that would mean it would take longer than the packet
5timeout to reply, and the detach would time out.  Make sure that doesn't
6happen.
7"""
8
9
10import lldb
11import lldbsuite.test.lldbutil as lldbutil
12from lldbsuite.test.lldbtest import *
13from lldbsuite.test.decorators import *
14import os
15import signal
16
17
18class TestDetachVrsProfile(TestBase):
19    NO_DEBUG_INFO_TESTCASE = True
20
21    @skipUnlessDarwin
22    @skipIfOutOfTreeDebugserver
23    @skipIfRemote
24    def test_profile_and_detach(self):
25        """There can be many tests in a test case - describe this test here."""
26        self.build()
27        self.main_source_file = lldb.SBFileSpec("main.c")
28        self.do_profile_and_detach()
29
30    def do_profile_and_detach(self):
31        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
32            self, "Set a breakpoint here", self.main_source_file
33        )
34
35        interp = self.dbg.GetCommandInterpreter()
36        result = lldb.SBCommandReturnObject()
37
38        # First make sure we are getting async data.  Set a short interval, continue a bit and check:
39        interp.HandleCommand(
40            "process plugin packet send 'QSetEnableAsyncProfiling;enable:1;interval_usec:500000;scan_type=0x5;'",
41            result,
42        )
43        self.assertTrue(
44            result.Succeeded(), "process packet send failed: %s" % (result.GetError())
45        )
46
47        # Run a bit to give us a change to collect profile data:
48        bkpt.SetIgnoreCount(1)
49        threads = lldbutil.continue_to_breakpoint(process, bkpt)
50        self.assertEqual(len(threads), 1, "Hit our breakpoint again.")
51        str = process.GetAsyncProfileData(1000)
52        self.assertGreater(len(str), 0, "Got some profile data")
53
54        # Now make the profiling interval very long and try to detach.
55        interp.HandleCommand(
56            "process plugin packet send 'QSetEnableAsyncProfiling;enable:1;interval_usec:10000000;scan_type=0x5;'",
57            result,
58        )
59        self.assertTrue(
60            result.Succeeded(), "process packet send failed: %s" % (result.GetError())
61        )
62        self.dbg.SetAsync(True)
63        listener = self.dbg.GetListener()
64
65        # We don't want to hit our breakpoint anymore.
66        bkpt.SetEnabled(False)
67
68        # Record our process pid so we can kill it since we are going to detach...
69        self.pid = process.GetProcessID()
70
71        def cleanup():
72            self.dbg.SetAsync(False)
73            os.kill(self.pid, signal.SIGKILL)
74
75        self.addTearDownHook(cleanup)
76
77        process.Continue()
78
79        event = lldb.SBEvent()
80        success = listener.WaitForEventForBroadcaster(
81            0, process.GetBroadcaster(), event
82        )
83        self.assertTrue(success, "Got an event which should be running.")
84        event_state = process.GetStateFromEvent(event)
85        self.assertState(event_state, lldb.eStateRunning, "Got the running event")
86
87        # Now detach:
88        error = process.Detach()
89        self.assertSuccess(error, "Detached successfully")
90