【问题标题】:Debugging Pybind11 extension with Visual Studio Code (MacOS)使用 Visual Studio Code (MacOS) 调试 Pybind11 扩展
【发布时间】:2020-04-28 21:14:52
【问题描述】:

我最近一直在使用 pybind11,现在我掌握了它的窍门,我对它很兴奋。这是一部很棒的作品。执行 pybind11 的工具难题的最后一部分是调试部分。我已经使用以下指南对 lldb 进行命令行调试:

Debugging pybind11 with lldb

我花了一些时间尝试使用 Visual Studio Code 进行调试,但收效甚微。第一个问题是,为了设置 attach 配置,您需要指定 python 可执行文件(而不是进程 ID)。如果您有多个活动的 python 进程,我不知道这应该如何工作,这种情况经常发生。

抛开这些,我设置了一个 launch 配置来指向 ipython 可执行文件,这是最方便使用的东西。当我尝试开始调试时,我得到了这个:

谁能解释一下?

如果我将可执行文件更改为纯 Python,我会在调试控制台中得到这个:

Could not initialize Python interpreter - only native expressions will be available.
Launching: /Users/andy/anaconda3/envs/SciPy37/bin/python

但是如果进入终端窗口,我可以成功输入 Python 表达式,并触发代码中设置的断点。万岁!但是还有一个问题。当我的一个扩展需要加载另一个dylib时,它找不到它。

>>> import block_test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/Users/andy/Dropbox (Personal)/Developer/AudioDev/GenericDSP/Common/SciPy/BlockTest/build/block_test.cpython-37m-darwin.so, 2): Symbol not found: _vDSP_vsmul
  Referenced from: /Users/andy/Dropbox (Personal)/Developer/AudioDev/GenericDSP/Common/SciPy/BlockTest/build/block_test.cpython-37m-darwin.so
  Expected in: flat namespace
 in /Users/andy/Dropbox (Personal)/Developer/AudioDev/GenericDSP/Common/SciPy/BlockTest/build/block_test.cpython-37m-darwin.so

这是有道理的,因为_vDSP_vsmul 是Apple DSP 加速库的一部分。但是我没有得到的是,当我使用本文开头提到的命令行调试技术时,我没有这个问题。显然这与如何找到 dylib 有某种关系,但是为什么这与命令行的情况不同呢?

在这些问题上的任何帮助都会很棒。让这些调试工具在 Visual Studio Code 中工作是 Python 和 C++ 之间绝对惊人的互操作性所缺少的部分

【问题讨论】:

  • 原来依赖库的第三个问题不是 VSC 问题。 Python 命令行也有同样的问题。 ipython 没有,不知道为什么。该问题已通过明确链接到 Accelerate 库来解决。但是 ipython 的谜团和关于缺少架构的错误消息仍然存在。
  • 虽然我还没有弄清楚如何无缝 VSC 调试 Visual Studio Code 和 ipython,但我确实找到了使用 Xcode 的简单方法。如果您使用的是 cmake,则可以使用它来生成 xcode 项目。然后就可以启动iPython,在Activity monitor中找到pid,通过pid附加到进程中进行调试。效果很好。

标签: c++ debugging visual-studio-code pybind11 python-extensions


【解决方案1】:

我想出了如何通过 iPython 和 Mac OS Catalina 附加到进程调试以使用 Visual Studio Code。 launch.json 中的以下代码将起作用:

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "name": "Debug",
      "program": "path_to/bin/python",
      "args": [],
      "cwd": "${workspaceFolder}/build"
    },
    { 
      "name": "Debug Attach",
      "type": "lldb",
      "request": "attach",
      "program": "path_to/bin/python",
      "processId": "${command:pickProcess}",
      "MIMode": "gdb"
  },
  ]
}

首先,在尝试开始调试之前,在终端窗口中启动 IPython,这样您就有了要附加到的进程。

我最初遇到 VSC 的问题,抱怨 json 文件中没有“程序”条目,这在附加到进程时似乎无关紧要。它实际上可能完全无关紧要,但是您必须添加它才能使事情正常进行。我没有尝试为程序参数输入一个虚假条目来查看值是否重要。

另一个细节 - 有时 VSC 中的断点似乎未启用,创建它们时会得到一个未填充的圆圈而不是红点。但似乎无论如何你都会遇到断点。但是,根据我之前的经验,最好在附加到进程后将被测iPython中的包导入,以获得最佳效果。

【讨论】:

  • “我没有尝试为程序参数输入虚假条目以查看值是否重要。”...无效条目会为我停止启动,所以是的有效程序/这里似乎需要可执行文件
【解决方案2】:

我偶然发现了这篇 SO 帖子 How to configure VS Code to be able to step into a shared library (.so) that is loaded when debugging a Python script?,我不必附加到已经运行的调试器,而是能够从 VSCode 中启动 gdb:

    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch 1123",
            "type": "cppdbg",
            "request": "launch",
            "program": "/usr/bin/python3",
            "args": ["${file}"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

通过这个launch.json 设置,我可以单步执行设置断点的C++ 代码并调试我的C++ 代码。但是,正如之前 SO 帖子的 cmets 中所述,我不确定在调试会话期间是否有一种方法可以在 python 和 C/C++ 代码之间流动。如果试图在我的 python 文件上放置断点,我也会“在创建它们时得到一个未填充的圆圈而不是红点”。

【讨论】:

    【解决方案3】:

    我在使用 LLDB 的 macOS 10.14.5 中遇到了问题。 对我有用的是使用以下配置为 VS Code 安装“vadimcn.vscode-lldb”扩展:

    {
        // Use IntelliSense to learn about possible attributes.
        // Hover to view descriptions of existing attributes.
        // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {
                "type": "lldb",
                "request": "attach",
                "name": "Attach pid",
                "pid": "${command:pickProcess}", // use ${command:pickProcess} to pick other users' processes,
            },
            {
                "name": "Python: Current File",
                "type": "python",
                "request": "launch",
                "program": "${file}",
                "console": "integratedTerminal",
                "stopOnEntry": true,
                "env": {
                    "PYTHONPATH": "${workspaceFolder}/build"
                }
            },
            {
                "type": "lldb",
                "request": "launch",
                "name": "LLDB Python",
                "program": "/usr/local/bin/python3",
                "args": [
                    "${file}"
                ],
                "cwd": "${workspaceFolder}",
                "stopOnEntry": false,
                "env": {
                    "PYTHONPATH": "${workspaceFolder}/build"
                },
            },
        ]
    }
    

    要么使用 lldb (LLDB Python) 启动 python,要么我首先启动一个 python 调试会话 (Python: Current File),然后我可以附加到 (Attach pid)。第二个选项的好处是能够在 python 和 C++ 中设置断点。

    【讨论】:

    • “当前文件”然后“附加”方法对我不起作用,因为弹出了三个不同的 Python 进程,当我尝试附加时它们都不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 2021-11-22
    相关资源
    最近更新 更多