Debugging a Python process using GDB

Source: Internet
Author: User
Tags print print sleep function python script

Debugging a Python process with gdb sometimes we want to debug a running Python process, or a Python process coredump. For example, now encountered a MOD_WSGI process zombie, do not accept the request, want to see exactly what line of Python code to run it? At this point, we need to sacrifice gdb. The main step is three steps: 1) to ensure that your GDB version >=72) installs the Python-debuginfo package (for example: python-debuginfo-2.6.6-29.el6_2.2.x86_64.rpm, This version number must be consistent with the version of Python you are using. HTTP://DEBUGINFO.CENTOS.ORG/6/X86_64/) 3) can be debugged with the #gdb python process number. Get ready

1. Confirm that your GDB version is >=7,gdb support for the debug of Python starting from version 7.

2. Confirm that the python that gdb is connecting to is the python you want to debug, or recompile gdb.

Method:

1234567 $ gdb(gdb) python>import sys>print sys.version>end2.4.3 (#1, Sep 21 2011, 19:55:41) [GCC 4.1.2 20080704 (Red Hat 4.1.2-51)]

In some of the stable distributions (for example, CentOS),the Python version will be lower, and it will compile a python for itself. GDB, which is installed from the source, connects to the Python version in the source . For example, in CentOS 5.4, the source Python is 2.4.3, and gdb from the source is also connected to the Python 2.4.3.

Compile-time note that you want to add your own compiled Python path to the PATH environment variable, so GDB configure will find a new version of Python and connect .

3. Download libpython.py

How to Debug

Assume that the process number to debug is 1000

1 $ gdb -p 1000

Use this command to attach gdb to the process.

Loading the Libpython script
    • If your gdb has been modified by a vendor such as Redhat or fedora, there will be a--python option that allows you to specify the Python extension script that is loaded when GDB starts (this script extends GDB, not the script we need to debug).
      1 $ gdb --python /path/to/libpython.py -p 1000
    • If you are installing GNU GDB, you will need to manually load the libpython.py script after opening gdb.

      123456 (gdb) python>import sys>sys.path.insert(0, ‘/path/to/libpython.py‘ )> importlibpython>end(gdb)

You can then use the PY-BT command to print the current thread's Python traceback.

Libpython also provides many commands, such as py-print print variables, py-locals print all local variables, and so on, to open libpython.py view in detail.

A little experience
    • GDB can use the generate-core-file command to generate a coredump file. You can then use Gdb–core to open the Coredump file for debug. Avoid attach live process, can quickly restart recovery services
    • Gdb-heap is an extension of gdb. Can print Python's memory usage

Resources

    • Debuggingwithgdb
    • Easierpythondebugging
    • Debugging with GDB (GDB documentation)

Debugging a Python script using gdb

Debugging Python scripts can generally be done by logging logs and using the PDB module that comes with Python , but there are always exceptions to this, and there are three scenarios where the above method is powerless.
1-Segment Error
2 Daemon Programs in operation
3 Core Dump
At this point you need to sacrifice gdb for debugging. python2.6 's source code provides some pre-defined functions for everyone to use GDB debugging, we just need to python-2.6/misc/the file The content included in the Gdbinit is added to the. gdbinit file in the user directory, so the definitions of these macros are automatically completed each time GDB is started. Unfortunately, Python2.6.2 Gdbini's definition of pylocals was wrong, and it appears that it has not been updated as the code is updated. We only need to modify the while $_i < f->f_nlocals to the while $_i < F->f_code->co_nlocals. Several macro recommendations appended to the article are also included in the. gdbinit file, with more macros available for reference

http://web.archive.org/web/20070915134837/

Http://www.mashebali.com/?Python_GDB_macros:The_Macros.


We first need to construct a Python script that will cause a fragment error. To be honest, it's not easy for Python to have a segment error, but it's easy to call the library from outside . We'll name the file gdb_test.py.
Import sys, OS, LIBXML2

Def segv_test ():
s = "Options = libxml2. Html_parse_recover + \
LIBXML2. Html_parse_noerror + \
LIBXML2. Html_parse_nowarning
Doc = Libxml2.htmlreaddoc (S, None, ' utf-8 ', options). doc
Ctxt = Doc.xpathnewcontext ()
nodes = Ctxt.xpatheval ('//body/node () ')
Nodes.reverse ()
For note in nodes:
nexts = Note.xpatheval (' node () ')
Note.unlinknode ()
Note.freenode ()//freenode will release the node and its child nodes
Nexts[0].unlinknode ()
Nexts[0].freenode ()//resource released, re-release will cause a segment error

def main ():
Segv_test ()

if __name__ = = "__main__":
Main ()

Using GDB to run the script, we get a segment error message.
GDB python
R gdb_test.py

GLIBC detected * * * double free or corruption (fasttop): 0x08104570 * * *

Program received signal SIGABRT, aborted.
[Switching to Thread-1208260928 (LWP 26159)]
0X00B987A2 in _dl_sysinfo_int80 () from/lib/ld-linux.so.2

Type BT to get the following stack information:
(GDB)BT
#0 0x00b987a2 in _dl_sysinfo_int80 () from/lib/ld-linux.so.2
#1 0x00c00825 in Raise () from/lib/tls/libc.so.6
#2 0x00c02289 in Abort () from/lib/tls/libc.so.6
#3 0x00c34cda in __libc_message () from/lib/tls/libc.so.6
#4 0x00c3b56f in _int_free () from/lib/tls/libc.so.6
#5 0x00c3b94a in free () from/lib/tls/libc.so.6
#6 0x009812c6 in Xmlfreenode () from/opt/sohumc/lib/libxml2.so.2
#7 0x0029d7f3 in Libxml_xmlfreenode () from/opt/sohumc/lib/python2.6/site-packages/libxml2mod.so
#8 0x00780bae in Pycfunction_call (func=0x8104570, arg=0xd05820, kw=0x6) at objects/methodobject.c:116
#9 0x007d8c79 in Call_function (pp_stack=0xbff8c48c, oparg=0) at python/ceval.c:3679
#10 0x007d6d2b in Pyeval_evalframeex (F=0X8124EF4, throwflag=0) at python/ceval.c:2370
#11 0x007d8e36 in Fast_function (func=0x6, PP_STACK=0XBFF8C5DC, N=1, Na=1, nk=0) at python/ceval.c:3765
#12 0x007d89cd in Call_function (PP_STACK=0XBFF8C5DC, oparg=0) at python/ceval.c:3700
#13 0x007d6d2b in Pyeval_evalframeex (F=0X81242FC, throwflag=0) at python/ceval.c:2370
#14 0x007d8e36 in Fast_function (func=0x6, pp_stack=0xbff8c72c, n=0, na=0, nk=0) at python/ceval.c:3765
#15 0x007d89cd in Call_function (pp_stack=0xbff8c72c, oparg=0) at python/ceval.c:3700
#16 0x007d6d2b in Pyeval_evalframeex (F=0X810A7C4, throwflag=0) at python/ceval.c:2370
#17 0x007d8e36 in Fast_function (func=0x6, pp_stack=0xbff8c87c, n=0, na=0, nk=0) at python/ceval.c:3765
#18 0x007d89cd in Call_function (pp_stack=0xbff8c87c, oparg=0) at python/ceval.c:3700
#19 0x007d6d2b in Pyeval_evalframeex (f=0x8091d0c, throwflag=0) at python/ceval.c:2370
#20 0x007d76f9 in Pyeval_evalcodeex (co=0xb7fa3728, globals=0x6, locals=0xb7f9902c, args=0x0, argcount=0, kws=0x0, Kwcount=0, defs=0x0, defcount=0,
closure=0x0) at python/ceval.c:2942
#21 0X007D47CB in Pyeval_evalcode (co=0xb7fa3728, globals=0xb7f9902c, locals=0xb7f9902c) at python/ceval.c:515
#22 0X007FBBCE in Run_mod (mod=0x80ea780, Filename=0xbffc6be6 "gdb_test.py", globals=0xb7f9902c, locals=0xb7f9902c, FLAGS=0XBFF8CA8C, Arena=0x807ef28)
At python/pythonrun.c:1330
#23 0x007fbb58 in Pyrun_fileexflags (fp=0x8091d00, Filename=0xbffc6be6 "gdb_test.py", start=257, globals=0xb7f9902c, LOCALS=0XB7F9902C, Closeit=1,
FLAGS=0XBFF8CA8C) at python/pythonrun.c:1316
#24 0x007fb22d in Pyrun_simplefileexflags (fp=0x8091d00, Filename=0xbffc6be6 "gdb_test.py", Closeit=1, flags= 0XBFF8CA8C) at python/pythonrun.c:926
#25 0x007facc9 in Pyrun_anyfileexflags (fp=0x8091d00, Filename=0xbffc6be6 "gdb_test.py", Closeit=1, flags=0xbff8ca8c) At python/pythonrun.c:731
#26 0x00808fea in Py_main (Argc=1, Argv=0xbff8cbb4) at modules/main.c:597
#27 0x080486ae in Main (argc=2, Argv=0xbff8cbb4) at modules/python.c:23

The Pystack and PYSTACKV two macros can be used to view the stack situation inside Python, and you can see that the program ends when it executes to the Freenode function, which is located in 3141 rows of libxml2.py.
(GDB)Pystack
/opt/lib/python2.6/site-packages/libxml2.py (3141): freenode
gdb_test.py (+): segv_test
gdb_test.py (+): Main
gdb_test.py (): <module>

from the stack we can see the invocation relationships of the functions within the script, so how do we look at the variables in the function? As you can say, the invocation of the Python internal stack and function is done by Pyeval_evalframeex, once Pyeval_evalframeex means a function call, like the above line 19,13,10 corresponds to Main, segv_test, Freenode function, after GDB is anchored to the corresponding row, use the Pylocals macro to see the details of the variables inside the function.
(GDB) up 13
#13 0x007d6d2b in Pyeval_evalframeex (F=0X81242FC, throwflag=0) at python/ceval.c:2370
2370 in PYTHON/CEVAL.C
(GDB) Pylocals
S
Object: ' Type:str
Refcount:3
address:0xb7f64440
Options
object:97
Type:int
Refcount:7
Address:0x8082c20
Doc
Object: <xmldoc (None) object at 0xb7cc04ec>
Type:instance
Refcount:1
Address:0xb7cc04ec
Ctxt
Object: <libxml2.xpathcontext instance at 0xb7f70ccc>
Type:instance
Refcount:1
Address:0xb7f70ccc
Nodes
object: [<xmlnode (儓 x? object at 0xb7cc0cac>]
Type:list
Refcount:2
address:0xb7f70a8c
Note
Object: <xmlnode (? 圶. Object at 0xb7cc0cac>
Type:instance
Refcount:2
Address:0xb7cc0cac
Nexts:
object: [<xmlnode (HhX object at 0xb7cc750c>, <xmlnode (HXX. Object at 0xb7cc76cc>, <xmlnode (@XX? object at 0xb7c9348c>]
Type:list
Refcount:1
address:0xb7f4ce4c

The setting of breakpoints in script debugging is a very troublesome thing, I can think of two ways: 1 according to the function of the Python source code to set breakpoints, 2 using the Sleep function and CTRL + C to interrupt the program's operation. It's a pain to use execution-by-article debugging, because the Python interpreter itself has a lot of work to do .

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.