Fix python-interactive with Python 3.6

New in v2:

 - Define PyMem_RawMalloc as PyMem_Malloc for Python < 3.4 and use
   PyMem_RawMalloc in the code.

Since Python 3.4, the callback installed in PyOS_ReadlineFunctionPointer
should return a value allocated with PyMem_RawMalloc instead of
PyMem_Malloc.  The reason is that PyMem_Malloc must be called with the
Python Global Interpreter Lock (GIL) held, which is not the case in the
context where this function is called.  PyMem_RawMalloc was introduced
for cases like this.

In Python 3.6, it looks like they added an assert to verify that
PyMem_Malloc was not called without the GIL.  The consequence is that
typing anything in the python-interactive mode of gdb crashes the
process.  The same behavior was observed with the official package on
Arch Linux as well as with a manual Python build on Ubuntu 14.04.

This is what is shown with a debug build of Python 3.6 (the error with a
non-debug build is far less clear):

  (gdb) pi
  >>> print(1)
  Fatal Python error: Python memory allocator called without holding the GIL

  Current thread 0x00007f1459af8780 (most recent call first):
  [1]    21326 abort      ./gdb

and the backtrace:

  #0  0x00007ffff618bc37 in raise () from /lib/x86_64-linux-gnu/libc.so.6
  #1  0x00007ffff618f028 in abort () from /lib/x86_64-linux-gnu/libc.so.6
  #2  0x00007ffff6b104d6 in Py_FatalError (msg=msg@entry=0x7ffff6ba15b8 "Python memory allocator called without holding the GIL") at Python/pylifecycle.c:1457
  #3  0x00007ffff6a37a68 in _PyMem_DebugCheckGIL () at Objects/obmalloc.c:1972
  #4  0x00007ffff6a3804e in _PyMem_DebugFree (ctx=0x7ffff6e65290 <_PyMem_Debug+48>, ptr=0x24f8830) at Objects/obmalloc.c:1994
  #5  0x00007ffff6a38e1d in PyMem_Free (ptr=<optimized out>) at Objects/obmalloc.c:442
  #6  0x00007ffff6b866c6 in _PyFaulthandler_Fini () at ./Modules/faulthandler.c:1369
  #7  0x00007ffff6b104bd in Py_FatalError (msg=msg@entry=0x7ffff6ba15b8 "Python memory allocator called without holding the GIL") at Python/pylifecycle.c:1431
  #8  0x00007ffff6a37a68 in _PyMem_DebugCheckGIL () at Objects/obmalloc.c:1972
  #9  0x00007ffff6a37aa3 in _PyMem_DebugMalloc (ctx=0x7ffff6e65290 <_PyMem_Debug+48>, nbytes=5) at Objects/obmalloc.c:1980
  #10 0x00007ffff6a38d91 in PyMem_Malloc (size=<optimized out>) at Objects/obmalloc.c:418
  #11 0x000000000064dbe2 in gdbpy_readline_wrapper (sys_stdin=0x7ffff6514640 <_IO_2_1_stdin_>, sys_stdout=0x7ffff6514400 <_IO_2_1_stdout_>, prompt=0x7ffff4d4f7d0 ">>> ")
    at /home/emaisin/src/binutils-gdb/gdb/python/py-gdb-readline.c:75

The documentation is very clear about it [1] and it was also mentioned
in the "What's New In Python 3.4" page [2].

[1] https://docs.python.org/3/c-api/veryhigh.html#c.PyOS_ReadlineFunctionPointer
[2] https://docs.python.org/3/whatsnew/3.4.html#changes-in-the-c-api

gdb/ChangeLog:

	* python/python-internal.h (PyMem_RawMalloc): Define for
	Python < 3.4.
	* python/py-gdb-readline.c (gdbpy_readline_wrapper): Use
	PyMem_RawMalloc instead of PyMem_Malloc.
This commit is contained in:
Simon Marchi 2017-01-20 20:39:08 -05:00 committed by Simon Marchi
parent 6dd1c25a5a
commit 6f8b04077b
3 changed files with 17 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2017-01-20 Simon Marchi <simon.marchi@ericsson.com>
* python/python-internal.h (PyMem_RawMalloc): Define for
Python < 3.4.
* python/py-gdb-readline.c (gdbpy_readline_wrapper): Use
PyMem_RawMalloc instead of PyMem_Malloc.
2017-01-20 Mike Wrighton <mike_wrighton@codesourcery.com> 2017-01-20 Mike Wrighton <mike_wrighton@codesourcery.com>
Luis Machado <lgustavo@codesourcery.com> Luis Machado <lgustavo@codesourcery.com>

View file

@ -21,6 +21,7 @@
#include "python-internal.h" #include "python-internal.h"
#include "top.h" #include "top.h"
#include "cli/cli-utils.h" #include "cli/cli-utils.h"
/* Readline function suitable for PyOS_ReadlineFunctionPointer, which /* Readline function suitable for PyOS_ReadlineFunctionPointer, which
is used for Python's interactive parser and raw_input. In both is used for Python's interactive parser and raw_input. In both
cases, sys_stdin and sys_stdout are always stdin and stdout cases, sys_stdin and sys_stdout are always stdin and stdout
@ -63,7 +64,7 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
/* Detect EOF (Ctrl-D). */ /* Detect EOF (Ctrl-D). */
if (p == NULL) if (p == NULL)
{ {
q = (char *) PyMem_Malloc (1); q = (char *) PyMem_RawMalloc (1);
if (q != NULL) if (q != NULL)
q[0] = '\0'; q[0] = '\0';
return q; return q;
@ -72,7 +73,7 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
n = strlen (p); n = strlen (p);
/* Copy the line to Python and return. */ /* Copy the line to Python and return. */
q = (char *) PyMem_Malloc (n + 2); q = (char *) PyMem_RawMalloc (n + 2);
if (q != NULL) if (q != NULL)
{ {
strncpy (q, p, n); strncpy (q, p, n);

View file

@ -172,6 +172,13 @@ typedef unsigned long gdb_py_ulongest;
typedef long Py_hash_t; typedef long Py_hash_t;
#endif #endif
/* PyMem_RawMalloc appeared in Python 3.4. For earlier versions, we can just
fall back to PyMem_Malloc. */
#if PY_VERSION_HEX < 0x03040000
#define PyMem_RawMalloc PyMem_Malloc
#endif
/* Python 2.6 did not wrap Py_DECREF in 'do {...} while (0)', leading /* Python 2.6 did not wrap Py_DECREF in 'do {...} while (0)', leading
to 'suggest explicit braces to avoid ambiguous else' gcc errors. to 'suggest explicit braces to avoid ambiguous else' gcc errors.
Wrap it ourselves, so that callers don't need to care. */ Wrap it ourselves, so that callers don't need to care. */