17db96d56Sopenharmony_ci# If you use the GNU debugger gdb to debug the Python C runtime, you
27db96d56Sopenharmony_ci# might find some of the following commands useful.  Copy this to your
37db96d56Sopenharmony_ci# ~/.gdbinit file and it'll get loaded into gdb automatically when you
47db96d56Sopenharmony_ci# start it up.  Then, at the gdb prompt you can do things like:
57db96d56Sopenharmony_ci#
67db96d56Sopenharmony_ci#    (gdb) pyo apyobjectptr
77db96d56Sopenharmony_ci#    <module 'foobar' (built-in)>
87db96d56Sopenharmony_ci#    refcounts: 1
97db96d56Sopenharmony_ci#    address    : 84a7a2c
107db96d56Sopenharmony_ci#    $1 = void
117db96d56Sopenharmony_ci#    (gdb)
127db96d56Sopenharmony_ci#
137db96d56Sopenharmony_ci# NOTE: If you have gdb 7 or later, it supports debugging of Python directly
147db96d56Sopenharmony_ci# with embedded macros that you may find superior to what is in here.
157db96d56Sopenharmony_ci# See Tools/gdb/libpython.py and http://bugs.python.org/issue8032.
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_cidefine pyo
187db96d56Sopenharmony_ci    # side effect of calling _PyObject_Dump is to dump the object's
197db96d56Sopenharmony_ci    # info - assigning just prevents gdb from printing the
207db96d56Sopenharmony_ci    # NULL return value
217db96d56Sopenharmony_ci    set $_unused_void = _PyObject_Dump($arg0)
227db96d56Sopenharmony_ciend
237db96d56Sopenharmony_cidocument pyo
247db96d56Sopenharmony_ci  Prints a representation of the object to stderr, along with the
257db96d56Sopenharmony_ci  number of reference counts it currently has and the hex address the
267db96d56Sopenharmony_ci  object is allocated at.  The argument must be a PyObject*
277db96d56Sopenharmony_ciend
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_cidefine pyg
307db96d56Sopenharmony_ci    print _PyGC_Dump($arg0)
317db96d56Sopenharmony_ciend
327db96d56Sopenharmony_cidocument pyg
337db96d56Sopenharmony_ci  Prints a representation of the object to stderr, along with the
347db96d56Sopenharmony_ci  number of reference counts it currently has and the hex address the
357db96d56Sopenharmony_ci  object is allocated at.  The argument must be a PyGC_Head*
367db96d56Sopenharmony_ciend
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_cidefine pylocals
397db96d56Sopenharmony_ci    set $_i = 0
407db96d56Sopenharmony_ci    while $_i < f->f_code->co_nlocals
417db96d56Sopenharmony_ci	if f->f_localsplus + $_i != 0
427db96d56Sopenharmony_ci	    set $_names = f->f_code->co_varnames
437db96d56Sopenharmony_ci	    set $_name = PyUnicode_AsUTF8(PyTuple_GetItem($_names, $_i))
447db96d56Sopenharmony_ci	    printf "%s:\n", $_name
457db96d56Sopenharmony_ci            pyo f->f_localsplus[$_i]
467db96d56Sopenharmony_ci	end
477db96d56Sopenharmony_ci        set $_i = $_i + 1
487db96d56Sopenharmony_ci    end
497db96d56Sopenharmony_ciend
507db96d56Sopenharmony_cidocument pylocals
517db96d56Sopenharmony_ci  Print the local variables of the current frame.
527db96d56Sopenharmony_ciend
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci# A rewrite of the Python interpreter's line number calculator in GDB's
557db96d56Sopenharmony_ci# command language
567db96d56Sopenharmony_cidefine lineno
577db96d56Sopenharmony_ci    set $__continue = 1
587db96d56Sopenharmony_ci    set $__co = f->f_code
597db96d56Sopenharmony_ci    set $__lasti = f->f_lasti
607db96d56Sopenharmony_ci    set $__sz = ((PyVarObject *)$__co->co_lnotab)->ob_size/2
617db96d56Sopenharmony_ci    set $__p = (unsigned char *)((PyBytesObject *)$__co->co_lnotab)->ob_sval
627db96d56Sopenharmony_ci    set $__li = $__co->co_firstlineno
637db96d56Sopenharmony_ci    set $__ad = 0
647db96d56Sopenharmony_ci    while ($__sz-1 >= 0 && $__continue)
657db96d56Sopenharmony_ci      set $__sz = $__sz - 1
667db96d56Sopenharmony_ci      set $__ad = $__ad + *$__p
677db96d56Sopenharmony_ci      set $__p = $__p + 1
687db96d56Sopenharmony_ci      if ($__ad > $__lasti)
697db96d56Sopenharmony_ci	set $__continue = 0
707db96d56Sopenharmony_ci      else
717db96d56Sopenharmony_ci        set $__li = $__li + *$__p
727db96d56Sopenharmony_ci        set $__p = $__p + 1
737db96d56Sopenharmony_ci      end
747db96d56Sopenharmony_ci    end
757db96d56Sopenharmony_ci    printf "%d", $__li
767db96d56Sopenharmony_ciend
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_cidefine pyframev
797db96d56Sopenharmony_ci    pyframe
807db96d56Sopenharmony_ci    pylocals
817db96d56Sopenharmony_ciend
827db96d56Sopenharmony_cidocument pyframev
837db96d56Sopenharmony_ci  Print the current frame - verbose
847db96d56Sopenharmony_ciend
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_cidefine pyframe
877db96d56Sopenharmony_ci    set $__fn = PyUnicode_AsUTF8(f->f_code->co_filename)
887db96d56Sopenharmony_ci    set $__n = PyUnicode_AsUTF8(f->f_code->co_name)
897db96d56Sopenharmony_ci    printf "%s (", $__fn
907db96d56Sopenharmony_ci    lineno
917db96d56Sopenharmony_ci    printf "): %s\n", $__n
927db96d56Sopenharmony_ci### Uncomment these lines when using from within Emacs/XEmacs so it will
937db96d56Sopenharmony_ci### automatically track/display the current Python source line
947db96d56Sopenharmony_ci#    printf "%c%c%s:", 032, 032, $__fn
957db96d56Sopenharmony_ci#    lineno
967db96d56Sopenharmony_ci#    printf ":1\n"
977db96d56Sopenharmony_ciend
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci### Use these at your own risk.  It appears that a bug in gdb causes it
1007db96d56Sopenharmony_ci### to crash in certain circumstances.
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci#define up
1037db96d56Sopenharmony_ci#    up-silently 1
1047db96d56Sopenharmony_ci#    printframe
1057db96d56Sopenharmony_ci#end
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci#define down
1087db96d56Sopenharmony_ci#    down-silently 1
1097db96d56Sopenharmony_ci#    printframe
1107db96d56Sopenharmony_ci#end
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_cidefine printframe
1137db96d56Sopenharmony_ci    if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault
1147db96d56Sopenharmony_ci	pyframe
1157db96d56Sopenharmony_ci    else
1167db96d56Sopenharmony_ci        frame
1177db96d56Sopenharmony_ci    end
1187db96d56Sopenharmony_ciend
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci# Here's a somewhat fragile way to print the entire Python stack from gdb.
1217db96d56Sopenharmony_ci# It's fragile because the tests for the value of $pc depend on the layout
1227db96d56Sopenharmony_ci# of specific functions in the C source code.
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ci# Explanation of while and if tests: We want to pop up the stack until we
1257db96d56Sopenharmony_ci# land in Py_Main (this is probably an incorrect assumption in an embedded
1267db96d56Sopenharmony_ci# interpreter, but the test can be extended by an interested party).  If
1277db96d56Sopenharmony_ci# Py_Main <= $pc <= Py_GetArgcArv is true, $pc is in Py_Main(), so the while
1287db96d56Sopenharmony_ci# tests succeeds as long as it's not true.  In a similar fashion the if
1297db96d56Sopenharmony_ci# statement tests to see if we are in PyEval_EvalFrameEx().
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci# Note: The name of the main interpreter function and the function which
1327db96d56Sopenharmony_ci# follow it has changed over time.  This version of pystack works with this
1337db96d56Sopenharmony_ci# version of Python.  If you try using it with older or newer versions of
1347db96d56Sopenharmony_ci# the interpreter you may will have to change the functions you compare with
1357db96d56Sopenharmony_ci# $pc.
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_cidefine pystack
1387db96d56Sopenharmony_ci    while $pc < Py_Main || $pc > Py_GetArgcArgv
1397db96d56Sopenharmony_ci        if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault
1407db96d56Sopenharmony_ci	    pyframe
1417db96d56Sopenharmony_ci        end
1427db96d56Sopenharmony_ci        up-silently 1
1437db96d56Sopenharmony_ci    end
1447db96d56Sopenharmony_ci    select-frame 0
1457db96d56Sopenharmony_ciend
1467db96d56Sopenharmony_cidocument pystack
1477db96d56Sopenharmony_ci  Print the entire Python call stack
1487db96d56Sopenharmony_ciend
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_cidefine pystackv
1517db96d56Sopenharmony_ci    while $pc < Py_Main || $pc > Py_GetArgcArgv
1527db96d56Sopenharmony_ci        if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault
1537db96d56Sopenharmony_ci	    pyframev
1547db96d56Sopenharmony_ci        end
1557db96d56Sopenharmony_ci        up-silently 1
1567db96d56Sopenharmony_ci    end
1577db96d56Sopenharmony_ci    select-frame 0
1587db96d56Sopenharmony_ciend
1597db96d56Sopenharmony_cidocument pystackv
1607db96d56Sopenharmony_ci  Print the entire Python call stack - verbose mode
1617db96d56Sopenharmony_ciend
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_cidefine pu
1647db96d56Sopenharmony_ci  set $uni = $arg0
1657db96d56Sopenharmony_ci  set $i = 0
1667db96d56Sopenharmony_ci  while (*$uni && $i++<100)
1677db96d56Sopenharmony_ci    if (*$uni < 0x80)
1687db96d56Sopenharmony_ci      print *(char*)$uni++
1697db96d56Sopenharmony_ci    else
1707db96d56Sopenharmony_ci      print /x *(short*)$uni++
1717db96d56Sopenharmony_ci    end
1727db96d56Sopenharmony_ci  end
1737db96d56Sopenharmony_ciend
1747db96d56Sopenharmony_cidocument pu
1757db96d56Sopenharmony_ci  Generally useful macro to print a Unicode string
1767db96d56Sopenharmony_ciend
177