Extend test gdb.python/py-recurse-unwind.exp
authorKevin Buettner <kevinb@redhat.com>
Mon, 26 Sep 2016 22:00:37 +0000 (15:00 -0700)
committerKevin Buettner <kevinb@redhat.com>
Wed, 16 Nov 2016 18:37:11 +0000 (11:37 -0700)
This patch modifies the unwinder (sniffer) defined in
py-recurse-unwind.py so that, depending upon the value of one of its
class variables, it will take different paths through the code,
testing different functionality.

The original test attempted to obtain the value of an undefined
symbol.

This somewhat expanded test checks to see if 'pc' can be read via
gdb.PendingFrame.read_register() and also via gdb.parse_and_eval().

gdb/testsuite/ChangeLog:

* gdb.python/py-recurse-unwind.c (main): Add loop.
* gdb.python/py-recurse-unwind.py (TestUnwinder): Add calls
to read_register() and gdb.parse_and_eval().  Make each code
call a separate case that can be individually tested.
* gdb.python/py-recurse-unwind.exp (cont_and_backtrace): New
proc. Call cont_and_backtrace for each of the code paths that
we want to test in the unwinder.

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-recurse-unwind.c
gdb/testsuite/gdb.python/py-recurse-unwind.exp
gdb/testsuite/gdb.python/py-recurse-unwind.py

index d9e61f41825bcf27ea9cfdc02848fac7015cf6aa..82126c03f4c2904c569af1c034cc70ff7410a435 100644 (file)
@@ -1,3 +1,13 @@
+2016-11-16  Kevin Buettner  <kevinb@redhat.com>
+
+       * gdb.python/py-recurse-unwind.c (main): Add loop.
+       * gdb.python/py-recurse-unwind.py (TestUnwinder): Add calls
+       to read_register() and gdb.parse_and_eval().  Make each code
+       call a separate case that can be individually tested.
+       * gdb.python/py-recurse-unwind.exp (cont_and_backtrace): New
+       proc. Call cont_and_backtrace for each of the code paths that
+       we want to test in the unwinder.
+
 2016-11-15  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
        * gdb.dwarf2/bitfield-parent-optimized-out.exp: Fix DWARF code for
index 02a835a833c1c5669161cc3deb1f647dcd945e5f..77acec13beead09576e7c2f8caa1cb487cecddc7 100644 (file)
@@ -37,6 +37,10 @@ aaa (int arg)
 int
 main ()
 {
-  aaa (123);
+  int i;
+
+  for (i = 0; i < 10; i++)
+    aaa (123);
+
   return 0;
 }
index 9629a974ba01ecae2da4c658143d635ea99d363e..97c69f7bc432f6bae59c7b2e2c033a437d17b0ea 100644 (file)
@@ -45,29 +45,46 @@ if ![runto_main] then {
     return 0
 }
 
-gdb_breakpoint "ccc"
 
-gdb_continue_to_breakpoint "ccc"
-
-# If the unwinder is active, the usage count will increment while
-# running to the breakpoint.  Reset it prior to doing the backtrace.
-gdb_test_no_output "python TestUnwinder.reset_count()"
-
-# The python based unwinder should be called a number of times while
-# generating the backtrace, but its sniffer always returns None.  So
-# it doesn't really contribute to generating any of the frames below.
-#
-# But that's okay.  Our goal here is to make sure that GDB doesn't
-# get hung up in potentially infinite recursion when invoking the
-# Python-based unwinder.
-
-gdb_test_sequence "bt"  "backtrace" {
-    "\\r\\n#0 .* ccc \\(arg=789\\) at "
-    "\\r\\n#1 .* bbb \\(arg=456\\) at "
-    "\\r\\n#2 .* aaa \\(arg=123\\) at "
-    "\\r\\n#3 .* main \\(.*\\) at"
+proc cont_and_backtrace { tst } {
+
+    with_test_prefix $tst {
+       gdb_breakpoint "ccc"
+
+       # We're testing different code paths within the unwinder's sniffer.
+       # Set the current path to be tested here.
+       gdb_test_no_output "python TestUnwinder.set_test(\"$tst\")" \
+                          "set code path within python unwinder to $tst"
+
+       # If the unwinder is active, the usage count will increment while
+       # running to the breakpoint.  Reset it prior to doing the backtrace.
+       gdb_test_no_output "python TestUnwinder.reset_count()" \
+                          "reset count"
+
+       gdb_continue_to_breakpoint "ccc"
+
+       # The python based unwinder should be called a number of times while
+       # generating the backtrace, but its sniffer always returns None.  So
+       # it doesn't really contribute to generating any of the frames below.
+       #
+       # But that's okay.  Our goal here is to make sure that GDB doesn't
+       # get hung up in potentially infinite recursion when invoking the
+       # Python-based unwinder.
+
+       gdb_test_sequence "bt"  "backtrace" {
+           "\\r\\n#0 .* ccc \\(arg=789\\) at "
+           "\\r\\n#1 .* bbb \\(arg=456\\) at "
+           "\\r\\n#2 .* aaa \\(arg=123\\) at "
+           "\\r\\n#3 .* main \\(.*\\) at"
+       }
+
+       # Test that the python-based unwinder / sniffer was actually called
+       # during generation of the backtrace.
+       gdb_test "python print(TestUnwinder.count > 0)" "True" \
+                "python unwinder called"
+    }
 }
 
-# Test that the python-based unwinder / sniffer was actually called
-# during generation of the backtrace.
-gdb_test "python print(TestUnwinder.count > 0)" "True"
+cont_and_backtrace "check_undefined_symbol"
+cont_and_backtrace "check_user_reg_pc"
+cont_and_backtrace "check_pae_pc"
index 1da7aca9339a78c81c6663df61d9dc3c3fd46b89..5eb87bb0b35f012931759cee9d31de265c4a4763 100644 (file)
@@ -40,13 +40,18 @@ class TestUnwinder(Unwinder):
     def inc_count (cls):
         cls.count += 1
 
+    test = 'check_undefined_symbol'
+
+    @classmethod
+    def set_test (cls, test) :
+       cls.test = test
+
     def __init__(self):
         Unwinder.__init__(self, "test unwinder")
         self.recurse_level = 0
 
     def __call__(self, pending_frame):
 
-
         if self.recurse_level > 0:
             gdb.write("TestUnwinder: Recursion detected - returning early.\n")
             return None
@@ -54,11 +59,25 @@ class TestUnwinder(Unwinder):
         self.recurse_level += 1
         TestUnwinder.inc_count()
 
-        try:
-            val = gdb.parse_and_eval("undefined_symbol")
+        if TestUnwinder.test == 'check_user_reg_pc' :
+
+            pc = pending_frame.read_register('pc')
+            pc_as_int = int(pc.cast(gdb.lookup_type('int')))
+            # gdb.write("In unwinder: pc=%x\n" % pc_as_int)
+
+        elif TestUnwinder.test == 'check_pae_pc' :
+
+            pc = gdb.parse_and_eval('$pc')
+            pc_as_int = int(pc.cast(gdb.lookup_type('int')))
+            # gdb.write("In unwinder: pc=%x\n" % pc_as_int)
+
+        elif TestUnwinder.test == 'check_undefined_symbol' :
+
+            try:
+                val = gdb.parse_and_eval("undefined_symbol")
 
-        except Exception as arg:
-            pass
+            except Exception as arg:
+                pass
 
         self.recurse_level -= 1