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