Fix python build and re-enable it.
(RH BZ 1829702, Kevin Buettner and Keith Seitz)
This commit is contained in:
parent
a6ec4e0365
commit
28b99d9981
@ -400,3 +400,7 @@ Patch098: gdb-rhbz1818011-bfd-gcc10-error.patch
|
||||
# Backport fix for deprecation of PyEval_InitThreads in Python 3.9.
|
||||
Patch099: gdb-rhbz1822715-fix-python-deprecation.patch
|
||||
|
||||
# Backport "Fix Python 3.9 related runtime problems"
|
||||
# Kevin Buettner <kevinb@redhat.com> and Keith Seitz <keiths@redhat.com>
|
||||
Patch100: gdb-rhbz1829702-fix-python39.patch
|
||||
|
||||
|
@ -97,3 +97,4 @@
|
||||
%patch097 -p1
|
||||
%patch098 -p1
|
||||
%patch099 -p1
|
||||
%patch100 -p1
|
||||
|
@ -97,3 +97,4 @@ gdb-vla-intel-fix-print-char-array.patch
|
||||
gdb-rhbz1553104-s390x-arch12-test.patch
|
||||
gdb-rhbz1818011-bfd-gcc10-error.patch
|
||||
gdb-rhbz1822715-fix-python-deprecation.patch
|
||||
gdb-rhbz1829702-fix-python39.patch
|
||||
|
224
gdb-rhbz1829702-fix-python39.patch
Normal file
224
gdb-rhbz1829702-fix-python39.patch
Normal file
@ -0,0 +1,224 @@
|
||||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Keith Seitz <keiths@redhat.com>
|
||||
Date: Thu, 4 Jun 2020 17:16:48 -0700
|
||||
Subject: gdb-rhbz1829702-fix-python39.patch
|
||||
|
||||
;; Backport "Fix Python 3.9 related runtime problems"
|
||||
;; Kevin Buettner <kevinb@redhat.com> and Keith Seitz <keiths@redhat.com>
|
||||
|
||||
commit c47bae859a5af0d95224d90000df0e529f7c5aa0
|
||||
Author: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Wed May 27 20:05:40 2020 -0700
|
||||
|
||||
Fix Python3.9 related runtime problems
|
||||
|
||||
Python3.9b1 is now available on Rawhide. GDB w/ Python 3.9 support
|
||||
can be built using the configure switch -with-python=/usr/bin/python3.9.
|
||||
|
||||
Attempting to run gdb/Python3.9 segfaults on startup:
|
||||
|
||||
#0 0x00007ffff7b0582c in PyEval_ReleaseLock () from /lib64/libpython3.9
|
||||
.so.1.0
|
||||
#1 0x000000000069ccbf in do_start_initialization ()
|
||||
at worktree-test1/gdb/python/python.c:1789
|
||||
#2 _initialize_python ()
|
||||
at worktree-test1/gdb/python/python.c:1877
|
||||
#3 0x00000000007afb0a in initialize_all_files () at init.c:237
|
||||
...
|
||||
|
||||
Consulting the the documentation...
|
||||
|
||||
https://docs.python.org/3/c-api/init.html
|
||||
|
||||
...we find that PyEval_ReleaseLock() has been deprecated since version
|
||||
3.2. It recommends using PyEval_SaveThread or PyEval_ReleaseThread()
|
||||
instead. In do_start_initialization, in gdb/python/python.c, we
|
||||
can replace the calls to PyThreadState_Swap() and PyEval_ReleaseLock()
|
||||
with a single call to PyEval_SaveThread. (Thanks to Keith Seitz
|
||||
for working this out.)
|
||||
|
||||
With that in place, GDB gets a little bit further. It still dies
|
||||
on startup, but the backtrace is different:
|
||||
|
||||
#0 0x00007ffff7b04306 in PyOS_InterruptOccurred ()
|
||||
from /lib64/libpython3.9.so.1.0
|
||||
#1 0x0000000000576e86 in check_quit_flag ()
|
||||
at worktree-test1/gdb/extension.c:776
|
||||
#2 0x0000000000576f8a in set_active_ext_lang (now_active=now_active@entry=0x983c00 <extension_language_python>)
|
||||
at worktree-test1/gdb/extension.c:705
|
||||
#3 0x000000000069d399 in gdbpy_enter::gdbpy_enter (this=0x7fffffffd2d0,
|
||||
gdbarch=0x0, language=0x0)
|
||||
at worktree-test1/gdb/python/python.c:211
|
||||
#4 0x0000000000686e00 in python_new_inferior (inf=0xddeb10)
|
||||
at worktree-test1/gdb/python/py-inferior.c:251
|
||||
#5 0x00000000005d9fb9 in std::function<void (inferior*)>::operator()(inferior*) const (__args#0=<optimized out>, this=0xccad20)
|
||||
at /usr/include/c++/10/bits/std_function.h:617
|
||||
#6 gdb::observers::observable<inferior*>::notify (args#0=0xddeb10,
|
||||
this=<optimized out>)
|
||||
at worktree-test1/gdb/../gdbsupport/observable.h:106
|
||||
#7 add_inferior_silent (pid=0)
|
||||
at worktree-test1/gdb/inferior.c:113
|
||||
#8 0x00000000005dbcb8 in initialize_inferiors ()
|
||||
at worktree-test1/gdb/inferior.c:947
|
||||
...
|
||||
|
||||
We checked with some Python Developers and were told that we should
|
||||
acquire the GIL prior to calling any Python C API function. We
|
||||
definitely don't have the GIL for calls of PyOS_InterruptOccurred().
|
||||
|
||||
I moved class_gdbpy_gil earlier in the file and use it in
|
||||
gdbpy_check_quit_flag() to acquire (and automatically release) the
|
||||
GIL.
|
||||
|
||||
With those changes in place, I was able to run to a GDB prompt. But,
|
||||
when trying to quit, it segfaulted again due to due to some other
|
||||
problems with gdbpy_check_quit_flag():
|
||||
|
||||
Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
|
||||
0x00007ffff7bbab0c in new_threadstate () from /lib64/libpython3.9.so.1.0
|
||||
(top-gdb) bt 8
|
||||
#0 0x00007ffff7bbab0c in new_threadstate () from /lib64/libpython3.9.so.1.0
|
||||
#1 0x00007ffff7afa5ea in PyGILState_Ensure.cold ()
|
||||
from /lib64/libpython3.9.so.1.0
|
||||
#2 0x000000000069b58c in gdbpy_gil::gdbpy_gil (this=<synthetic pointer>)
|
||||
at worktree-test1/gdb/python/python.c:278
|
||||
#3 gdbpy_check_quit_flag (extlang=<optimized out>)
|
||||
at worktree-test1/gdb/python/python.c:278
|
||||
#4 0x0000000000576e96 in check_quit_flag ()
|
||||
at worktree-test1/gdb/extension.c:776
|
||||
#5 0x000000000057700c in restore_active_ext_lang (previous=0xe9c050)
|
||||
at worktree-test1/gdb/extension.c:729
|
||||
#6 0x000000000088913a in do_my_cleanups (
|
||||
pmy_chain=0xc31870 <final_cleanup_chain>,
|
||||
old_chain=0xae5720 <sentinel_cleanup>)
|
||||
at worktree-test1/gdbsupport/cleanups.cc:131
|
||||
#7 do_final_cleanups ()
|
||||
at worktree-test1/gdbsupport/cleanups.cc:143
|
||||
|
||||
In this case, we're trying to call a Python C API function after
|
||||
Py_Finalize() has been called from finalize_python(). I made
|
||||
finalize_python set gdb_python_initialized to false and then cause
|
||||
check_quit_flag() to return early when it's false.
|
||||
|
||||
With these changes in place, GDB seems to be working again with
|
||||
Python3.9b1. I think it likely that there are other problems lurking.
|
||||
I wouldn't be surprised to find that there are other calls into Python
|
||||
where we don't first make sure that we have the GIL. Further changes
|
||||
may well be needed.
|
||||
|
||||
I see no regressions testing on Rawhide using a GDB built with the
|
||||
default Python version (3.8.3) versus one built using Python 3.9b1.
|
||||
|
||||
I've also tested on Fedora 28, 29, 30, 31, and 32 (all x86_64) using
|
||||
the default (though updated) system installed versions of Python on
|
||||
those OSes. This means that I've tested against Python versions
|
||||
2.7.15, 2.7.17, 2.7.18, 3.7.7, 3.8.2, and 3.8.3. In each case GDB
|
||||
still builds without problem and shows no regressions after applying
|
||||
this patch.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
2020-MM-DD Kevin Buettner <kevinb@redhat.com>
|
||||
Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* python/python.c (do_start_initialization): For Python 3.9 and
|
||||
later, call PyEval_SaveThread instead of PyEval_ReleaseLock.
|
||||
(class gdbpy_gil): Move to earlier in file.
|
||||
(finalize_python): Set gdb_python_initialized.
|
||||
(gdbpy_check_quit_flag): Acquire GIL via gdbpy_gil. Return early
|
||||
when not initialized.
|
||||
|
||||
diff --git a/gdb/python/python.c b/gdb/python/python.c
|
||||
--- a/gdb/python/python.c
|
||||
+++ b/gdb/python/python.c
|
||||
@@ -234,6 +234,30 @@ gdbpy_enter::~gdbpy_enter ()
|
||||
PyGILState_Release (m_state);
|
||||
}
|
||||
|
||||
+/* A helper class to save and restore the GIL, but without touching
|
||||
+ the other globals that are handled by gdbpy_enter. */
|
||||
+
|
||||
+class gdbpy_gil
|
||||
+{
|
||||
+public:
|
||||
+
|
||||
+ gdbpy_gil ()
|
||||
+ : m_state (PyGILState_Ensure ())
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ ~gdbpy_gil ()
|
||||
+ {
|
||||
+ PyGILState_Release (m_state);
|
||||
+ }
|
||||
+
|
||||
+ DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
|
||||
+
|
||||
+private:
|
||||
+
|
||||
+ PyGILState_STATE m_state;
|
||||
+};
|
||||
+
|
||||
/* Set the quit flag. */
|
||||
|
||||
static void
|
||||
@@ -247,6 +271,10 @@ gdbpy_set_quit_flag (const struct extension_language_defn *extlang)
|
||||
static int
|
||||
gdbpy_check_quit_flag (const struct extension_language_defn *extlang)
|
||||
{
|
||||
+ if (!gdb_python_initialized)
|
||||
+ return 0;
|
||||
+
|
||||
+ gdbpy_gil gil;
|
||||
return PyOS_InterruptOccurred ();
|
||||
}
|
||||
|
||||
@@ -924,30 +952,6 @@ gdbpy_source_script (const struct extension_language_defn *extlang,
|
||||
|
||||
/* Posting and handling events. */
|
||||
|
||||
-/* A helper class to save and restore the GIL, but without touching
|
||||
- the other globals that are handled by gdbpy_enter. */
|
||||
-
|
||||
-class gdbpy_gil
|
||||
-{
|
||||
-public:
|
||||
-
|
||||
- gdbpy_gil ()
|
||||
- : m_state (PyGILState_Ensure ())
|
||||
- {
|
||||
- }
|
||||
-
|
||||
- ~gdbpy_gil ()
|
||||
- {
|
||||
- PyGILState_Release (m_state);
|
||||
- }
|
||||
-
|
||||
- DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
|
||||
-
|
||||
-private:
|
||||
-
|
||||
- PyGILState_STATE m_state;
|
||||
-};
|
||||
-
|
||||
/* A single event. */
|
||||
struct gdbpy_event
|
||||
{
|
||||
@@ -1548,6 +1552,7 @@ finalize_python (void *ignore)
|
||||
|
||||
Py_Finalize ();
|
||||
|
||||
+ gdb_python_initialized = false;
|
||||
restore_active_ext_lang (previous_active);
|
||||
}
|
||||
|
||||
@@ -1720,8 +1725,7 @@ do_start_initialization ()
|
||||
return false;
|
||||
|
||||
/* Release the GIL while gdb runs. */
|
||||
- PyThreadState_Swap (NULL);
|
||||
- PyEval_ReleaseLock ();
|
||||
+ PyEval_SaveThread ();
|
||||
|
||||
make_final_cleanup (finalize_python, NULL);
|
||||
|
9
gdb.spec
9
gdb.spec
@ -11,9 +11,6 @@
|
||||
# workload gets run it decreases the general performance now.
|
||||
# --define 'scl somepkgname': Independent packages by scl-utils-build.
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1829702
|
||||
%global _without_python 1
|
||||
|
||||
%{?scl:%scl_package gdb}
|
||||
%{!?scl:
|
||||
%global pkg_name %{name}
|
||||
@ -38,7 +35,7 @@ Version: 9.1
|
||||
|
||||
# The release always contains a leading reserved number, start it at 1.
|
||||
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
|
||||
Release: 7%{?dist}
|
||||
Release: 8%{?dist}
|
||||
|
||||
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL
|
||||
# Do not provide URL for snapshots as the file lasts there only for 2 days.
|
||||
@ -1158,6 +1155,10 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Jun 5 2020 Keith Seitz <keiths@redhat.com> - 9.1-8
|
||||
- Add patch for Python 3.9 and re-enable python.
|
||||
- Update generate-*.sh to include stgit support.
|
||||
|
||||
* Thu May 21 2020 Miro Hrončok <mhroncok@redhat.com> - 9.1-7
|
||||
- Disable Python support to workaround problems with Python 3.9 (RHBZ 1829702)
|
||||
|
||||
|
@ -14,7 +14,7 @@ usage ()
|
||||
$0 -- Generate a git repository from .patch files
|
||||
|
||||
Usage:
|
||||
$0 <REPOSITORY>
|
||||
$0 [-u] [-h] <REPOSITORY>
|
||||
|
||||
<REPOSITORY> is the directory where the rebase was performed. You
|
||||
need to clone the repository first.
|
||||
@ -22,6 +22,7 @@ need to clone the repository first.
|
||||
Options are:
|
||||
|
||||
-h: Print this message
|
||||
-u: Uncommit all patches and initialize stgit repo
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
@ -31,8 +32,21 @@ test -f gdb.spec || die "This script needs to run from the same directory as gdb
|
||||
test -z $1 && die "You need to specify the repository."
|
||||
test "$1" = "-h" && usage
|
||||
|
||||
uncommit=0
|
||||
if [ "$1" = "-u" ]; then
|
||||
uncommit=1
|
||||
shift
|
||||
fi
|
||||
|
||||
git_repo=$1
|
||||
if [ ! -e $git_repo ]; then
|
||||
echo "$0: repository \"$git_repo\" does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -f _git_upstream_commit || die "Cannot find _git_upstream_commit file."
|
||||
test -f _patch_order || die "Cannot find _patch_order file."
|
||||
command -v stg > /dev/null 2>&1 || die "Cannot find stg. Is stgit installed?"
|
||||
|
||||
last_ancestor_commit=`cat _git_upstream_commit`
|
||||
|
||||
@ -41,8 +55,19 @@ cd $1
|
||||
git name-rev $last_ancestor_commit
|
||||
test $? -eq 0 || die "Could not find $last_ancestor_commit in the repository $1. Did you run 'git fetch'?"
|
||||
|
||||
git checkout $last_ancestor_commit
|
||||
# Create a branch for the checkout; use the distro name in
|
||||
# the name of this branch.
|
||||
f=`cd .. && pwd`
|
||||
name=devel-`basename $f`
|
||||
git checkout -b $name $last_ancestor_commit
|
||||
echo "Applying patches..."
|
||||
for p in `cat ../_patch_order` ; do
|
||||
git am ../$p
|
||||
test $? -eq 0 || die "Could not apply patch '$p'."
|
||||
done
|
||||
|
||||
if (($uncommit)); then
|
||||
echo "Uncommitting patches..."
|
||||
stg init
|
||||
stg uncommit -t $last_ancestor_commit -x
|
||||
fi
|
||||
|
@ -52,6 +52,13 @@ done
|
||||
|
||||
cd $1
|
||||
|
||||
# If patches were uncommitted when the patches were applied,
|
||||
# make sure that we're sitting at the top-most patch. Otherwise
|
||||
# we'll only add patches up to the current top patch.
|
||||
# It's safe to just assume stgit was used -- the push will simply
|
||||
# fail.
|
||||
stg push --all > /dev/null 2>&1
|
||||
|
||||
git name-rev $commit_or_tag
|
||||
test $? -eq 0 || die "Could not find $commit_or_tag in the repository. Did you run 'git fetch'?"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user