1952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen"""Disassemble lldb's Driver::MainLoop() functions comparing lldb against gdb.""" 2952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 3952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenimport os, sys 4952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenimport unittest2 5952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenimport lldb 6952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenimport pexpect 7952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenfrom lldbbench import * 8952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 964b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chendef is_exe(fpath): 1064b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen """Returns true if fpath is an executable.""" 1164b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 1264b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen 13952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenclass DisassembleDriverMainLoop(BenchBase): 14952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 153a9c0967d3987d50e5f0a30fbbcdfce2e9c7dccaJohnny Chen mydir = os.path.join("benchmarks", "disassembly") 16952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 17952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen def setUp(self): 1864b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen """ 1964b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen Note that lldbExec can be specified with the LLDB_EXEC env variable (see 2064b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen dotest.py), and gdbExec can be specified with the GDB_EXEC env variable. 2164b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen This provides a flexibility in specifying different versions of gdb for 2264b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen comparison purposes. 2364b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen """ 24952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen BenchBase.setUp(self) 2564b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen # If env var GDB_EXEC is specified, use it; otherwise, use gdb in your 2664b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen # PATH env var. 2764b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen if "GDB_EXEC" in os.environ and is_exe(os.environ["GDB_EXEC"]): 2864b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen self.gdbExec = os.environ["GDB_EXEC"] 2964b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen else: 3064b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen self.gdbExec = "gdb" 3164b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen 326033bedc163bc57b5e5c3c1aee8ba81f64b4f11eJohnny Chen self.exe = self.lldbHere 33952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.function = 'Driver::MainLoop()' 34952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.lldb_avg = None 35952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.gdb_avg = None 365f2ed17114c1711a23011c160832b318d77db888Johnny Chen self.count = lldb.bmIterationCount 375f2ed17114c1711a23011c160832b318d77db888Johnny Chen if self.count <= 0: 385f2ed17114c1711a23011c160832b318d77db888Johnny Chen self.count = 5 39952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 40952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen @benchmarks_test 41952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen def test_run_lldb_then_gdb(self): 42952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen """Test disassembly on a large function with lldb vs. gdb.""" 43952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print 44c6e328a322123a276524857242f99e019e56a5deJohnny Chen print "lldb path: %s" % self.lldbExec 45c6e328a322123a276524857242f99e019e56a5deJohnny Chen print "gdb path: %s" % self.gdbExec 46c6e328a322123a276524857242f99e019e56a5deJohnny Chen 47c6e328a322123a276524857242f99e019e56a5deJohnny Chen print 485f2ed17114c1711a23011c160832b318d77db888Johnny Chen self.run_lldb_disassembly(self.exe, self.function, self.count) 49952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "lldb benchmark:", self.stopwatch 505f2ed17114c1711a23011c160832b318d77db888Johnny Chen self.run_gdb_disassembly(self.exe, self.function, self.count) 51952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "gdb benchmark:", self.stopwatch 52952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "lldb_avg/gdb_avg: %f" % (self.lldb_avg/self.gdb_avg) 53952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 54952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen @benchmarks_test 55952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen def test_run_gdb_then_lldb(self): 56952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen """Test disassembly on a large function with lldb vs. gdb.""" 57952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print 58c6e328a322123a276524857242f99e019e56a5deJohnny Chen print "lldb path: %s" % self.lldbExec 59c6e328a322123a276524857242f99e019e56a5deJohnny Chen print "gdb path: %s" % self.gdbExec 60c6e328a322123a276524857242f99e019e56a5deJohnny Chen 61c6e328a322123a276524857242f99e019e56a5deJohnny Chen print 625f2ed17114c1711a23011c160832b318d77db888Johnny Chen self.run_gdb_disassembly(self.exe, self.function, self.count) 63952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "gdb benchmark:", self.stopwatch 645f2ed17114c1711a23011c160832b318d77db888Johnny Chen self.run_lldb_disassembly(self.exe, self.function, self.count) 65952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "lldb benchmark:", self.stopwatch 66952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "lldb_avg/gdb_avg: %f" % (self.lldb_avg/self.gdb_avg) 67952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 68952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen def run_lldb_disassembly(self, exe, function, count): 69952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Set self.child_prompt, which is "(lldb) ". 70952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.child_prompt = '(lldb) ' 71952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen prompt = self.child_prompt 72952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 73952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # So that the child gets torn down after the test. 747d7f447af7fba3eae442ab99c18f5ae532886099Johnny Chen self.child = pexpect.spawn('%s %s %s' % (self.lldbExec, self.lldbOption, exe)) 75952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child = self.child 76952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 77952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Turn on logging for what the child sends back. 78952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen if self.TraceOn(): 79952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.logfile_read = sys.stdout 80952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 81952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 82952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('breakpoint set -F %s' % function) 83952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 84952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('run') 85952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 86952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 87952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Reset the stopwatch now. 88952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.stopwatch.reset() 89952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen for i in range(count): 90952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen with self.stopwatch: 91952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Disassemble the function. 92952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('disassemble -f') 93952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 94952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('next') 95952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 96952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 97952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('quit') 98952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen try: 99952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.child.expect(pexpect.EOF) 100952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen except: 101952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen pass 102952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 103952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.lldb_avg = self.stopwatch.avg() 104952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen if self.TraceOn(): 105952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "lldb disassembly benchmark:", str(self.stopwatch) 106952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.child = None 107952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 108952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen def run_gdb_disassembly(self, exe, function, count): 109952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Set self.child_prompt, which is "(gdb) ". 110952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.child_prompt = '(gdb) ' 111952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen prompt = self.child_prompt 112952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 113952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # So that the child gets torn down after the test. 11464b4f192a8e40b2a1e3573227522ee1de508c5b9Johnny Chen self.child = pexpect.spawn('%s --nx %s' % (self.gdbExec, exe)) 115952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child = self.child 116952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 117952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Turn on logging for what the child sends back. 118952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen if self.TraceOn(): 119952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.logfile_read = sys.stdout 120952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 121952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 122952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('break %s' % function) 123952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 124952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('run') 125952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 126952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 127952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Reset the stopwatch now. 128952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.stopwatch.reset() 129952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen for i in range(count): 130952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen with self.stopwatch: 131952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen # Disassemble the function. 132952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('disassemble') 133952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 134952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('next') 135952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact(prompt) 136952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 137952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('quit') 138952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.expect_exact('The program is running. Exit anyway?') 139952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen child.sendline('y') 140952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen try: 141952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.child.expect(pexpect.EOF) 142952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen except: 143952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen pass 144952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 145952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.gdb_avg = self.stopwatch.avg() 146952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen if self.TraceOn(): 147952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen print "gdb disassembly benchmark:", str(self.stopwatch) 148952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen self.child = None 149952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 150952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen 151952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chenif __name__ == '__main__': 152952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen import atexit 153952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen lldb.SBDebugger.Initialize() 154952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen atexit.register(lambda: lldb.SBDebugger.Terminate()) 155952cc2b9f1fdbf4919e06d559d8d0ae27b4bc538Johnny Chen unittest2.main() 156