【问题标题】:Debugging Python and C++ exposed by boost together一起调试boost暴露的Python和C++
【发布时间】:2016-12-18 07:35:49
【问题描述】:

我可以使用ddd -pydb prog.py 调试 Python 代码。所有 python 命令行参数也可以在prog.py 之后传递。在我的例子中,许多类已经用 C++ 实现,它们使用boost-python 暴露给 python。我希望我可以一起调试 python 代码和 C++。例如我想设置这样的断点:

break my_python.py:123
break my_cpp.cpp:456
cont

当然,我在使用调试选项编译 c++ 代码后尝试它,但调试器不会越过 boost 边界。有什么办法吗?

编辑: 我看到了http://www.boost.org/doc/libs/1_61_0/libs/python/doc/html/faq/how_do_i_debug_my_python_extensi.html。 我跟着它,我可以为 python 和 C++ 进行调试。但我更喜欢用DDD 进行可视化调试,但我不知道如何在DDD 中给出'target exec python' 命令。如果不是(仅使用链接中的gdb),我应该能够调试 Python 脚本,而不是像链接中那样以交互方式提供 python 命令。

【问题讨论】:

标签: python c++ debugging boost ddd-debugger


【解决方案1】:

我发现了如何在运行 python 时调试 C++ 部分。 (在阅读 Python 书籍中的进程 ID 检测时意识到这一点。)。
首先,您运行包含 C++ 程序的 python 程序。在 python 程序开始时,使用 raw_input() 让程序等待你输入。但在此之前做print os.getpid()(当然你应该已经导入了os包)。当你运行 python 程序时,它会打印出你正在运行的 python 程序的 pid,并等待你的键盘输入。

python 停止代码:

import os

def w1(str):
    print (str)
    wait = raw_input()
    return

print os.getpid()
w1('starting main..press a key')

结果:

27352
starting main..press a key

或者,您可以使用 import pdb, pdb.set_trace() 作为下面的注释。(感谢@AndyG)并查看 EDIT* 以使用ps -aux 获取 pid。

现在,假设 C++ 共享库是 _caffe.so(这是我的情况。这个 _caffe.so 库包含所有 C++ 代码和 boost python 包装函数)。 27352 是 pid。然后在另一个 shell 中像

一样启动 gdb
gdb caffe-fast-rcnn/python/caffe/_caffe.so 27352

或者,如果您想使用 DDD 之类的图形调试,请执行

ddd caffe-fast-rcnn/python/caffe/_caffe.so 27352

然后你会看到 gdb 启动并等待提示。 python 程序被 gdb 中断并在停止模式下等待(它正在等待您的键输入,但现在它实际上处于停止模式,它需要来自第二个调试器的 gdb continue 命令才能继续键等待)。
现在你可以像

一样在 gdb 中给出断点命令
br solver.cpp:225

你可以看到像

这样的消息
Breakpoint 1 at 0x7f2cccf70397: file src/caffe/solver.cpp, line 226. (2 locations)

当您在第二个 gdb 窗口(保存程序)中发出 continue 命令时,python 代码再次运行。当然,您应该在第一个 gdb 窗口中输入一个键以使其继续。
现在至少您可以在运行 python 程序的同时调试 C++ 代码(这就是我想要做的)!

我后来检查了我是否可以同时进行 python 和 C++ 调试并且它可以工作。您像ddd -pydb prog1.py options.. 一样启动调试器(DDD)并使用上述方法附加另一个 DDD。现在您可以为 python 和 C++ 设置断点,并在每个窗口中使用其他调试功能(我希望我在几个月前就知道这一点。它应该有帮助。)。

编辑:要获取 pid,您可以改为使用 ps -aux | grep python。这个 pid 是 ddd 的下一个 pid。

【讨论】:

  • pdb.set_trace() 可能是让 Python 暂停的更好方法,但最终它们具有相同的效果。
【解决方案2】:

我遇到了类似的问题,但未能让Chan's answer 中的解决方案发挥作用(在 MAC OS X 10.12.4 上)。相反,以下内容对我有用。

  1. 编写一个python脚本test.py,导入并使用boost.Python模块。
  2. 在调试器中启动 python

    lldb python3 test.py
    

    给予

    > lldb python3 test.py
    (lldb) target create "python3"
    Current executable set to 'python3' (x86_64).
    (lldb) settings set -- target.run-args  "test.py"
    (lldb) run
    Process 46189 launched: '/Users/me/anaconda/bin/python3' (x86_64)
    test.cpython-36m-darwin.so was compiled with optimization - stepping may behave oddly; variables may not be available.
    Process 46189 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10d4b3000)
    frame #0: 0x00000001019f49c2 test.cpython-36m-darwin.so`std::__1::enable_if<true, void>::type (anonymous namespace)::Render2D<double>::add_particle<true, 5ul>(float*, float, float, float, float) const [inlined] mylib::SSE::packed<8ul, float>::loadu(
       944        { return {_mm256_load_ps(p)}; }
       945        /// load from unaligned memory location
       946        static __always__inline packed loadu(const element_type*p) noexcept
    -> 947        { return {_mm256_loadu_ps(p)}; }
       948        /// load from aligned memory location, using template arg for alignment
       949        template<bool aligned>
    
       950        static __always_inline enable_if_t< aligned, packed>
    

无需获取 pid 并从单独的窗口启动调试器或设置任何断点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多