r5 - 13 Dec 2006 - 15:02:31 - BryanStearnsYou are here: OSAF >  Projects Web  >  DevelopmentHome > WxPythonProject > ChandlerWxDebugging

Debugging wx Issues in Chandler

Reid Ellis

Chandler Apps Team Engineer, OSA Foundation

26 January 2006







Introduction

This page has extra information pertaining to debugging Chandler using gdb. Specifically, several useful macros that make iot much easier to examine Python control flow and data structures.

These gdb macros are used by Robin when debugging wxWidgets:

define wx26
   cd /projects/wx2.6/wxPython/demo
   set env PYTHONPATH /projects/wx2.6/wxPython
   dir /projects/wx2.6/include/wx
   dir /projects/wx2.6/include/wx/gtk
   dir /projects/wx2.6/include/wx/generic
   dir /projects/wx2.6/wxPython/include/wx/wxPython
end

define pystring
   x/s ((PyStringObject*)$arg0)->ob_sval
end

define ps
   print $arg0.ToAscii()
end

Note that you might want to change the specific path mentioned above.

Other Useful gdb Macros for Python

gdb macros from Python's Misc directory.

# -*- ksh -*-
#
# If you use the GNU debugger gdb to debug the Python C runtime, you
# might find some of the following commands useful.  Copy this to your
# ~/.gdbinit file and it'll get loaded into gdb automatically when you
# start it up.  Then, at the gdb prompt you can do things like:
#
#    (gdb) pyo apyobjectptr
#    <module 'foobar' (built-in)>
#    refcounts: 1
#    address    : 84a7a2c
#    $1 = void
#    (gdb)

# Prints a representation of the object to stderr, along with the
# number of reference counts it current has and the hex address the
# object is allocated at.  The argument must be a PyObject*
define pyo
print _PyObject_Dump($arg0)
end

# Prints a representation of the object to stderr, along with the
# number of reference counts it current has and the hex address the
# object is allocated at.  The argument must be a PyGC_Head*
define pyg
print _PyGC_Dump($arg0)
end

# print the local variables of the current frame
define pylocals
    set $_i = 0
    while $_i < f->f_nlocals
   if f->f_localsplus + $_i != 0
       set $_names = co->co_varnames
       set $_name = PyString_AsString(PyTuple_GetItem($_names, $_i))
       printf "%s:\n", $_name
       # side effect of calling _PyObject_Dump is to dump the object's
       # info - assigning just prevents gdb from printing the
       # NULL return value
       set $_val = _PyObject_Dump(f->f_localsplus[$_i])
   end
        set $_i = $_i + 1
    end
end

# A rewrite of the Python interpreter's line number calculator in GDB's
# command language
define lineno
    set $__continue = 1
    set $__co = f->f_code
    set $__lasti = f->f_lasti
    set $__sz = ((PyStringObject *)$__co->co_lnotab)->ob_size/2
    set $__p = (unsigned char *)((PyStringObject *)$__co->co_lnotab)->ob_sval
    set $__li = $__co->co_firstlineno
    set $__ad = 0
    while ($__sz-1 >= 0 && $__continue)
      set $__sz = $__sz - 1
      set $__ad = $__ad + *$__p
      set $__p = $__p + 1
      if ($__ad > $__lasti)
   set $__continue = 0
      end
      set $__li = $__li + *$__p
      set $__p = $__p + 1
    end
    printf "%d", $__li
end

# print the current frame - verbose
define pyframev
    pyframe
    pylocals
end

define pyframe
    set $__fn = (char *)((PyStringObject *)co->co_filename)->ob_sval
    set $__n = (char *)((PyStringObject *)co->co_name)->ob_sval
    printf "%s (", $__fn
    lineno
    printf "): %s\n", $__n
### Uncomment these lines when using from within Emacs/XEmacs so it will
### automatically track/display the current Python source line
#    printf "%c%c%s:", 032, 032, $__fn
#    lineno
#    printf ":1\n"
end

### Use these at your own risk.  It appears that a bug in gdb causes it
### to crash in certain circumstances.

#define up
#    up-silently 1
#    printframe
#end

#define down
#    down-silently 1
#    printframe
#end

define printframe
    if $pc > PyEval_EvalFrameEx && $pc < PyEval_EvalCodeEx
   pyframe
    else
        frame
    end
end

# Here's a somewhat fragile way to print the entire Python stack from gdb.
# It's fragile because the tests for the value of $pc depend on the layout
# of specific functions in the C source code.

# Explanation of while and if tests: We want to pop up the stack until we
# land in Py_Main (this is probably an incorrect assumption in an embedded
# interpreter, but the test can be extended by an interested party).  If
# Py_Main <= $pc <= Py_GetArgcArv is true, $pc is in Py_Main(), so the while
# tests succeeds as long as it's not true.  In a similar fashion the if
# statement tests to see if we are in PyEval_EvalFrame().

# print the entire Python call stack
define pystack
    while $pc < Py_Main || $pc > Py_GetArgcArgv
        if $pc > PyEval_EvalFrame && $pc < PyEval_EvalCodeEx
       pyframe
        end
        up-silently 1
    end
    select-frame 0
end

# print the entire Python call stack - verbose mode
define pystackv
    while $pc < Py_Main || $pc > Py_GetArgcArgv
        if $pc > PyEval_EvalFrame && $pc < PyEval_EvalCodeEx
       pyframev
        end
        up-silently 1
    end
    select-frame 0
end


###
###
# end of pilfered code
###
###
PageInfo
PageType DevDocPage
MaintainedBy DavidSurovell
PageStatus Work in progress -- this page is still being drafted?
Trash.CommentsWelcome2 Feel free to contribute comments?
Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r5 < r4 < r3 < r2 < r1 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.