1"""Benchmark the turnaround time starting a debugger and run to the breakpont with lldb vs. gdb."""
2
3import os, sys
4import unittest2
5import lldb
6import pexpect
7from lldbbench import *
8
9class CompileRunToBreakpointBench(BenchBase):
10
11    mydir = os.path.join("benchmarks", "turnaround")
12
13    def setUp(self):
14        BenchBase.setUp(self)
15        self.exe = self.lldbHere
16        self.function = 'Driver::MainLoop()'
17
18        self.count = lldb.bmIterationCount
19        if self.count <= 0:
20            self.count = 3
21
22        self.lldb_avg = None
23        self.gdb_avg = None
24
25    @benchmarks_test
26    def test_run_lldb_then_gdb(self):
27        """Benchmark turnaround time with lldb vs. gdb."""
28        print
29        self.run_lldb_turnaround(self.exe, self.function, self.count)
30        print "lldb turnaround benchmark:", self.stopwatch
31        self.run_gdb_turnaround(self.exe, self.function, self.count)
32        print "gdb turnaround benchmark:", self.stopwatch
33        print "lldb_avg/gdb_avg: %f" % (self.lldb_avg/self.gdb_avg)
34
35    def run_lldb_turnaround(self, exe, function, count):
36        def run_one_round():
37            prompt = self.child_prompt
38
39            # So that the child gets torn down after the test.
40            self.child = pexpect.spawn('%s %s %s' % (self.lldbExec, self.lldbOption, exe))
41            child = self.child
42
43            # Turn on logging for what the child sends back.
44            if self.TraceOn():
45                child.logfile_read = sys.stdout
46
47            child.expect_exact(prompt)
48            child.sendline('breakpoint set -F %s' % function)
49            child.expect_exact(prompt)
50            child.sendline('run')
51            child.expect_exact(prompt)
52
53        # Set self.child_prompt, which is "(lldb) ".
54        self.child_prompt = '(lldb) '
55        # Reset the stopwatch now.
56        self.stopwatch.reset()
57
58        for i in range(count + 1):
59            # Ignore the first invoke lldb and run to the breakpoint turnaround time.
60            if i == 0:
61                run_one_round()
62            else:
63                with self.stopwatch:
64                    run_one_round()
65
66            self.child.sendline('quit')
67            try:
68                self.child.expect(pexpect.EOF)
69            except:
70                pass
71
72        self.lldb_avg = self.stopwatch.avg()
73        self.child = None
74
75    def run_gdb_turnaround(self, exe, function, count):
76        def run_one_round():
77            prompt = self.child_prompt
78
79            # So that the child gets torn down after the test.
80            self.child = pexpect.spawn('gdb --nx %s' % exe)
81            child = self.child
82
83            # Turn on logging for what the child sends back.
84            if self.TraceOn():
85                child.logfile_read = sys.stdout
86
87            child.expect_exact(prompt)
88            child.sendline('break %s' % function)
89            child.expect_exact(prompt)
90            child.sendline('run')
91            child.expect_exact(prompt)
92
93        # Set self.child_prompt, which is "(gdb) ".
94        self.child_prompt = '(gdb) '
95        # Reset the stopwatch now.
96        self.stopwatch.reset()
97
98        for i in range(count+1):
99            # Ignore the first invoke lldb and run to the breakpoint turnaround time.
100            if i == 0:
101                run_one_round()
102            else:
103                with self.stopwatch:
104                    run_one_round()
105
106            self.child.sendline('quit')
107            self.child.expect_exact('The program is running.  Exit anyway?')
108            self.child.sendline('y')
109            try:
110                self.child.expect(pexpect.EOF)
111            except:
112                pass
113
114        self.gdb_avg = self.stopwatch.avg()
115        self.child = None
116
117
118if __name__ == '__main__':
119    import atexit
120    lldb.SBDebugger.Initialize()
121    atexit.register(lambda: lldb.SBDebugger.Terminate())
122    unittest2.main()
123