[PATCH v3] Make GDB compile with Python 3 on MinGW
Christian Biesinger via gdb-patches
Thu Aug 15 17:42:00 GMT 2019
[Fixes two minor typos]
PyFile_FromString and PyFile_AsFile have been removed in Python 3.
There is no obvious replacement that works here, and we can't just
pass our FILE* to a DLL in Windows because it may use a different
So we just call a Python function which reads and executes file
contents. Care must be taken to execute it in the context of
Tested by inverting the ifdef and running the testsuite on Debian
Linux (even without the patch, I failed at running the testsuite
on Windows). I did test with both Python 2 and 3.
2019-08-13 Christian Biesinger <email@example.com>
* python/lib/gdb/__init__.py: Add an execute_file function.
* python/python.c (python_run_simple_file): Call gdb.execute_file
gdb/python/lib/gdb/__init__.py | 26 ++++++++++++++++++++++++++
gdb/python/python.c | 26 +++++++++++++++++---------
2 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index af74df80c8..afe5b08f3a 100644
@@ -106,6 +106,32 @@ def execute_unwinders(pending_frame):
+ """This function is used to replace Python 2's PyRun_SimpleFile.
+ Loads and executes the given file.
+ We could use the runpy module, but its documentation says:
+ "Furthermore, any functions and classes defined by the executed code are
+ not guaranteed to work correctly after a runpy function has returned."
+ globals = sys.modules['__main__'].__dict__
+ set_file = False
+ # Set file (if not set) so that the imported file can use it (e.g. to
+ # access file-relative paths). This matches what PyRun_SimpleFile does.
+ if not hasattr(globals, '__file__'):
+ globals['__file__'] = filepath
+ set_file = True
+ with open(filepath, 'rb') as file:
+ # We pass globals also as locals to match what Python does
+ # in PyRun_SimpleFile.
+ compiled = compile(file.read(), filepath, 'exec')
+ exec(compiled, globals, globals)
+ if set_file:
+ del globals['__file__']
# Convenience variable to GDB's python directory
PYTHONDIR = os.path.dirname(os.path.dirname(__file__))
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 162470dcc0..46aedba0ed 100644
@@ -323,14 +323,13 @@ python_interactive_command (const char *arg, int from_tty)
A FILE * from one runtime does not necessarily operate correctly in
the other runtime.
- To work around this potential issue, we create on Windows hosts the
- FILE object using Python routines, thus making sure that it is
- compatible with the Python library. */
+ To work around this potential issue, we run code in Python to load
+ the script. */
python_run_simple_file (FILE *file, const char *filename)
PyRun_SimpleFile (file, filename);
@@ -339,14 +338,23 @@ python_run_simple_file (FILE *file, const char *filename)
/* Because we have a string for a filename, and are using Python to
open the file, we need to expand any tilde in the path first. */
gdb::unique_xmalloc_ptr<char> full_path (tilde_expand (filename));
- gdbpy_ref<> python_file (PyFile_FromString (full_path.get (), (char *) "r"));
- if (python_file == NULL)
+ if (gdb_python_module == nullptr
+ || ! PyObject_HasAttrString (gdb_python_module, "_execute_file"))
- gdbpy_print_stack ();
- error (_("Error while opening file: %s"), full_path.get ());
+ error (_("Installation error: gdb._execute_file function is missing"));
- PyRun_SimpleFile (PyFile_AsFile (python_file.get ()), filename);
+ gdbpy_ref<> return_value
+ (PyObject_CallMethod (gdb_python_module, "_execute_file", "s",
+ full_path.get ()));
+ if (return_value == nullptr)
+ /* Use PyErr_PrintEx instead of gdbpy_print_stack to better match the
+ behavior of the non-Windows codepath. */
#endif /* _WIN32 */
More information about the Gdb-patches