您的位置:首页 > 编程语言 > C语言/C++

使用GDB调试python调用的C++共享库

2015-08-05 16:35 871 查看


最近在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的所有元素了


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: