1"""Disassemble lldb's Driver::MainLoop() functions comparing lldb against gdb.""" 2 3import os, sys 4import unittest2 5import lldb 6import pexpect 7from lldbbench import * 8 9def is_exe(fpath): 10 """Returns true if fpath is an executable.""" 11 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 12 13class DisassembleDriverMainLoop(BenchBase): 14 15 mydir = os.path.join("benchmarks", "disassembly") 16 17 def setUp(self): 18 """ 19 Note that lldbExec can be specified with the LLDB_EXEC env variable (see 20 dotest.py), and gdbExec can be specified with the GDB_EXEC env variable. 21 This provides a flexibility in specifying different versions of gdb for 22 comparison purposes. 23 """ 24 BenchBase.setUp(self) 25 # If env var GDB_EXEC is specified, use it; otherwise, use gdb in your 26 # PATH env var. 27 if "GDB_EXEC" in os.environ and is_exe(os.environ["GDB_EXEC"]): 28 self.gdbExec = os.environ["GDB_EXEC"] 29 else: 30 self.gdbExec = "gdb" 31 32 self.exe = self.lldbHere 33 self.function = 'Driver::MainLoop()' 34 self.lldb_avg = None 35 self.gdb_avg = None 36 self.count = lldb.bmIterationCount 37 if self.count <= 0: 38 self.count = 5 39 40 @benchmarks_test 41 def test_run_lldb_then_gdb(self): 42 """Test disassembly on a large function with lldb vs. gdb.""" 43 print 44 print "lldb path: %s" % self.lldbExec 45 print "gdb path: %s" % self.gdbExec 46 47 print 48 self.run_lldb_disassembly(self.exe, self.function, self.count) 49 print "lldb benchmark:", self.stopwatch 50 self.run_gdb_disassembly(self.exe, self.function, self.count) 51 print "gdb benchmark:", self.stopwatch 52 print "lldb_avg/gdb_avg: %f" % (self.lldb_avg/self.gdb_avg) 53 54 @benchmarks_test 55 def test_run_gdb_then_lldb(self): 56 """Test disassembly on a large function with lldb vs. gdb.""" 57 print 58 print "lldb path: %s" % self.lldbExec 59 print "gdb path: %s" % self.gdbExec 60 61 print 62 self.run_gdb_disassembly(self.exe, self.function, self.count) 63 print "gdb benchmark:", self.stopwatch 64 self.run_lldb_disassembly(self.exe, self.function, self.count) 65 print "lldb benchmark:", self.stopwatch 66 print "lldb_avg/gdb_avg: %f" % (self.lldb_avg/self.gdb_avg) 67 68 def run_lldb_disassembly(self, exe, function, count): 69 # Set self.child_prompt, which is "(lldb) ". 70 self.child_prompt = '(lldb) ' 71 prompt = self.child_prompt 72 73 # So that the child gets torn down after the test. 74 self.child = pexpect.spawn('%s %s %s' % (self.lldbExec, self.lldbOption, exe)) 75 child = self.child 76 77 # Turn on logging for what the child sends back. 78 if self.TraceOn(): 79 child.logfile_read = sys.stdout 80 81 child.expect_exact(prompt) 82 child.sendline('breakpoint set -F %s' % function) 83 child.expect_exact(prompt) 84 child.sendline('run') 85 child.expect_exact(prompt) 86 87 # Reset the stopwatch now. 88 self.stopwatch.reset() 89 for i in range(count): 90 with self.stopwatch: 91 # Disassemble the function. 92 child.sendline('disassemble -f') 93 child.expect_exact(prompt) 94 child.sendline('next') 95 child.expect_exact(prompt) 96 97 child.sendline('quit') 98 try: 99 self.child.expect(pexpect.EOF) 100 except: 101 pass 102 103 self.lldb_avg = self.stopwatch.avg() 104 if self.TraceOn(): 105 print "lldb disassembly benchmark:", str(self.stopwatch) 106 self.child = None 107 108 def run_gdb_disassembly(self, exe, function, count): 109 # Set self.child_prompt, which is "(gdb) ". 110 self.child_prompt = '(gdb) ' 111 prompt = self.child_prompt 112 113 # So that the child gets torn down after the test. 114 self.child = pexpect.spawn('%s --nx %s' % (self.gdbExec, exe)) 115 child = self.child 116 117 # Turn on logging for what the child sends back. 118 if self.TraceOn(): 119 child.logfile_read = sys.stdout 120 121 child.expect_exact(prompt) 122 child.sendline('break %s' % function) 123 child.expect_exact(prompt) 124 child.sendline('run') 125 child.expect_exact(prompt) 126 127 # Reset the stopwatch now. 128 self.stopwatch.reset() 129 for i in range(count): 130 with self.stopwatch: 131 # Disassemble the function. 132 child.sendline('disassemble') 133 child.expect_exact(prompt) 134 child.sendline('next') 135 child.expect_exact(prompt) 136 137 child.sendline('quit') 138 child.expect_exact('The program is running. Exit anyway?') 139 child.sendline('y') 140 try: 141 self.child.expect(pexpect.EOF) 142 except: 143 pass 144 145 self.gdb_avg = self.stopwatch.avg() 146 if self.TraceOn(): 147 print "gdb disassembly benchmark:", str(self.stopwatch) 148 self.child = None 149 150 151if __name__ == '__main__': 152 import atexit 153 lldb.SBDebugger.Initialize() 154 atexit.register(lambda: lldb.SBDebugger.Terminate()) 155 unittest2.main() 156