PR python/19293 - invalidate frame cache when unwinders change
authorTom Tromey <tom@tromey.com>
Thu, 9 Jun 2016 21:20:09 +0000 (15:20 -0600)
committerTom Tromey <tom@tromey.com>
Tue, 12 Jul 2016 19:56:07 +0000 (13:56 -0600)
PR python/19293 notes that when a Python unwinder is disabled, the
frame cache is not invalidated.  This means that disabling an unwinder
doesn't have any immediate effect -- but in my experience it's often
the case that I want to enable or disable an unwinder in order to see
what happens.

This patch adds a new gdb.invalidate_cached_frames function and
arranges for the relevant bits of library code to call it.  I've only
partially documented this function, considering a warning sufficient
without going into all the reasons ordinary code should not call it.
The name of the new function was taken from a comment in frame.h next
to reinit_frame_cache.

No new test as I think the updates to the existing test are sufficient
to show that the code is working as intended.

Built and regtested on x86-64 Fedora 23.

2016-07-12  Tom Tromey  <tom@tromey.com>

PR python/19293:
* python/lib/gdb/command/unwinders.py (do_enable_unwinder): Call
gdb.invalidate_cached_frames.
* python/lib/gdb/unwinder.py (register_unwinder): Call
gdb.invalidate_cached_frames.
* python/python.c (gdbpy_invalidate_cached_frames): New function.
(python_GdbMethods): Add entry for invalidate_cached_frames.

2016-07-12  Tom Tromey  <tom@tromey.com>

PR python/19293:
* python.texi (Frames In Python): Document
gdb.invalidate_cached_frames.

2016-07-12  Tom Tromey  <tom@tromey.com>

PR python/19293:
* gdb.python/py-unwind-maint.exp: Update tests.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/python.texi
gdb/python/lib/gdb/command/unwinders.py
gdb/python/lib/gdb/unwinder.py
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-unwind-maint.exp

index 92c13374928d23337ea7ee73b41cb5673cb5534c..4139a293f4c59b106e342736e6f49b410d967e7b 100644 (file)
@@ -1,3 +1,13 @@
+2016-07-12  Tom Tromey  <tom@tromey.com>
+
+       PR python/19293:
+       * python/lib/gdb/command/unwinders.py (do_enable_unwinder): Call
+       gdb.invalidate_cached_frames.
+       * python/lib/gdb/unwinder.py (register_unwinder): Call
+       gdb.invalidate_cached_frames.
+       * python/python.c (gdbpy_invalidate_cached_frames): New function.
+       (python_GdbMethods): Add entry for invalidate_cached_frames.
+
 2016-07-07  Walfred Tedeschi  <walfred.tedeschi@intel.com>
 
        * cp-namespace.c (cp_lookup_bare_symbol): Initialize 
index 3186ff2311c09b4f36d763c8fe3d079dc3fc7628..385ca412d73c5ad1a243afd696d04f0e6590aa7c 100644 (file)
@@ -1,3 +1,9 @@
+2016-07-12  Tom Tromey  <tom@tromey.com>
+
+       PR python/19293:
+       * python.texi (Frames In Python): Document
+       gdb.invalidate_cached_frames.
+
 2016-06-21  Pedro Alves  <palves@redhat.com>
 
        * gdb.texinfo (Interpreters): Update intepreter-exec section,
index 6623d8e1df89d13a00c4735d7caff4c6a0b08757..f218ad6089c51894d40d410aa6e9ecff706b9e07 100644 (file)
@@ -3838,6 +3838,15 @@ frames, as expressed by the given @var{reason} code (an integer, see the
 @code{unwind_stop_reason} method further down in this section).
 @end defun
 
+@findex gdb.invalidate_cached_frames
+@defun gdb.invalidate_cached_frames
+@value{GDBN} internally keeps a cache of the frames that have been
+unwound.  This function invalidates this cache.
+
+This function should not generally be called by ordinary Python code.
+It is documented for the sake of completeness.
+@end defun
+
 A @code{gdb.Frame} object has the following methods:
 
 @defun Frame.is_valid ()
index a9b9d8a89f8711bc4e0cd7a087e6d099a3617ab7..8fd013606073b997b0fcf7bbe09b9887f1947cec 100644 (file)
@@ -136,6 +136,8 @@ def do_enable_unwinder(arg, flag):
         if locus_re.match(objfile.filename):
             total += do_enable_unwinder1(objfile.frame_unwinders, name_re,
                                          flag)
+    if total > 0:
+        gdb.invalidate_cached_frames()
     print("%d unwinder%s %s" % (total, "" if total == 1 else "s",
                                 "enabled" if flag else "disabled"))
 
index 14b275855d42f0d531731d0579a04d0f6a13436a..67a37cb594bbb3baf45a99a609b92ccd718535e6 100644 (file)
@@ -92,3 +92,4 @@ def register_unwinder(locus, unwinder, replace=False):
                                    unwinder.name)
         i += 1
     locus.frame_unwinders.insert(0, unwinder)
+    gdb.invalidate_cached_frames()
index 3a272a9025c7cff32b87b366c5e5565611e42b05..621e2012ae79a95cedf407da0214cd8c0cf44b7f 100644 (file)
@@ -885,6 +885,15 @@ gdbpy_find_pc_line (PyObject *self, PyObject *args)
   return result;
 }
 
+/* Implementation of gdb.invalidate_cached_frames.  */
+
+static PyObject *
+gdbpy_invalidate_cached_frames (PyObject *self, PyObject *args)
+{
+  reinit_frame_cache ();
+  Py_RETURN_NONE;
+}
+
 /* Read a file as Python code.
    This is the extension_language_script_ops.script_sourcer "method".
    FILE is the file to load.  FILENAME is name of the file FILE.
@@ -2071,6 +2080,12 @@ Return the selected inferior object." },
   { "inferiors", gdbpy_inferiors, METH_NOARGS,
     "inferiors () -> (gdb.Inferior, ...).\n\
 Return a tuple containing all inferiors." },
+
+  { "invalidate_cached_frames", gdbpy_invalidate_cached_frames, METH_NOARGS,
+    "invalidate_cached_frames () -> None.\n\
+Invalidate any cached frame objects in gdb.\n\
+Intended for internal use only." },
+
   {NULL, NULL, 0, NULL}
 };
 
index a83c9f8ab8670760d262fbca2fac0250482f4a2d..851487f77096ad525a76eb582f38dd452fb7de90 100644 (file)
@@ -1,3 +1,8 @@
+2016-07-12  Tom Tromey  <tom@tromey.com>
+
+       PR python/19293:
+       * gdb.python/py-unwind-maint.exp: Update tests.
+
 2016-07-12  Yao Qi  <yao.qi@linaro.org>
 
        * lib/selftest-support.exp (selftest_setup): Match the output
index e89d28447adf85cca3b5a106da483bd920b1eb05..3a98cb13f6caf382bd1c58945231d868ab4cd85d 100644 (file)
@@ -34,7 +34,11 @@ if ![runto_main ] then {
     return -1
 }
 
-gdb_test "source ${pyfile}" "Python script imported" "import python scripts"
+gdb_test_sequence "source ${pyfile}" "import python scripts" {
+    "Python script imported"
+    "py_unwind_maint_ps_unwinder called"
+    "global_unwinder called"
+}
 
 gdb_test_sequence "info unwinder" "Show all unwinders" {
     "Global:"
@@ -50,7 +54,10 @@ gdb_test_sequence "continue" "Unwinders called" {
     "global_unwinder called"
 }
 
-gdb_test "disable unwinder global .*" "1 unwinder disabled" "Unwinder disabled"
+gdb_test_sequence "disable unwinder global .*" "Unwinder disabled" {
+    "1 unwinder disabled"
+    "py_unwind_maint_ps_unwinder called"
+}
 
 gdb_test_sequence "info unwinder" "Show with global unwinder disabled" {
     "Global:"