Live data from Hacker News

Exploring and Dynamically Patching Django/Python Using GDB

stripe.com

11–12 of 12 posts

Re: Exploring and Dynamically Patching Django/Python Using GDB

#11
post #8
post #5

Earlier quoted context omitted.

Right, I see the use in this now. How difficult would it be to wrap this up in a reusable script that you could run directly, instead of having to manually work through the debugger prompt?

Hmm, it'd probably be doable. In particular, you can use the "commands" command to script what happens when you hit a breakpoint (a friend talked about this in a Ksplice GDB blog post: https://blogs.oracle.com/ksplice/entry/8_gdb_tricks_you_shou... ) Normally, the "finish" command will interrupt any script you're in the middle of executing, so we have to do a bit of an ugly hack to make sure our script keeps running:…

> Edited because I couldn't get monospace text working

If you start each line with a few spaces, HN will format it as source code:

    b PyEval_EvalFrameEx if strcmp(PyString_AsString(f->f_code->co_name), "handle_uncaught_exception") == 0
    commands
    disable
    frame 3
    python
    gdb.execute('finish')
    gdb.execute('shell git stash pop')
    gdb.execute('call PyImport_ReloadModule(PyImport_AddModule("monospace.views"))')
    gdb.execute('call PyImport_ReloadModule(PyImport_AddModule("monospace.urls"))')
    gdb.execute('set $self = PyDict_GetItemString(f->f_locals, "self")')
    gdb.execute('set $request = PyDict_GetItemString(f->f_locals, "request")')
    gdb.execute('set $get_response = PyObject_GetAttrString($self, "get_response")')
    gdb.execute('set $args = Py_BuildValue("(O)", $request)')
    gdb.execute('set $rax PyObject_Call($get_response, $args, 0)')
    gdb.execute('enable')
    gdb.execute('c')
    end
    c
    end

Re: Exploring and Dynamically Patching Django/Python Using GDB

#12
post #4
post #3

Couldn't you do almost the exact same thing using pdb, without all the C API / register stuff? Maybe I misunderstood the post, but it sounds like you're just stopping right before the request returns, reloading the module, generating a new response, and allowing execution to continue. Why is GDB required for any of this?

You're right! You could do all of this with pdb, but only if you have enough foresight to run the app under pdb to begin with (which I definitely never do). Using GDB, you don't have to change the app or remember to run it in a particular way.

Then perhaps it would be easier to use gdb just for bootstrapping pdb into the app?
Post reply on HN