Package: cpython-lldb
Overviewcpython_lldbis an LLDB extension for debugging Python programs.It can be useful for troubleshooting stuck threads and crashes in the interpreter
or external libraries. Unlike most Python debuggers, LLDB allows attaching to a
running process without instrumenting it in advance, as well as loading a process
coredump to perform an offline (or post-mortem) analysis of a problem.When analyzing the state of a Python process, normally you would only have
access tointepreter-levelinformation: most variables would be of typePyObject*, and stack traces would only contain CPython internal calls and
calls to library functions. Unless you are a CPython developer troubleshooting
the interpreter implementation, that is typically not very useful. This extension,
however, allows you to extractapplication-levelinformation about execution of
a program: print the values of variables, list the source code, display Python
stack traces, etc.While CPython already provides a similar extension for gdbout of the box,
LLDB might be the debugger of choice on some operating systems, e.g.
on Mac OS.This extension requires CPython to be built with debugging symbols enabled, which
is not the case for some Linux distros (notably Arch Linux). CPython officialDocker imagesare known to work correctly, as they
are used for integration testing.Featurescpython_lldbtargets CPython 3.5+ and supports the following features:pretty-priting of built-in types (int, bool, float, bytes, str, none, tuple, list, set, frozenset, dict)printing of Python-level stack tracesprinting of local variableslisting the source codewalking up and down the Python call stackInstallationIf your version of LLDB is linked against system libpython, it's recommended
that you install the extension to the user site packages directory and allow
it to be loaded automatically on start of a new LLDB session:$python-mpipinstall--usercpython-lldb
$echo"command script import cpython_lldb">>~/.lldbinit
$chmod+x~/.lldbinitAlternatively, you can install the extension to some other location and tell LLDB
to load it from there, e.g. ~/.lldb:$mkdir-p~/.lldb/cpython_lldb
$python-mpipinstall--target~/.lldb/cpython_lldbcpython-lldb
$echo"command script import ~/.lldb/cpython_lldb/cpython_lldb.py">>~/.lldbinit
$chmod+x~/.lldbinitMacOSLLDB bundled with MacOS is linked with the system version of CPython which may not even
be in your PATH. To locate the right version of the interpreter, use:$lldb--print-script-interpreter-infoThe output of the command above is a JSON with the following structure:{
  "executable":"/Library/.../Python3.framework/Versions/3.9/bin/python3",
  "language":"python",
  "lldb-pythonpath":"/Library/.../LLDB.framework/Resources/Python",
  "prefix":"/Library/.../Python3.framework/Versions/3.9"
}Where the value for "executable" is the CPython version that should be used to installcpython_lldbfor LLDB to be able to successfully import the script:$(lldb--print-script-interpreter-info|jq-r.executable)-mpipinstallcpython_lldbUsageStart a new LLDB session:$lldb/usr/bin/pythonor attach to an existing CPython process:$lldb/usr/bin/python-p$PIDIf you've followed the installation steps, the extension will now be automatically
loaded on start of a new LLDB session and register some Python-specific commands:(lldb) help
...
Current user-defined commands:
  py-bt     -- Print a Python-level call trace of the selected thread.
  py-down   -- Select a newer Python stack frame.
  py-list   -- List the source code of the Python module that is currently being executed.
  py-locals -- Print the values of local variables in the selected Python frame.
  py-up     -- Select an older Python stack frame.
For more information on any command, type 'help <command-name>'.Pretty-printingAll knownPyObject's (i.e. built-in types) are automatically pretty-printed
when encountered, as if you tried to get arepr()of something in Python REPL,
e.g.:(lldb) frame variable v
(PyObject *) v = 0x0000000100793c00 42
(lldb) p v->ob_type->tp_name
(const char *) $3 = 0x000000010017d42a "int"Stack tracesUsepy-btto print a full application-level stack trace of the current thread, e.g.:(lldb) py-bt
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    fc()
  File "test.py", line 12, in fc
    fb()
  File "test.py", line 8, in fb
    fa()
  File "test.py", line 2, in fa
    abs(1)Walking up and down the call stackUsepy-upandpy-downto select an older or a newer Python call stack frame, e.g.:(lldb) py-up
  File "/Users/malor/src/cpython/test.py", line 6, in cb
    self.ca()
(lldb) py-up
  File "/Users/malor/src/cpython/test.py", line 20, in f_static
    c.cb()
(lldb) py-down
  File "/Users/malor/src/cpython/test.py", line 6, in cb
    self.ca()
(lldb) py-down
  File "/Users/malor/src/cpython/test.py", line 3, in ca
    abs(1)
(lldb) py-down
*** Newest framePrinting of local variablesUsepy-localsto print the values of local variables in the selected frame:(lldb) py-locals
a = 42
args = (1, 2, 3)
b = [1, u'hello', u'\\u0442\\u0435\\u0441\\u0442']
c = ([1], 2, [[3]])
d = u'test'
e = {u'a': -1, u'b': 0, u'c': 1}
eggs = 42
kwargs = {u'foo': 'spam'}
spam = u'foobar'Listing the source codeUsepy-listto list the source code that is currently being executed in the selected
Python frame, e.g.:(lldb) py-list
    1    SOME_CONST = 42
    2
    3
    4    def fa():
   >5        abs(1)
    6        return 1
    7
    8
    9    def fb():
   10        1 + 1The command also accepts optionalstartandendarguments that allow to
list the source code within a specific range of lines, e.g.:(lldb) py-list 4
    4    def fa():
   >5        abs(1)
    6        return 1
    7
    8
    9    def fb():
   10        1 + 1
   11        fa()
   12
   13
   14    def fc():or:(lldb) py-list 4 11
    4    def fa():
   >5        abs(1)
    6        return 1
    7
    8
    9    def fb():
   10        1 + 1
   11        fa()Potential issues and how to solve themCPython 2.7.xCPython 2.7.x is not supported. There are currently no plans to support it in the future.Missing debugging symbolsCPython debugging symbols are required. You can check if they are available as follows:$lldb/usr/bin/python
$(lldb)typelookupPyObjectIf debugging symbols are not available, you'll see something like:notypewasfoundmatching'PyObject'Some Linux distros ship debugging symbols separately. To fix the problem on Debian / Ubuntu do:$sudoapt-getinstallpython-dbgon CentOS / Fedora / RHEL do:$sudoyuminstallpython-debuginfoOther distros, like Arch Linux, do not provide debugging symbols in the package repos. In this case,
you would need to build CPython from source. Please refer to the officialCPythonordistrodocumentation for instructions.Alternatively, you can use the official CPythonDocker images.Broken LLDB scriptingSome Linux distros (notably Debian Stretch) are shipped with a version of LLDB in which using Python scripting
triggers a segmentation fault when executing any non-trivial operation:$lldb(lldb)script
PythonInteractiveInterpreter.Toexit,type'quit()','exit()'orCtrl-D.
>>>importio
>>>SegmentationfaultIt's recommended that you use the latest LLDB release from the officialAPT repoinstead
of the one shipped with your distro.See thispagefor advice on troubleshooting LLDB.DevelopmentRunning testsTests currently requiremakeanddockerto be installed.To run the tests against thelatestreleased CPython version, do:$ make testTo run the tests against a specific CPython (or LLDB) version, do:$ PY_VERSION=X.Y LLDB_VERSION=Z make testSupported CPython versions are:3.73.83.93.10Supported LLDB versions:7891011ContributorsKudos to everyone who have contributed to this project!Marco Neumann