Skip to content

Instantly share code, notes, and snippets.

@classmember
Last active May 6, 2019 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save classmember/d3358affdf13f57d7d178892be323f72 to your computer and use it in GitHub Desktop.
Save classmember/d3358affdf13f57d7d178892be323f72 to your computer and use it in GitHub Desktop.

Watching all layers of Python code

We're going to dive into how languages interact as a stack. First, we'll download the a copy of Python and compile with GNU debugging tags enabled. I hope you're ready to watch registers in the processor flutter and C code scroll. We start by opening our favorite terminal.

Compile a debugging build of Python

Go to the directory the debugging build will be installed in

cd /opt/

Download a copy of cpython

git clone https://github.com/python/cpython.git

Go the directory

cd cpython

Configure the build with Py_Debug to enable GDB tags

./configure --with-pydebug

make the build

make

For convenience, make an alias to run the debugger. The alias is to run gdb with flags to add python gdb extensions and target

alias dive='gdb -iex '\''add-auto-load-safe-path .'\'' /opt/cpython/python'

run the alias

dive

Open TUI for reading C and assembly during the program's runtime.

This combo opens and closes the TUI

ctrl + x    ctrl + a

TUI mode 2 shows the C code and assembly as you step through the code with the return key

ctrl + x    2

In GDB, you can set breakpoints, run and step through code

b 1
r
s

That translates to:

  • set breakpoint at 1.
  • run code
  • step

This should drop you in

./Programs/python.c

Which looks like

/* Minimal main program -- everything is loaded from the library */

#include "Python.h"
#include "pycore_pylifecycle.h"

#ifdef MS_WINDOWS
int
wmain(int argc, wchar_t **argv)
{
    return Py_Main(argc, argv);
}
#else
int
main(int argc, char **argv)
{
    return _Py_UnixMain(argc, argv);
}
#endif

other gdb commands:

help
b 1  (breakpoint at line 1)
up
down
next
ctrl+x ctrl+a  (enable/disable TUI)
s  (step)
list
refresh
i  (info)
i r

frame -- Select	and print a stack frame
py-bt -- Display the current python frame and all the frames within its	call stack (if any)
py-bt-full -- Display the current python frame and all the frames within its call stack	(if any)
py-down	-- Select and print the	python stack frame called by this one (if any)
py-up -- Select	and print the python stack frame that called this one (if any)
return -- Make selected	stack frame return to its caller
select-frame --	Select a stack frame without printing anything
up -- Select and print stack frame that	called this one

References:

@classmember
Copy link
Author

TODO:

  • Move to a repo
  • Add gif to demonstrate usage at the top of the file
  • write script for a standard linux distro
  • add CI script

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment