Turn off debugging.
[riscv-tests.git] / debug / testlib.py
1 import os.path
2 import pexpect
3 import shlex
4 import subprocess
5 import tempfile
6 import testlib
7 import unittest
8
9 # Note that gdb comes with its own testsuite. I was unable to figure out how to
10 # run that testsuite against the spike simulator.
11
12 def find_file(path):
13 for directory in (os.getcwd(), os.path.dirname(testlib.__file__)):
14 fullpath = os.path.join(directory, path)
15 if os.path.exists(fullpath):
16 return fullpath
17 return None
18
19 def compile(args, xlen=32):
20 """Compile a single .c file into a binary."""
21 dst = os.path.splitext(args[0])[0]
22 cc = os.path.expandvars("$RISCV/bin/riscv%d-unknown-elf-gcc" % xlen)
23 cmd = [cc, "-g", "-o", dst]
24 for arg in args:
25 found = find_file(arg)
26 if found:
27 cmd.append(found)
28 else:
29 cmd.append(arg)
30 cmd = " ".join(cmd)
31 result = os.system(cmd)
32 assert result == 0, "%r failed" % cmd
33 return dst
34
35 def unused_port():
36 # http://stackoverflow.com/questions/2838244/get-open-tcp-port-in-python/2838309#2838309
37 import socket
38 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
39 s.bind(("",0))
40 port = s.getsockname()[1]
41 s.close()
42 return port
43
44 class Spike(object):
45 def __init__(self, cmd, binary=None, halted=False, with_gdb=True, timeout=None,
46 xlen=64):
47 """Launch spike. Return tuple of its process and the port it's running on."""
48 if cmd:
49 cmd = shlex.split(cmd)
50 else:
51 cmd = ["spike"]
52 if (xlen == 32):
53 cmd += ["--isa", "RV32"]
54
55 if timeout:
56 cmd = ["timeout", str(timeout)] + cmd
57
58 if halted:
59 cmd.append('-H')
60 if with_gdb:
61 self.port = unused_port()
62 cmd += ['--gdb-port', str(self.port)]
63 cmd.append('pk')
64 if binary:
65 cmd.append(binary)
66 logfile = open("spike.log", "w")
67 logfile.write("+ %s\n" % " ".join(cmd))
68 self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile,
69 stderr=logfile)
70
71 def __del__(self):
72 try:
73 self.process.kill()
74 self.process.wait()
75 except OSError:
76 pass
77
78 def wait(self, *args, **kwargs):
79 return self.process.wait(*args, **kwargs)
80
81 class Openocd(object):
82 def __init__(self, cmd=None, config=None, debug=False):
83 if cmd:
84 cmd = shlex.split(cmd)
85 else:
86 cmd = ["openocd"]
87 if config:
88 cmd += ["-f", find_file(config)]
89 if debug:
90 cmd.append("-d")
91 logfile = open("openocd.log", "w")
92 logfile.write("+ %s\n" % " ".join(cmd))
93 self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile,
94 stderr=logfile)
95 # TODO: Pick a random port
96 self.port = 3333
97
98 def __del__(self):
99 try:
100 self.process.kill()
101 self.process.wait()
102 except OSError:
103 pass
104
105 class Gdb(object):
106 def __init__(self,
107 path=os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gdb")):
108 self.child = pexpect.spawn(path)
109 self.child.logfile = file("gdb.log", "w")
110 self.child.logfile.write("+ %s\n" % path)
111 self.wait()
112 self.command("set confirm off")
113 self.command("set width 0")
114 self.command("set height 0")
115 # Force consistency.
116 self.command("set print entry-values no")
117
118 def wait(self):
119 """Wait for prompt."""
120 self.child.expect("\(gdb\)")
121
122 def command(self, command, timeout=-1):
123 self.child.sendline(command)
124 self.child.expect("\n", timeout=timeout)
125 self.child.expect("\(gdb\)", timeout=timeout)
126 return self.child.before.strip()
127
128 def c(self, wait=True):
129 if wait:
130 output = self.command("c")
131 assert "Continuing" in output
132 return output
133 else:
134 self.child.sendline("c")
135 self.child.expect("Continuing")
136
137 def interrupt(self):
138 self.child.send("\003");
139 self.child.expect("\(gdb\)")
140 return self.child.before.strip()
141
142 def x(self, address, size='w'):
143 output = self.command("x/%s %s" % (size, address))
144 value = int(output.split(':')[1].strip(), 0)
145 return value
146
147 def p(self, obj):
148 output = self.command("p/x %s" % obj)
149 value = int(output.split('=')[-1].strip(), 0)
150 return value
151
152 def stepi(self):
153 output = self.command("stepi")
154 assert "Cannot" not in output
155 return output
156
157 def load(self):
158 output = self.command("load", timeout=60)
159 assert "failed" not in output
160 assert "Transfer rate" in output
161
162 def b(self, location):
163 output = self.command("b %s" % location)
164 assert "not defined" not in output
165 assert "Breakpoint" in output
166 return output
167
168 def hbreak(self, location):
169 output = self.command("hbreak %s" % location)
170 assert "not defined" not in output
171 assert "Hardware assisted breakpoint" in output
172 return output