You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WinDbg调试pyx代码时查看变量值?

在WinDbg中调试Cython代码:查看本地变量与PyObject内容

查看Cython本地变量(如min_bound)的数值

WinDbg的自动变量面板对Cython生成的封装变量支持不足,需通过手动命令查看:

  1. 确认变量的C别名:Cython会将pyx中的变量转换为带__pyx_v_前缀的C变量(例如min_bound对应__pyx_v_min_bound)。可通过查看Cython生成的.c文件,或在断点处执行x helloworld!__pyx_v_*命令列出所有本地变量。
  2. 查看变量值:
    • 对于基础类型(int/float等),直接执行dt __pyx_v_min_bound;
    • 若需明确类型,可指定类型参数:dt int __pyx_v_min_bound;
    • 也可使用dv命令列出当前栈帧的所有变量,定位目标变量后查看其值。

查看PyObject类型对象(如__pyx_v_self)的内容

要实现类似Python中print(__pyx_v_self)的效果,可通过WinDbg调用Python的调试接口完成:

方法1:调用PyObject_Print函数

  1. 获取PyObject的指针地址:执行dt __pyx_v_self得到变量的内存地址(例如0x0000023456789abc)。
  2. 调用Python的打印函数:
    .call python311!PyObject_Print(0x0000023456789abc, &stdout, 0)
    
    注意:python311需替换为你实际使用的Python版本模块名(如python39、python310)。

方法2:执行Python代码片段

通过PyRun_SimpleString直接执行Python打印逻辑,将C中的PyObject指针映射到Python环境:

.call python311!PyRun_SimpleString("import ctypes; obj = ctypes.cast(0x0000023456789abc, ctypes.py_object).value; print(obj)")

将0x0000023456789abc替换为__pyx_v_self的实际地址即可。

方法3:使用WinDbg Python扩展(pycmd)

如果安装了WinDbg的Python扩展,可直接用pycmd执行Python代码:

pycmd import ctypes; print(ctypes.cast(0x0000023456789abc, ctypes.py_object).value)

最小示例

操作步骤

  1. 创建以下三个文件
  2. 执行编译命令:python setup.py build_ext --inplace
  3. 运行main.py确认代码可执行
  4. 在WinDbg中启动python.exe
  5. 在Python交互环境中执行:import os; os.chdir("你的代码文件夹路径"),再粘贴main.py中的代码并回车
  6. 在WinDbg中打开helloworld.pyx文件,设置断点
  7. 再次执行main.py中的代码触发断点

helloworld.pyx

from __future__ import print_function

def fib(n):
    """Print the Fibonacci series up to n."""
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a + b

    print()

def primes(int nb_primes):
    cdef int n, i, len_p
    cdef int[1000] p

    if nb_primes > 1000:
        nb_primes = 1000

    len_p = 0  # 当前p中的元素数量
    n = 2
    while len_p < nb_primes:
        # 判断n是否为质数
        for i in p[:len_p]:
            if n % i == 0:
                break

        # 如果循环没有break,说明是质数
        else:
            p[len_p] = n
            len_p += 1
        n += 1

    # 将结果复制到Python列表
    result_as_list = [prime for prime in p[:len_p]]
    return result_as_list

class MyClass:
    def __init__(self, n) -> None:
        self.fib = fib(n)
        self.primes = primes(n)
        # 尝试在Windbg中查看self.fib和self.primes的值

setup.py

from setuptools import Extension, setup
from Cython.Build import cythonize

extensions = [Extension('helloworld', ["helloworld.pyx"], extra_compile_args=["-Ox", "-Zi"], extra_link_args=["-debug:full"])]
setup(
    ext_modules = cythonize(extensions, gdb_debug=True, emit_linenums=True)
)

main.py

import helloworld
my_class = helloworld.MyClass(2000)
print(my_class.fib)

内容的提问来源于stack exchange,提问作者codeDom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:24:54