Skip to content

Commit 3b15a69

Browse files
committed
Make breakpoint.run test run against LLDB as well as GDB
1 parent 49e30f3 commit 3b15a69

File tree

4 files changed

+119
-45
lines changed

4 files changed

+119
-45
lines changed

src/test/breakpoint.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
from util import *
22

3-
send_gdb('b C')
4-
expect_gdb('Breakpoint 1')
5-
6-
send_gdb('c')
3+
breakpoint_at('C', 1)
4+
cont()
75

86
expect_rr('calling C')
7+
expect_breakpoint_stop(1)
98

10-
expect_gdb('Breakpoint 1(.*) C')
11-
12-
send_gdb('bt')
13-
expect_gdb('#0[^C]+C[^#]+#1[^B]+B[^#]+#2[^A]+A[^#]+#3[^m]+main')
9+
backtrace()
10+
expect_debugger('#0[^C]+C[^#]+#1[^B]+B[^#]+#2[^A]+A[^#]+#3.+main')
1411

1512
ok()

src/test/breakpoint.run

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
source `dirname $0`/util.sh
2-
debug_test_gdb_only
2+
debug_test

src/test/util.py

+73-33
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import pexpect, re, signal, sys, time
22

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' ]
79

810
# Don't use python timeout. Use test-monitor timeout instead.
911
TIMEOUT_SEC = 10000
1012
# The debugger and rr are part of the same process tree, so they share
1113
# stdin/stdout.
1214
child = None
15+
debugger_type = 'GDB'
1316

1417
# Public API
15-
def expect_gdb(what):
18+
def expect_debugger(what):
1619
expect(child, what)
1720

1821
def expect_list(pats):
@@ -28,11 +31,11 @@ def failed(why, e=None):
2831
clean_up()
2932
sys.exit(1)
3033

31-
def interrupt_gdb():
34+
def interrupt_debugger():
3235
try:
3336
child.kill(signal.SIGINT)
3437
except Exception as e:
35-
failed('interrupting gdb', e)
38+
failed('interrupting debugger', e)
3639
expect_gdb('stopped.')
3740

3841
def iterlines_both():
@@ -41,6 +44,22 @@ def iterlines_both():
4144
def last_match():
4245
return child.match
4346

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+
4463
# Restarts and continues execution
4564
def restart_replay(event=0):
4665
if event:
@@ -56,14 +75,46 @@ def restart_replay(event=0):
5675
expect_rr('stopped')
5776
send_gdb('c')
5877

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)
6199

62100
def ok():
63-
send_gdb('q')
64-
send_gdb('y')
101+
send_debugger('quit', 'quit')
102+
send_debugger('y', 'y')
65103
clean_up()
66104

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+
67118
# Internal helpers
68119
def clean_up():
69120
global child
@@ -88,25 +139,6 @@ def expect(prog, what):
88139
except Exception as e:
89140
failed('expecting "%s"'% (what), e)
90141

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-
110142
def send(prog, what):
111143
try:
112144
prog.send(what)
@@ -115,11 +147,19 @@ def send(prog, what):
115147

116148
def set_up():
117149
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'
118157
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'))
120160
child.delaybeforesend = 0
121-
expect_gdb(r'\(rr\)')
161+
expect_debugger(r'\(rr\)')
122162
except Exception as e:
123-
failed('initializing rr and gdb', e)
163+
failed('initializing rr and debugger', e)
124164

125165
set_up()

src/test/util.sh

+40-3
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,28 @@ function do_ps { psflags=$1
336336
$RR_EXE $GLOBAL_OPTIONS ps $psflags
337337
}
338338

339+
# debug_lldb_only <expect-script-name> [replay-args]
340+
#
341+
# Load the "expect" script to drive replay of the recording of |exe|.
342+
# Only LLDB is tested.
343+
function debug_lldb_only { expectscript=$1; replayargs=$2
344+
_RR_TRACE_DIR="$workdir" test-monitor $TIMEOUT debug.err \
345+
python3 $TESTDIR/$expectscript.py --lldb \
346+
$RR_EXE $GLOBAL_OPTIONS replay -o-S -o$TESTDIR/test_setup.lldb $replayargs
347+
if [[ $? == 0 ]]; then
348+
passed_msg lldb
349+
else
350+
failed "debug script failed (lldb)"
351+
echo "--------------------------------------------------"
352+
echo "lldb_rr.log:"
353+
cat lldb_rr.log
354+
echo "--------------------------------------------------"
355+
echo "debug.err:"
356+
cat debug.err
357+
echo "--------------------------------------------------"
358+
fi
359+
}
360+
339361
# debug_gdb_only <expect-script-name> [replay-args]
340362
#
341363
# Load the "expect" script to drive replay of the recording of |exe|.
@@ -345,9 +367,9 @@ function debug_gdb_only { expectscript=$1; replayargs=$2
345367
python3 $TESTDIR/$expectscript.py \
346368
$RR_EXE $GLOBAL_OPTIONS replay -o-n -o-ix -o$TESTDIR/test_setup.gdb $replayargs
347369
if [[ $? == 0 ]]; then
348-
passed
370+
passed_msg gdb
349371
else
350-
failed "debug script failed"
372+
failed "debug script failed (lldb)"
351373
echo "--------------------------------------------------"
352374
echo "gdb_rr.log:"
353375
cat gdb_rr.log
@@ -367,6 +389,10 @@ function passed {
367389
echo "Test '$TESTNAME' PASSED"
368390
}
369391

392+
function passed_msg { msg=$1
393+
echo "Test '$TESTNAME' PASSED ($msg)"
394+
}
395+
370396
function just_check_replay_err {
371397
if [[ $(cat replay.err) != "" ]]; then
372398
failed ": error during replay:"
@@ -470,11 +496,22 @@ function compare_test { token=$1; replayflags=$2;
470496
check $token
471497
}
472498

473-
# debug_test_gdb_only
499+
# debug_test
474500
#
475501
# Record the test name passed to |util.sh|, then replay the recording
476502
# using the "expect" script $test-name.py, which is responsible for
477503
# computing test pass/fail.
504+
function debug_test {
505+
record $TESTNAME
506+
debug_gdb_only $TEST_PREFIX$TESTNAME_NO_BITNESS
507+
debug_lldb_only $TEST_PREFIX$TESTNAME_NO_BITNESS
508+
}
509+
510+
# debug_test_gdb_only
511+
#
512+
# Record the test name passed to |util.sh|, then replay the recording
513+
# using the "expect" script $test-name.py, which is responsible for
514+
# computing test pass/fail. Only GDB is tested.
478515
function debug_test_gdb_only {
479516
record $TESTNAME
480517
debug_gdb_only $TEST_PREFIX$TESTNAME_NO_BITNESS

0 commit comments

Comments
 (0)