c62261a
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
c62261a
From: Sergio Durigan Junior <sergiodj@redhat.com>
c62261a
Date: Thu, 27 Jun 2019 13:14:26 -0400
c62261a
Subject: gdb-rhbz1723564-gdb-crash-PYTHONMALLOC-debug.patch
c62261a
c62261a
;; Fix 'gdb crash when using PYTHONMALLOC=debug on Python'
c62261a
;; RHBZ 1723564, Sergio Durigan Junior.
c62261a
c62261a
Fix crash when using PYTHONMALLOC=debug (PR python/24742)
c62261a
c62261a
This bug was originally reported against Fedora GDB:
c62261a
c62261a
  https://bugzilla.redhat.com/show_bug.cgi?id=1723564
c62261a
c62261a
The problem is that GDB will crash in the following scenario:
c62261a
c62261a
- PYTHONMALLOC=debug or PYTHONDEVMODE=1 is set.
c62261a
c62261a
- The Python debuginfo is installed.
c62261a
c62261a
- GDB is used to debug Python.
c62261a
c62261a
The crash looks like this:
c62261a
c62261a
  $ PYTHONMALLOC=debug gdb -args python3 -c pass
c62261a
  GNU gdb (GDB) Fedora 8.3-3.fc30
c62261a
  Reading symbols from python3...
c62261a
  Reading symbols from /usr/lib/debug/usr/bin/python3.7m-3.7.3-3.fc30.x86_64.debug...
c62261a
  (gdb) run
c62261a
  Starting program: /usr/bin/python3 -c pass
c62261a
  Missing separate debuginfos, use: dnf debuginfo-install glibc-2.29-9.fc30.x86_64
c62261a
  Debug memory block at address p=0x5603977bf330: API ''
c62261a
      8098648152243306496 bytes originally requested
c62261a
      The 7 pad bytes at p-7 are not all FORBIDDENBYTE (0xfb):
c62261a
	  at p-7: 0x03 *** OUCH
c62261a
	  at p-6: 0x00 *** OUCH
c62261a
	  at p-5: 0x00 *** OUCH
c62261a
	  at p-4: 0x00 *** OUCH
c62261a
	  at p-3: 0x00 *** OUCH
c62261a
	  at p-2: 0x00 *** OUCH
c62261a
	  at p-1: 0x00 *** OUCH
c62261a
      Because memory is corrupted at the start, the count of bytes requested
c62261a
	 may be bogus, and checking the trailing pad bytes may segfault.
c62261a
      The 8 pad bytes at tail=0x706483999ad1f330 are Segmentation fault (core dumped)
c62261a
c62261a
It's hard to determine what happens, but after doing some
c62261a
investigation and talking to Victor Stinner I found that GDB should
c62261a
not use the Python memory allocation functions before the Python
c62261a
interpreter is initialized (which makes sense).  However, we do just
c62261a
that on python/python.c:do_start_initialization:
c62261a
c62261a
  ...
c62261a
  progsize = strlen (progname.get ());
c62261a
  progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
c62261a
  ...
c62261a
  /* Note that Py_SetProgramName expects the string it is passed to
c62261a
     remain alive for the duration of the program's execution, so
c62261a
     it is not freed after this call.  */
c62261a
  Py_SetProgramName (progname_copy);
c62261a
  ...
c62261a
  Py_Initialize ();
c62261a
  PyEval_InitThreads ();
c62261a
c62261a
Upon reading the Python 3 C API documentation, I
c62261a
found (https://docs.python.org/3.5/c-api/memory.html):
c62261a
c62261a
  To avoid memory corruption, extension writers should never try to
c62261a
  operate on Python objects with the functions exported by the C
c62261a
  library: malloc(), calloc(), realloc() and free(). This will result in
c62261a
  mixed calls between the C allocator and the Python memory manager with
c62261a
  fatal consequences, because they implement different algorithms and
c62261a
  operate on different heaps. However, one may safely allocate and
c62261a
  release memory blocks with the C library allocator for individual
c62261a
  purposes[...]
c62261a
c62261a
And Py_SetProgramName seems like a very simple call that doesn't need
c62261a
a Python-allocated memory to work on.  So I'm proposing this patch,
c62261a
which simply replaces PyMem_Malloc by xmalloc.
c62261a
c62261a
Testing this is more complicated.  First, the crash is completely
c62261a
non-deterministic; I was able to reproduce it 10 times in a row, and
c62261a
then I wasn't able to reproduce it anymore.  I found that if you
c62261a
completely remove your build directory and rebuild GDB from scratch,
c62261a
you can reproduce it again confidently.  And with my patch, I
c62261a
confirmed that the bug doesn't manifest even in this situation.
c62261a
c62261a
No regressions found.
c62261a
c62261a
OK to apply?
c62261a
c62261a
gdb/ChangeLog:
c62261a
2019-06-28  Sergio Durigan Junior  <sergiodj@redhat.com>
c62261a
c62261a
	PR python/24742
c62261a
	https://bugzilla.redhat.com/show_bug.cgi?id=1723564
c62261a
	* python/python.c (do_start_initialization): Use 'xmalloc'
c62261a
	instead of 'PyMem_Malloc'.
c62261a
c62261a
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
c62261a
--- a/gdb/ChangeLog
c62261a
+++ b/gdb/ChangeLog
c62261a
@@ -1,3 +1,10 @@
c62261a
+2019-06-28  Sergio Durigan Junior  <sergiodj@redhat.com>
c62261a
+
c62261a
+	PR python/24742
c62261a
+	https://bugzilla.redhat.com/show_bug.cgi?id=1723564
c62261a
+	* python/python.c (do_start_initialization): Use 'xmalloc'
c62261a
+	instead of 'PyMem_Malloc'.
c62261a
+
c62261a
 2019-06-14  Tom Tromey  <tromey@adacore.com>
c62261a
 
c62261a
 	PR gdb/24502:
c62261a
diff --git a/gdb/python/python.c b/gdb/python/python.c
c62261a
--- a/gdb/python/python.c
c62261a
+++ b/gdb/python/python.c
c62261a
@@ -1720,7 +1720,7 @@ do_start_initialization ()
c62261a
   std::string oldloc = setlocale (LC_ALL, NULL);
c62261a
   setlocale (LC_ALL, "");
c62261a
   progsize = strlen (progname.get ());
c62261a
-  progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
c62261a
+  progname_copy = (wchar_t *) xmalloc ((progsize + 1) * sizeof (wchar_t));
c62261a
   if (!progname_copy)
c62261a
     {
c62261a
       fprintf (stderr, "out of memory\n");