aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-06-14 16:04:57 -0700
committerGitHub <noreply@github.com>2019-06-14 16:04:57 -0700
commita2456ef50d41bb5679b1cd73372bbc1ea1c1268a (patch)
tree2626a31a98f875de99e309351cd49960015a24ec
parentb7a0a80210c77c1d817243963ce35fba3ec97851 (diff)
downloadriscv-tests-a2456ef50d41bb5679b1cd73372bbc1ea1c1268a.zip
riscv-tests-a2456ef50d41bb5679b1cd73372bbc1ea1c1268a.tar.gz
riscv-tests-a2456ef50d41bb5679b1cd73372bbc1ea1c1268a.tar.bz2
Work better with mainline gdb (#192)
* Parse floats the way mainline gdb prints them. For 64-bit floats, it shows both float and double results. Now more tests pass using mainline gdb. * Disable ANSI when talking to gdb. Helps more tests pass with mainline gdb. * Parse {float=...,double=...} in "info registers" Makes tests work better with mainline gdb.
-rwxr-xr-xdebug/gdbserver.py16
-rw-r--r--debug/testlib.py53
2 files changed, 46 insertions, 23 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index 754c560..8c58b6b 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -123,16 +123,16 @@ class SimpleF18Test(SimpleRegisterTest):
self.gdb.stepi()
a = random.random()
b = random.random()
- self.gdb.p_raw("$%s=%f" % (name, a))
- assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - a), .001)
+ self.gdb.p_fpr("$%s=%f" % (name, a))
+ assertLess(abs((self.gdb.p_fpr("$%s" % alias)) - a), .001)
self.gdb.stepi()
- assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - a), .001)
- assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - a), .001)
- self.gdb.p_raw("$%s=%f" % (alias, b))
- assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001)
+ assertLess(abs((self.gdb.p_fpr("$%s" % name)) - a), .001)
+ assertLess(abs((self.gdb.p_fpr("$%s" % alias)) - a), .001)
+ self.gdb.p_fpr("$%s=%f" % (alias, b))
+ assertLess(abs((self.gdb.p_fpr("$%s" % name)) - b), .001)
self.gdb.stepi()
- assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001)
- assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - b), .001)
+ assertLess(abs((self.gdb.p_fpr("$%s" % name)) - b), .001)
+ assertLess(abs((self.gdb.p_fpr("$%s" % alias)) - b), .001)
size = self.gdb.p("sizeof($%s)" % name)
if self.hart.extensionSupported('D'):
diff --git a/debug/testlib.py b/debug/testlib.py
index 960f444..0bf8ed1 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -382,6 +382,28 @@ class CouldNotFetch(Exception):
Thread = collections.namedtuple('Thread', ('id', 'description', 'target_id',
'name', 'frame'))
+def parse_rhs(text):
+ text = text.strip()
+ if text.startswith("{") and text.endswith("}"):
+ inner = text[1:-1]
+ parsed = [parse_rhs(t) for t in inner.split(", ")]
+ if all([isinstance(p, dict) for p in parsed]):
+ dictionary = {}
+ for p in parsed:
+ for k, v in p.iteritems():
+ dictionary[k] = v
+ parsed = dictionary
+ return parsed
+ elif text.startswith('"') and text.endswith('"'):
+ return text[1:-1]
+ elif ' = ' in text:
+ lhs, rhs = text.split(' = ', 1)
+ return {lhs: parse_rhs(rhs)}
+ elif re.match(r"-?\d+\.\d+(e-?\d+)?", text):
+ return float(text)
+ else:
+ return int(text, 0)
+
class Gdb(object):
"""A single gdb class which can interact with one or more gdb instances."""
@@ -419,6 +441,7 @@ class Gdb(object):
for port, child in zip(self.ports, self.children):
self.select_child(child)
self.wait()
+ self.command("set style enabled off")
self.command("set confirm off")
self.command("set width 0")
self.command("set height 0")
@@ -557,17 +580,7 @@ class Gdb(object):
m = re.search("Cannot access memory at address (0x[0-9a-f]+)", output)
if m:
raise CannotAccess(int(m.group(1), 0))
- return output.split('=')[-1].strip()
-
- def parse_string(self, text):
- text = text.strip()
- if text.startswith("{") and text.endswith("}"):
- inner = text[1:-1]
- return [self.parse_string(t) for t in inner.split(", ")]
- elif text.startswith('"') and text.endswith('"'):
- return text[1:-1]
- else:
- return int(text, 0)
+ return output.split('=', 1)[-1].strip()
def p(self, obj, fmt="/x", ops=1):
output = self.command("p%s %s" % (fmt, obj), ops=ops)
@@ -577,8 +590,14 @@ class Gdb(object):
m = re.search(r"Could not fetch register \"(\w+)\"; (.*)$", output)
if m:
raise CouldNotFetch(m.group(1), m.group(2))
- rhs = output.split('=')[-1]
- return self.parse_string(rhs)
+ rhs = output.split('=', 1)[-1]
+ return parse_rhs(rhs)
+
+ def p_fpr(self, obj, ops=1):
+ result = self.p(obj, fmt="", ops=ops)
+ if isinstance(result, dict):
+ return result['double']
+ return result
def p_string(self, obj):
output = self.command("p %s" % obj)
@@ -589,12 +608,16 @@ class Gdb(object):
output = self.command("info registers %s" % group, ops=5)
result = {}
for line in output.splitlines():
- parts = line.split()
+ m = re.match(r"(\w+)\s+({.*})\s+(\(.*\))", line)
+ if m:
+ parts = m.groups()
+ else:
+ parts = line.split()
name = parts[0]
if "Could not fetch" in line:
result[name] = " ".join(parts[1:])
else:
- result[name] = int(parts[1], 0)
+ result[name] = parse_rhs(parts[1])
return result
def stepi(self):