From a2456ef50d41bb5679b1cd73372bbc1ea1c1268a Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Fri, 14 Jun 2019 16:04:57 -0700 Subject: 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. --- debug/gdbserver.py | 16 ++++++++-------- debug/testlib.py | 53 ++++++++++++++++++++++++++++++++++++++--------------- 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): -- cgit v1.1