]> granicus.if.org Git - python/commitdiff
[3.6] bpo-30983: [gdb] Fix py-bt, etc. for non-debug shared builds (GH-3153) (#3192)
authorŁukasz Langa <lukasz@langa.pl>
Tue, 22 Aug 2017 20:20:40 +0000 (13:20 -0700)
committerGitHub <noreply@github.com>
Tue, 22 Aug 2017 20:20:40 +0000 (13:20 -0700)
PEP 523 introduced _PyEval_EvalFrameDefault which inlines PyEval_EvalFrameEx on
non-debug shared builds.  This breaks the ability to use py-bt, py-up, and
a few other Python-specific gdb integrations.

This patch fixes the problem by only looking for _PyEval_EvalFrameDefault
frames.

test_gdb passes on both a debug and a non-debug build.

Original patch by Bruno "Polaco" Penteado.
(cherry picked from commit 5fe59f8e3a0a56a155c18f9d581205ec533764b6)

Misc/ACKS
Misc/NEWS.d/next/Tools-Demos/2017-08-18-17-19-23.bpo-30983.ggGz9z.rst [new file with mode: 0644]
Tools/gdb/libpython.py

index 20e174384ba2c3a7fe145fd1941cbad078c3204a..a67eb0a557ea043faee434d0a7619d994be59419 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1171,6 +1171,7 @@ Berker Peksag
 Andreas Pelme
 Steven Pemberton
 Bo Peng
+Bruno "Polaco" Penteado
 Santiago Peresón
 George Peristerakis
 Thomas Perl
diff --git a/Misc/NEWS.d/next/Tools-Demos/2017-08-18-17-19-23.bpo-30983.ggGz9z.rst b/Misc/NEWS.d/next/Tools-Demos/2017-08-18-17-19-23.bpo-30983.ggGz9z.rst
new file mode 100644 (file)
index 0000000..404263e
--- /dev/null
@@ -0,0 +1,6 @@
+gdb integration commands (py-bt, etc.) work on optimized shared builds now,
+too.  PEP 523 introduced _PyEval_EvalFrameDefault which inlines
+PyEval_EvalFrameEx on non-debug shared builds.  This broke the ability to
+use py-bt, py-up, and a few other Python-specific gdb integrations. The
+problem is fixed by only looking for _PyEval_EvalFrameDefault frames in
+python-gdb.py.  Original patch by Bruno "Polaco" Penteado.
index 31ae8117c785ff466db1a7f1624ccccc404c6853..aac9b5c1b8a77bb1ee30853604f0f74ab7e07f2a 100755 (executable)
@@ -99,6 +99,8 @@ hexdigits = "0123456789abcdef"
 
 ENCODING = locale.getpreferredencoding()
 
+EVALFRAME = '_PyEval_EvalFrameDefault'
+
 class NullPyObjectPtr(RuntimeError):
     pass
 
@@ -1492,18 +1494,18 @@ class Frame(object):
     #   - everything else
 
     def is_python_frame(self):
-        '''Is this a PyEval_EvalFrameEx frame, or some other important
+        '''Is this a _PyEval_EvalFrameDefault frame, or some other important
         frame? (see is_other_python_frame for what "important" means in this
         context)'''
-        if self.is_evalframeex():
+        if self.is_evalframe():
             return True
         if self.is_other_python_frame():
             return True
         return False
 
-    def is_evalframeex(self):
-        '''Is this a PyEval_EvalFrameEx frame?'''
-        if self._gdbframe.name() == 'PyEval_EvalFrameEx':
+    def is_evalframe(self):
+        '''Is this a _PyEval_EvalFrameDefault frame?'''
+        if self._gdbframe.name() == EVALFRAME:
             '''
             I believe we also need to filter on the inline
             struct frame_id.inline_depth, only regarding frames with
@@ -1512,7 +1514,7 @@ class Frame(object):
             So we reject those with type gdb.INLINE_FRAME
             '''
             if self._gdbframe.type() == gdb.NORMAL_FRAME:
-                # We have a PyEval_EvalFrameEx frame:
+                # We have a _PyEval_EvalFrameDefault frame:
                 return True
 
         return False
@@ -1631,7 +1633,7 @@ class Frame(object):
         frame = cls.get_selected_frame()
 
         while frame:
-            if frame.is_evalframeex():
+            if frame.is_evalframe():
                 return frame
             frame = frame.older()
 
@@ -1639,7 +1641,7 @@ class Frame(object):
         return None
 
     def print_summary(self):
-        if self.is_evalframeex():
+        if self.is_evalframe():
             pyop = self.get_pyop()
             if pyop:
                 line = pyop.get_truncated_repr(MAX_OUTPUT_LEN)
@@ -1658,7 +1660,7 @@ class Frame(object):
                 sys.stdout.write('#%i\n' % self.get_index())
 
     def print_traceback(self):
-        if self.is_evalframeex():
+        if self.is_evalframe():
             pyop = self.get_pyop()
             if pyop:
                 pyop.print_traceback()