#182 [WIP] Skip test_gdb if Python was optimized
Closed 3 years ago by vstinner. Opened 3 years ago by vstinner.
rpms/ vstinner/python3 test-gdb-optimized-out  into  master

Cleanup patch
Victor Stinner • 3 years ago  
Skip test_gdb if Python was optimized
Victor Stinner • 3 years ago  
@@ -0,0 +1,103 @@ 

+ bpo-40019: Skip test_gdb if Python was optimized (GH-19081)

+ 

+ test_gdb now skips tests if it detects that gdb failed to read debug

+ information because the Python binary is optimized.

+ 

+ Backport commit 7bf069b6110278102c8f4719975a5eb5a5af25f9

+ 

+ diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py

+ index e106033..bd9a5cb 100644

+ --- a/Lib/test/test_gdb.py

+ +++ b/Lib/test/test_gdb.py

+ @@ -230,6 +230,15 @@ class DebuggerTests(unittest.TestCase):

+                                      " because the Program Counter is"

+                                      " not present")

+ 

+ +        # bpo-40019: Skip the test if gdb failed to read debug information

+ +        # because the Python binary is optimized.

+ +        for pattern in (

+ +            '(frame information optimized out)',

+ +            'Unable to read information on python frame',

+ +        ):

+ +            if pattern in out:

+ +                raise unittest.SkipTest(f"{pattern!r} found in gdb output")

+ +

+          return out

+ 

+      def get_gdb_repr(self, source,

+ diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py

+ index 93f997c..d8b2266 100755

+ --- a/Tools/gdb/libpython.py

+ +++ b/Tools/gdb/libpython.py

+ @@ -99,6 +99,8 @@ hexdigits = "0123456789abcdef"

+ 

+  ENCODING = locale.getpreferredencoding()

+ 

+ +FRAME_INFO_OPTIMIZED_OUT = '(frame information optimized out)'

+ +UNABLE_READ_INFO_PYTHON_FRAME = 'Unable to read information on python frame'

+  EVALFRAME = '_PyEval_EvalFrameDefault'

+ 

+  class NullPyObjectPtr(RuntimeError):

+ @@ -918,7 +920,7 @@ class PyFrameObjectPtr(PyObjectPtr):

+      def filename(self):

+          '''Get the path of the current Python source file, as a string'''

+          if self.is_optimized_out():

+ -            return '(frame information optimized out)'

+ +            return FRAME_INFO_OPTIMIZED_OUT

+          return self.co_filename.proxyval(set())

+ 

+      def current_line_num(self):

+ @@ -949,7 +951,7 @@ class PyFrameObjectPtr(PyObjectPtr):

+          '''Get the text of the current source line as a string, with a trailing

+          newline character'''

+          if self.is_optimized_out():

+ -            return '(frame information optimized out)'

+ +            return FRAME_INFO_OPTIMIZED_OUT

+ 

+          lineno = self.current_line_num()

+          if lineno is None:

+ @@ -970,7 +972,7 @@ class PyFrameObjectPtr(PyObjectPtr):

+ 

+      def write_repr(self, out, visited):

+          if self.is_optimized_out():

+ -            out.write('(frame information optimized out)')

+ +            out.write(FRAME_INFO_OPTIMIZED_OUT)

+              return

+          lineno = self.current_line_num()

+          lineno = str(lineno) if lineno is not None else "?"

+ @@ -993,7 +995,7 @@ class PyFrameObjectPtr(PyObjectPtr):

+ 

+      def print_traceback(self):

+          if self.is_optimized_out():

+ -            sys.stdout.write('  (frame information optimized out)\n')

+ +            sys.stdout.write('  %s\n' % FRAME_INFO_OPTIMIZED_OUT)

+              return

+          visited = set()

+          lineno = self.current_line_num()

+ @@ -1744,7 +1746,7 @@ class PyList(gdb.Command):

+ 

+          pyop = frame.get_pyop()

+          if not pyop or pyop.is_optimized_out():

+ -            print('Unable to read information on python frame')

+ +            print(UNABLE_READ_INFO_PYTHON_FRAME)

+              return

+ 

+          filename = pyop.filename()

+ @@ -1904,7 +1906,7 @@ class PyPrint(gdb.Command):

+ 

+          pyop_frame = frame.get_pyop()

+          if not pyop_frame:

+ -            print('Unable to read information on python frame')

+ +            print(UNABLE_READ_INFO_PYTHON_FRAME)

+              return

+ 

+          pyop_var, scope = pyop_frame.get_var_by_name(name)

+ @@ -1938,7 +1940,7 @@ class PyLocals(gdb.Command):

+ 

+          pyop_frame = frame.get_pyop()

+          if not pyop_frame:

+ -            print('Unable to read information on python frame')

+ +            print(UNABLE_READ_INFO_PYTHON_FRAME)

+              return

+ 

+          for pyop_name, pyop_value in pyop_frame.iter_locals():

file modified
+3 -3
@@ -271,6 +271,8 @@ 

  # Ideally, we should talk to upstream and explain why we don't want this

  Patch328: 00328-pyc-timestamp-invalidation-mode.patch

  

+ Patch9999: 9999-test-gdb-optimized-out.patch

+ 

  # (New patches go here ^^^)

  #

  # When adding new patches to "python" and "python3" in Fedora, EL, etc.,
@@ -618,6 +620,7 @@ 

  %patch251 -p1

  %patch274 -p1

  %patch328 -p1

+ %patch9999 -p1

  

  

  # Remove files that should be generated by the build
@@ -1052,8 +1055,6 @@ 

    # --timeout=1800: kill test running for longer than 30 minutes

    # test_gdb skipped on s390x:

    #   https://bugzilla.redhat.com/show_bug.cgi?id=1678277

-   # test_gdb skipped everywhere:

-   #   https://bugzilla.redhat.com/show_bug.cgi?id=1734327

    # test_distutils

    #   distutils.tests.test_bdist_rpm tests fail when bootstraping the Python

    #   package: rpmbuild requires /usr/bin/pythonX.Y to be installed
@@ -1062,7 +1063,6 @@ 

      %if %{with bootstrap}

      -x test_distutils \

      %endif

-     -x test_gdb \

      %ifarch %{mips64}

      -x test_ctypes \

      %endif

Backport commit 7bf069b6110278102c8f4719975a5eb5a5af25f9

Reenable test_gdb.

Build failed.

1 new commit added

  • Cleanup patch
3 years ago

Oops, I included a patch in a commit message and the commit message was used as a patch! Funny issue. It's now fixed.

Build succeeded.

test_gdb passed on s390x and armv7hl: the patch works as expected.

@vstinner this was backported in upstream for 3.8 and 3.7. The test was disabled for a very long time, so let's not carry a patch for this and just wait?

Is this in 3.9.0a5?

Yes, my commit 7bf069b6110278102c8f4719975a5eb5a5af25f9 is part of Python 3.9.0a5. So we can start by trying to reenble test_gdb in python39 in Rawhide.

So we can start by trying to reenble test_gdb in python39 in Rawhide.

OK, @vstinner please submit a PR there.

OK, @vstinner please submit a PR there.

PR for python39: https://src.fedoraproject.org/rpms/python39/pull-request/39 Let's see how it goes ;-)

I close this one which was more an experiment. Let's focus on python39 for now: https://src.fedoraproject.org/rpms/python39/pull-request/39

Pull-Request has been closed by vstinner

3 years ago