1"""Test evaluating expressions repeatedly comparing lldb against gdb."""
2
3from __future__ import print_function
4
5
6import sys
7import lldb
8from lldbsuite.test.lldbbench import BenchBase
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import configuration
12from lldbsuite.test import lldbutil
13
14
15class RepeatedExprsCase(BenchBase):
16
17    def setUp(self):
18        BenchBase.setUp(self)
19        self.source = 'main.cpp'
20        self.line_to_break = line_number(
21            self.source, '// Set breakpoint here.')
22        self.lldb_avg = None
23        self.gdb_avg = None
24        self.count = 100
25
26    @benchmarks_test
27    @expectedFailureAll(
28        oslist=["windows"],
29        bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
30    def test_compare_lldb_to_gdb(self):
31        """Test repeated expressions with lldb vs. gdb."""
32        self.build()
33        self.exe_name = 'a.out'
34
35        print()
36        self.run_lldb_repeated_exprs(self.exe_name, self.count)
37        print("lldb benchmark:", self.stopwatch)
38        self.run_gdb_repeated_exprs(self.exe_name, self.count)
39        print("gdb benchmark:", self.stopwatch)
40        print("lldb_avg/gdb_avg: %f" % (self.lldb_avg / self.gdb_avg))
41
42    def run_lldb_repeated_exprs(self, exe_name, count):
43        import pexpect
44        exe = self.getBuildArtifact(exe_name)
45
46        # Set self.child_prompt, which is "(lldb) ".
47        self.child_prompt = '(lldb) '
48        prompt = self.child_prompt
49
50        # So that the child gets torn down after the test.
51        self.child = pexpect.spawn(
52            '%s %s %s' %
53            (lldbtest_config.lldbExec, self.lldbOption, exe))
54        child = self.child
55
56        # Turn on logging for what the child sends back.
57        if self.TraceOn():
58            child.logfile_read = sys.stdout
59
60        child.expect_exact(prompt)
61        child.sendline(
62            'breakpoint set -f %s -l %d' %
63            (self.source, self.line_to_break))
64        child.expect_exact(prompt)
65        child.sendline('run')
66        child.expect_exact(prompt)
67        expr_cmd1 = 'expr ptr[j]->point.x'
68        expr_cmd2 = 'expr ptr[j]->point.y'
69
70        # Reset the stopwatch now.
71        self.stopwatch.reset()
72        for i in range(count):
73            with self.stopwatch:
74                child.sendline(expr_cmd1)
75                child.expect_exact(prompt)
76                child.sendline(expr_cmd2)
77                child.expect_exact(prompt)
78            child.sendline('process continue')
79            child.expect_exact(prompt)
80
81        child.sendline('quit')
82        try:
83            self.child.expect(pexpect.EOF)
84        except:
85            pass
86
87        self.lldb_avg = self.stopwatch.avg()
88        if self.TraceOn():
89            print("lldb expression benchmark:", str(self.stopwatch))
90        self.child = None
91
92    def run_gdb_repeated_exprs(self, exe_name, count):
93        import pexpect
94        exe = self.getBuildArtifact(exe_name)
95
96        # Set self.child_prompt, which is "(gdb) ".
97        self.child_prompt = '(gdb) '
98        prompt = self.child_prompt
99
100        # So that the child gets torn down after the test.
101        self.child = pexpect.spawn('gdb --nx %s' % exe)
102        child = self.child
103
104        # Turn on logging for what the child sends back.
105        if self.TraceOn():
106            child.logfile_read = sys.stdout
107
108        child.expect_exact(prompt)
109        child.sendline('break %s:%d' % (self.source, self.line_to_break))
110        child.expect_exact(prompt)
111        child.sendline('run')
112        child.expect_exact(prompt)
113        expr_cmd1 = 'print ptr[j]->point.x'
114        expr_cmd2 = 'print ptr[j]->point.y'
115
116        # Reset the stopwatch now.
117        self.stopwatch.reset()
118        for i in range(count):
119            with self.stopwatch:
120                child.sendline(expr_cmd1)
121                child.expect_exact(prompt)
122                child.sendline(expr_cmd2)
123                child.expect_exact(prompt)
124            child.sendline('continue')
125            child.expect_exact(prompt)
126
127        child.sendline('quit')
128        child.expect_exact('The program is running.  Exit anyway?')
129        child.sendline('y')
130        try:
131            self.child.expect(pexpect.EOF)
132        except:
133            pass
134
135        self.gdb_avg = self.stopwatch.avg()
136        if self.TraceOn():
137            print("gdb expression benchmark:", str(self.stopwatch))
138        self.child = None
139