Overview
Starting with GDB 7, support for extending GDB with Python scripting was added to GDB.
The xPack GNU Arm Embedded GCC also supports this, by providing two separate binaries:
arm-none-eabi-gdb-py
with Python 2 supportarm-none-eabi-gdb-py3
with Python 3 support
Prerequisites
Due to some Python internals, when embedded in other applications, the Python run-time remains tied to the version used during the build process.
With the current versions of XBB (v3.1), these versions are:
- 2.7
- 3.7
The immediate consequence of this characteristic is that in order for
gdb-py
and gdb-py3
to run properly, these exact versions of Python
must be available.
Windows - TO BE ADDED
As of macOS 10.15, Apple provides Python 2.7 as part of the basic system install.
% python2 -c 'from distutils import sysconfig;print(sysconfig.PREFIX)'
/System/Library/Frameworks/Python.framework/Versions/2.7
However, it displays a warning:
% python2
WARNING: Python 2.7 is not recommended.
This version is included in macOS for compatibility with legacy software.
Future versions of macOS will not include Python 2.7.
Instead, it is recommended that you transition to using 'python3' from within Terminal.
Python 2.7.16 (default, Dec 13 2019, 18:00:32)
Python 3 is not directly available, but may come packed with some recent releases of the Command Line Tools.
% python3 -c 'from distutils import sysconfig;print(sysconfig.PREFIX)'
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7
For consistent results, the GDB binaries were built agains the official Python binaries, available from Python Releases for Mac OS X:
For a seamless experience, it is recommended to install exactly these versions.
If Python 2 is not installed in the default location
(/Library/Frameworks/Python.framework/Versions/2.7
)
attempts to run gdb-py
directly will fail:
% arm-none-eabi-gdb-py
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site
However, it is possible to use the Apple binaries, or any other binaries,
(like Homebrew), if GDB is informed about the location where Python is
installed, via the environment variable PYTHONHOME
:
% PYTHONHOME="$(python2 -c 'from distutils import sysconfig;print(sysconfig.PREFIX)')" arm-none-eabi-gdb-py --config
This GDB was configured as follows:
configure --host=x86_64-apple-darwin14.5.0 --target=arm-none-eabi
--with-auto-load-dir=$debugdir:$datadir/auto-load
--with-auto-load-safe-path=$debugdir:$datadir/auto-load
--with-expat
--with-gdb-datadir=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/arm-none-eabi/share/gdb (relocatable)
--with-jit-reader-dir=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/lib/gdb (relocatable)
--without-libunwind-ia64
--with-lzma
--without-babeltrace
--without-intel-pt
--disable-libmcheck
--with-mpfr
--with-python=/Library/Frameworks/Python.framework/Versions/2.7
--without-guile
--disable-source-highlight
--with-separate-debug-dir=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/lib/debug (relocatable)
--with-system-gdbinit=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/arm-none-eabi/lib/gdbinit (relocatable)
("Relocatable" means the directory can be moved with the GDB installation
tree, and GDB will still find it.)
Similarly, if Python 3 is not installed in the default location
(/Library/Frameworks/Python.framework/Versions/3.7
)
attempts to run gdb-py3
directly will fail:
% arm-none-eabi-gdb-py3
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
Current thread 0x0000000106239dc0 (most recent call first):
zsh: abort
If Python 3 is installed, setting PYTHONHOME
to its location
allows gdb-py3
to start properly:
% PYTHONHOME="$(python3 -c 'from distutils import sysconfig;print(sysconfig.PREFIX)')" arm-none-eabi-gdb-py3 --config
This GDB was configured as follows:
configure --host=x86_64-apple-darwin14.5.0 --target=arm-none-eabi
--with-auto-load-dir=$debugdir:$datadir/auto-load
--with-auto-load-safe-path=$debugdir:$datadir/auto-load
--with-expat
--with-gdb-datadir=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/arm-none-eabi/share/gdb (relocatable)
--with-jit-reader-dir=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/lib/gdb (relocatable)
--without-libunwind-ia64
--with-lzma
--without-babeltrace
--without-intel-pt
--disable-libmcheck
--with-mpfr
--with-python=/Library/Frameworks/Python.framework/Versions/3.7
--without-guile
--disable-source-highlight
--with-separate-debug-dir=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/lib/debug (relocatable)
--with-system-gdbinit=/Users/ilg/Work/arm-none-eabi-gcc-9.2.1-1.2/darwin-x64/install/arm-none-eabi-gcc/arm-none-eabi/lib/gdbinit (relocatable)
("Relocatable" means the directory can be moved with the GDB installation
tree, and GDB will still find it.)
The technical reason why the GDB binaries are tied to a given Python version is
that the Python run-time is packed as a versioned library named like
libpython2.7.dylib
,
in other words with both major and minor numbers, which probably means that
versions with different minor numbers are not compatible. The reference to
this library can be circumvented by packing the library with the executable.
To make things even worse, each Python version expects to find a
versioned folder like lib/python2.7
in the Python home folder, which
again probably means that the content is not compatible between versions
with different minor numbers.
Most modern distributions come with both Python 2 and 3 available as native packages, but some come with versions different from 2.7 and 3.7.
For consistent results, the GDB binaries were built against the official Python binaries, available from Python Source Releases:
For a seamless experience, it is recommended to install exactly these versions.
To compile Python 2 use the following commands:
python2_version="2.7.17"
mkdir -p "${HOME}/Downloads"
curl -L --fail -o "${HOME}/Downloads/Python-${python2_version}.tgz" \
https://www.python.org/ftp/python/${python2_version}/Python-${python2_version}.tgz
rm -rf "${HOME}/Work/Python-${python2_version}"
mkdir -p "${HOME}/Work"
cd "${HOME}/Work"
tar xzf "${HOME}/Downloads/Python-${python2_version}.tgz"
cd "${HOME}/Work/Python-${python2_version}"
bash ./configure --enable-unicode=ucs4
make
sudo make altinstall
To check where the new binaries were installed:
$ which python2.7
/usr/local/bin/python2.7
To compile Python 3 use the following commands:
python3_version="3.7.6"
mkdir -p "${HOME}/Downloads"
curl -L --fail -o "${HOME}/Downloads/Python-${python3_version}.tgz" \
https://www.python.org/ftp/python/${python3_version}/Python-${python3_version}.tgz
rm -rf "${HOME}/Work/Python-${python3_version}"
mkdir -p "${HOME}/Work"
cd "${HOME}/Work"
tar xzf "${HOME}/Downloads/Python-${python3_version}.tgz"
cd "${HOME}/Work/Python-${python3_version}"
bash ./configure
make
sudo make altinstall
To check where the new binaries were installed:
$ which python3.7
/usr/local/bin/python3.7
The technical reason why the GDB binaries are tied to a given Python version is
that the Python run-time is packed as a versioned library named like
libpython2.7.so.1.0
,
in other words with both major and minor numbers, which probably means that
versions with different minor numbers are not compatible. The reference to
this library can be circumvented by packing the library with the executable.
To make things even worse, each Python version expects to find a
versioned folder like lib/python2.7
in the Python home folder, which
again probably means that the content is not compatible between versions
with different minor numbers.
Debian & related distributions are particularly picky with embedded Python applications, and attempts to run gdb-py usually end in:
/home/ilg/Work/test-arm-none-eabi-gcc/xpack-arm-none-eabi-gcc-9.2.1-1.2/bin/arm-none-eabi-gdb-py --version
Traceback (most recent call last):
File "/usr/lib/python2.7/site.py", line 554, in <module>
main()
File "/usr/lib/python2.7/site.py", line 536, in main
known_paths = addusersitepackages(known_paths)
File "/usr/lib/python2.7/site.py", line 272, in addusersitepackages
user_site = getusersitepackages()
File "/usr/lib/python2.7/site.py", line 247, in getusersitepackages
user_base = getuserbase() # this will also set USER_BASE
File "/usr/lib/python2.7/site.py", line 237, in getuserbase
USER_BASE = get_config_var('userbase')
File "/usr/lib/python2.7/sysconfig.py", line 587, in get_config_var
return get_config_vars().get(name)
File "/usr/lib/python2.7/sysconfig.py", line 533, in get_config_vars
_init_posix(_CONFIG_VARS)
File "/usr/lib/python2.7/sysconfig.py", line 417, in _init_posix
from _sysconfigdata import build_time_vars
File "/usr/lib/python2.7/_sysconfigdata.py", line 6, in <module>
from _sysconfigdata_nd import *
ImportError: No module named _sysconfigdata_nd
Install Python 2.7 as instructed before, and gdb-py will start properly.