1"""
2Test that the lldb driver's batch mode works correctly.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11from lldbsuite.test.lldbpexpect import PExpectTest
12
13
14class DriverBatchModeTest(PExpectTest):
15
16    mydir = TestBase.compute_mydir(__file__)
17    source = 'main.c'
18
19    @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) # Randomly fails on buildbot
20    @expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
21    def test_batch_mode_run_crash(self):
22        """Test that the lldb driver's batch mode works correctly."""
23        self.build()
24
25        exe = self.getBuildArtifact("a.out")
26
27        # Pass CRASH so the process will crash and stop in batch mode.
28        extra_args = ['-b',
29            '-o', 'break set -n main',
30            '-o', 'run',
31            '-o', 'continue',
32            '-k', 'frame var touch_me_not',
33            '--', 'CRASH',
34        ]
35        self.launch(executable=exe, extra_args=extra_args)
36        child = self.child
37
38        # We should see the "run":
39        child.expect_exact("run")
40        # We should have hit the breakpoint & continued:
41        child.expect_exact("continue")
42        # The App should have crashed:
43        child.expect_exact("About to crash")
44        # The -k option should have printed the frame variable once:
45        child.expect_exact('(char *) touch_me_not')
46        # Then we should have a live prompt:
47        self.expect_prompt()
48        self.expect("frame variable touch_me_not", substrs=['(char *) touch_me_not'])
49
50    @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) # Randomly fails on buildbot
51    @expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
52    def test_batch_mode_run_exit(self):
53        """Test that the lldb driver's batch mode works correctly."""
54        self.build()
55
56        exe = self.getBuildArtifact("a.out")
57
58        # Now do it again, and make sure if we don't crash, we quit:
59        extra_args = ['-b',
60            '-o', 'break set -n main',
61            '-o', 'run',
62            '-o', 'continue',
63            '--', 'NOCRASH',
64        ]
65        self.launch(executable=exe, extra_args=extra_args)
66        child = self.child
67
68        # We should see the "run":
69        child.expect_exact("run")
70        # We should have hit the breakpoint & continued:
71        child.expect_exact("continue")
72        # The App should have not have crashed:
73        child.expect_exact("Got there on time and it did not crash.")
74
75        # Then lldb should exit.
76        child.expect_exact("exited")
77        import pexpect
78        child.expect(pexpect.EOF)
79
80    @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) # Randomly fails on buildbot
81    @expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
82    def test_batch_mode_launch_stop_at_entry(self):
83        """Test that the lldb driver's batch mode works correctly for process launch."""
84        self.build()
85
86        exe = self.getBuildArtifact("a.out")
87
88        # Launch with the option '--stop-at-entry' stops with a signal (usually SIGSTOP)
89        # that should be suppressed since it doesn't imply a crash and
90        # this is not a reason to exit batch mode.
91        extra_args = ['-b',
92            '-o', 'process launch --stop-at-entry',
93            '-o', 'continue',
94        ]
95        self.launch(executable=exe, extra_args=extra_args)
96        child = self.child
97
98        # Check that the process has been launched:
99        child.expect("Process ([0-9]+) launched:")
100        # We should have continued:
101        child.expect_exact("continue")
102        # The App should have not have crashed:
103        child.expect_exact("Got there on time and it did not crash.")
104
105        # Then lldb should exit.
106        child.expect_exact("exited")
107        import pexpect
108        child.expect(pexpect.EOF)
109
110    def closeVictim(self):
111        if self.victim is not None:
112            self.victim.close()
113            self.victim = None
114
115    @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) # Randomly fails on buildbot
116    @expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot")
117    @expectedFailureNetBSD
118    def test_batch_mode_attach_exit(self):
119        """Test that the lldb driver's batch mode works correctly."""
120        self.build()
121        self.setTearDownCleanup()
122
123        exe = self.getBuildArtifact("a.out")
124
125        # Start up the process by hand, attach to it, and wait for its completion.
126        # Attach is funny, since it looks like it stops with a signal on most Unixen so
127        # care must be taken not to treat that as a reason to exit batch mode.
128
129        # Start up the process by hand and wait for it to get to the wait loop.
130        import pexpect
131        self.victim = pexpect.spawn('%s WAIT' % (exe))
132        if self.victim is None:
133            self.fail("Could not spawn ", exe, ".")
134
135        self.addTearDownHook(self.closeVictim)
136
137        self.victim.expect("PID: ([0-9]+) END")
138        victim_pid = int(self.victim.match.group(1))
139
140        self.victim.expect("Waiting")
141
142        extra_args = [
143            '-b',
144            '-o', 'process attach -p %d'%victim_pid,
145            '-o', "breakpoint set --file '%s' -p 'Stop here to unset keep_waiting' -N keep_waiting"%self.source,
146            '-o', 'continue',
147            '-o', 'break delete keep_waiting',
148            '-o', 'expr keep_waiting = 0',
149            '-o', 'continue',
150        ]
151        self.launch(executable=exe, extra_args=extra_args)
152        child = self.child
153
154        child.expect_exact("attach")
155
156        child.expect_exact(self.PROMPT + "continue")
157
158        child.expect_exact(self.PROMPT + "continue")
159
160        # Then we should see the process exit:
161        child.expect_exact("Process %d exited with status" % (victim_pid))
162
163        self.victim.expect(pexpect.EOF)
164        child.expect(pexpect.EOF)
165