最近在Python框架下开发,一些性能要求高的处理用C++写,然后编成共享库在python
程序中调用,于是问题来了,怎么对python的共享库进行调试呢?既然是在Linux下,那么首先想到的肯定是用GDB进行调试,那么下面先介绍一下如何使用GDB调试python调用的C++共享库,再介绍一下如何使用GDB+Code::Blocks对python调用的C++共享库进行可视化调试。
下面下附上测试用的代码:
C++共享库代码:
- //testlib.cpp
- #ifdef DEBUG
- #include <python2.7_d/Python.h>
- #else
- #include <python2.7/Python.h>
- #endif
- using namespace std;
- PyObject* CFuncEntry(PyObject* self,PyObject* args)
- {
- PyObject* datalist = NULL;
- PyArg_ParseTuple( args,"O",&datalist );
- int rst = 0;
- for ( int i = 0; i < PyList_Size(datalist); ++i )
- {
- int val = PyInt_AsLong(PyList_GetItem( datalist,i ));
- rst += val;
- }
- return Py_BuildValue("i", rst);
- }
- PyMODINIT_FUNC initCFuncEntry(void)
- {
- static PyMethodDef methods[] = {
- {"CFuncEntry", (PyCFunction)CFuncEntry, METH_VARARGS, "test lib"},
- {NULL, NULL, 0, NULL}
- };
- Py_InitModule("CFuncEntry", methods);
- }
python 代码:
- #!/usr/bin/python
- # -*- encoding: utf-8 -*-
- import CFuncEntry
- if __name__ == "__main__":
- numberlist = [1,2,3,4,5,6,7]
- rst = CFuncEntry.CFuncEntry(numberlist)
- print rst
如上图:
1. 我们所编写的两个文件
2. 编译共享库 我们编译的事debug版,需要链接的库是:-lpython2.7_d 如果没有这个库,需要下载安装python debug版
3. 使用这个命令进入python代码的调试,
这一步也可以使用 gdb –tui –args python-dbg test.py 一会进入c++代码库进行调试的时候会进入自带的可视化调试窗口
4. 设置断点 这里我用使用共享库的入口函数CFuncEntry作为断点处。这里引申一下,如果在py程序中使用了多进程,此处的断点并不会停,因为断点默认只停在父进程中,因此需要set follow-fork-mode child命令设置一下
5. 提示在py文件中没有找到函数定义,但是可能后面引入的库包含,选择y就可以了
6. r 让程序跑起来,显示程序停在了我们设置的断点函数处
7. 可以输入info locals命令看一下本函数变量的值
如果第三步输入的是:gdb –tui –args python-dbg test.py这个命令,那么执行到第6步的时候就会看到如下结果:
---------------------------------------------------------------------------------------------------------
下面是使用GDB调试脚本,输出vector类型变量的值
1.建一个.gdbinit文件在gdb调试目录或者用户目录下
文件内容如下
- define hookpost-next
- echo \n
- info locals
- echo \n
- end
- define pv
- set $i = 0
- while $i < $arg0.size()
- print $arg0.at($i)
- set $i += 1
- end
- end
- define pvfrom1to2
- set $i = $arg1
- while $i < $arg2
- print $arg0.at($i)
- set $i += 1
- end
- end
重新启动gdb或者在gdb中输入 source .gdbinit命令来使文件生效
这样就可以在GDB调试的时候直接输入:pv myvector
来打印myvector变量里面的所有元素
也可以输入:pvfrom1to2 myvector 1 3
来打印myvector中下标1到3的所有元素了