5 changed files with 126 additions and 4 deletions
@ -0,0 +1,27 @@ |
|||
#include <stdio.h> |
|||
|
|||
char c = 'x'; |
|||
|
|||
void print_row(int length) |
|||
{ |
|||
for (int x=0; x<length; x++) { |
|||
printf("%c", c); |
|||
} |
|||
printf("\n"); |
|||
} |
|||
|
|||
int main() |
|||
{ |
|||
volatile int i = 42; |
|||
const char *text = "constant\n"; |
|||
int threshold = 7; |
|||
|
|||
// Wait for the debugger to get us out of this loop.
|
|||
while (i) |
|||
; |
|||
|
|||
printf("%s", text); |
|||
for (int y=0; y < 10; y++) { |
|||
print_row(y); |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
#!/usr/bin/python |
|||
|
|||
import os |
|||
import testlib |
|||
import unittest |
|||
import tempfile |
|||
import time |
|||
|
|||
class SmokeTest(unittest.TestCase): |
|||
def setUp(self): |
|||
self.tmpf = tempfile.NamedTemporaryFile() |
|||
testlib.compile("debug.c", self.tmpf.name) |
|||
self.spike = testlib.spike(self.tmpf.name, halted=False) |
|||
self.gdb = testlib.Gdb() |
|||
self.gdb.command("file %s" % self.tmpf.name) |
|||
self.gdb.command("target extended-remote localhost:9824") |
|||
self.gdb.command("p i"); |
|||
self.gdb.command("p i=0"); |
|||
|
|||
def cleanUp(self): |
|||
self.spike.kill() |
|||
|
|||
def test_turbostep(self): |
|||
"""Single step until the program exits. TODO""" |
|||
last_pc = None |
|||
for _ in range(100): |
|||
self.gdb.command("stepi") |
|||
pc = self.gdb.command("p $pc") |
|||
self.assertNotEqual(last_pc, pc) |
|||
last_pc = pc |
|||
|
|||
def test_exit(self): |
|||
output = self.gdb.command("c") |
|||
self.assertIn("Continuing", output) |
|||
self.assertIn("Remote connection closed", output) |
|||
|
|||
def test_breakpoint(self): |
|||
self.gdb.command("b print_row") |
|||
# The breakpoint should be hit exactly 10 times. |
|||
for _ in range(10): |
|||
output = self.gdb.command("c") |
|||
self.assertIn("Continuing", output) |
|||
self.assertIn("Breakpoint 1", output) |
|||
output = self.gdb.command("c") |
|||
self.assertIn("Continuing", output) |
|||
self.assertIn("Remote connection closed", output) |
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
|||
@ -0,0 +1,46 @@ |
|||
import os.path |
|||
import pexpect |
|||
import subprocess |
|||
import tempfile |
|||
import testlib |
|||
import unittest |
|||
|
|||
# Note that gdb comes with its own testsuite. I was unable to figure out how to |
|||
# run that testsuite against the spike simulator. |
|||
|
|||
def find_file(path): |
|||
for directory in (os.getcwd(), os.path.dirname(testlib.__file__)): |
|||
fullpath = os.path.join(directory, path) |
|||
if os.path.exists(fullpath): |
|||
return fullpath |
|||
raise ValueError("Couldn't find %r." % path) |
|||
|
|||
def compile(src, dst): |
|||
"""Compile a single .c file into a binary.""" |
|||
cc = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gcc") |
|||
return os.system("%s -g -o %s %s" % (cc, dst, find_file(src))) |
|||
|
|||
def spike(binary, halted=False): |
|||
cmd = [find_file("spike")] |
|||
if halted: |
|||
cmd.append('-H') |
|||
cmd += ['pk', binary] |
|||
logfile = open("spike.log", "w") |
|||
return subprocess.Popen(cmd, stdout=logfile, stderr=logfile) |
|||
|
|||
class Gdb(object): |
|||
def __init__(self): |
|||
path = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gdb") |
|||
self.child = pexpect.spawn(path) |
|||
self.child.logfile = file("gdb.log", "w") |
|||
self.wait() |
|||
|
|||
def wait(self): |
|||
"""Wait for prompt.""" |
|||
self.child.expect("\(gdb\)") |
|||
|
|||
def command(self, command): |
|||
self.child.sendline(command) |
|||
self.child.expect("\n") |
|||
self.child.expect("\(gdb\)") |
|||
return self.child.before.strip() |
|||
Loading…
Reference in new issue