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