1
1
import pexpect , re , signal , sys , time
2
2
3
- __all__ = [ 'expect_gdb' , 'send_gdb' ,'expect_rr' , 'expect_list' ,
4
- 'restart_replay' , 'interrupt_gdb' , 'ok' ,
5
- 'failed' , 'iterlines_both' , 'last_match' , 'get_exe_arch' ,
6
- 'get_gdb_version' ]
3
+ __all__ = [ 'expect_rr' , 'expect_list' , 'expect_debugger' ,
4
+ 'restart_replay' , 'interrupt_gdb' , 'expect_gdb' , 'send_gdb' ,
5
+ 'ok' , 'failed' , 'iterlines_both' , 'last_match' , 'get_exe_arch' ,
6
+ 'get_gdb_version' ,
7
+ 'breakpoint_at' , 'cont' , 'backtrace' ,
8
+ 'expect_breakpoint_stop' ]
7
9
8
10
# Don't use python timeout. Use test-monitor timeout instead.
9
11
TIMEOUT_SEC = 10000
10
12
# The debugger and rr are part of the same process tree, so they share
11
13
# stdin/stdout.
12
14
child = None
15
+ debugger_type = 'GDB'
13
16
14
17
# Public API
15
- def expect_gdb (what ):
18
+ def expect_debugger (what ):
16
19
expect (child , what )
17
20
18
21
def expect_list (pats ):
@@ -28,11 +31,11 @@ def failed(why, e=None):
28
31
clean_up ()
29
32
sys .exit (1 )
30
33
31
- def interrupt_gdb ():
34
+ def interrupt_debugger ():
32
35
try :
33
36
child .kill (signal .SIGINT )
34
37
except Exception as e :
35
- failed ('interrupting gdb ' , e )
38
+ failed ('interrupting debugger ' , e )
36
39
expect_gdb ('stopped.' )
37
40
38
41
def iterlines_both ():
@@ -41,6 +44,22 @@ def iterlines_both():
41
44
def last_match ():
42
45
return child .match
43
46
47
+ def expect_gdb (what ):
48
+ assert debugger_type == 'GDB'
49
+ expect_debugger (what )
50
+
51
+ def interrupt_gdb ():
52
+ assert debugger_type == 'GDB'
53
+ interrupt_debugger ()
54
+
55
+ def send_gdb (what ):
56
+ assert debugger_type == 'GDB'
57
+ send (child , "%s\n " % what )
58
+
59
+ def send_lldb (what ):
60
+ assert debugger_type == 'LLDB'
61
+ send (child , "%s\n " % what )
62
+
44
63
# Restarts and continues execution
45
64
def restart_replay (event = 0 ):
46
65
if event :
@@ -56,14 +75,46 @@ def restart_replay(event=0):
56
75
expect_rr ('stopped' )
57
76
send_gdb ('c' )
58
77
59
- def send_gdb (what ):
60
- send (child , "%s\n " % what )
78
+ def breakpoint_at (location , expected_number ):
79
+ send_debugger ('b %s' % location , 'b %s' % location )
80
+ expect_debugger ('Breakpoint %d' % expected_number )
81
+
82
+ def cont ():
83
+ send_debugger ('continue' , 'continue' )
84
+
85
+ def backtrace ():
86
+ send_debugger ('bt' , 'thread backtrace' )
87
+
88
+ def expect_breakpoint_stop (number ):
89
+ if debugger_type == 'GDB' :
90
+ expect_debugger ("Breakpoint %d" % number )
91
+ else :
92
+ expect_debugger ("stop reason = breakpoint %d" % number )
93
+
94
+ def send_debugger (gdb_cmd , lldb_cmd ):
95
+ if debugger_type == 'GDB' :
96
+ send_gdb (gdb_cmd )
97
+ else :
98
+ send_lldb (lldb_cmd )
61
99
62
100
def ok ():
63
- send_gdb ( 'q ' )
64
- send_gdb ( 'y' )
101
+ send_debugger ( 'quit' , 'quit ' )
102
+ send_debugger ( 'y' , 'y' )
65
103
clean_up ()
66
104
105
+ def get_exe_arch ():
106
+ send_gdb ('show architecture' )
107
+ expect_gdb (r'The target architecture is set (automatically|to "auto") \(currently "?([0-9a-z:-]+)"?\)\.?' )
108
+ global child
109
+ return child .match .group (2 )
110
+
111
+ def get_gdb_version ():
112
+ '''Return the gdb version'''
113
+ send_gdb ('python print(gdb.VERSION)' )
114
+ expect_gdb (r'(\d+.\d+)' )
115
+ global child
116
+ return float (child .match .group (1 ))
117
+
67
118
# Internal helpers
68
119
def clean_up ():
69
120
global child
@@ -88,25 +139,6 @@ def expect(prog, what):
88
139
except Exception as e :
89
140
failed ('expecting "%s"' % (what ), e )
90
141
91
- def get_exe_arch ():
92
- send_gdb ('show architecture' )
93
- expect_gdb (r'The target architecture is set (automatically|to "auto") \(currently "?([0-9a-z:-]+)"?\)\.?' )
94
- global child
95
- return child .match .group (2 )
96
-
97
- def get_rr_cmd ():
98
- '''Return the command that should be used to invoke rr, as the tuple
99
- (executable, array-of-args)'''
100
- rrargs = sys .argv [1 :]
101
- return (rrargs [0 ], rrargs [1 :])
102
-
103
- def get_gdb_version ():
104
- '''Return the gdb version'''
105
- send_gdb ('python print(gdb.VERSION)' )
106
- expect_gdb (r'(\d+.\d+)' )
107
- global child
108
- return float (child .match .group (1 ))
109
-
110
142
def send (prog , what ):
111
143
try :
112
144
prog .send (what )
@@ -115,11 +147,19 @@ def send(prog, what):
115
147
116
148
def set_up ():
117
149
global child
150
+ global debugger_type
151
+ args = sys .argv [1 :]
152
+ log_file = 'gdb_rr.log'
153
+ if args [0 ] == '--lldb' :
154
+ debugger_type = 'LLDB'
155
+ args = args [1 :] + ['-d' , 'lldb' , '-o' , '--no-use-colors' ]
156
+ log_file = 'lldb_rr.log'
118
157
try :
119
- child = pexpect .spawn (* get_rr_cmd (), codec_errors = 'ignore' , timeout = TIMEOUT_SEC , encoding = 'utf-8' , logfile = open ('gdb_rr.log' , 'w' ))
158
+ child = pexpect .spawn (args [0 ], args [1 :], codec_errors = 'ignore' ,
159
+ timeout = TIMEOUT_SEC , encoding = 'utf-8' , logfile = open (log_file , 'w' ))
120
160
child .delaybeforesend = 0
121
- expect_gdb (r'\(rr\)' )
161
+ expect_debugger (r'\(rr\)' )
122
162
except Exception as e :
123
- failed ('initializing rr and gdb ' , e )
163
+ failed ('initializing rr and debugger ' , e )
124
164
125
165
set_up ()
0 commit comments