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

Python不可抛出异常告警时触发调试器,解决CFFI回调调试问题

针对CFFI不可抛出异常的断点调试方案

核心原理

CFFI在回调异常无法抛回C侧时,会将异常写入Python的sys.unraisable钩子链,Python 3.8+原生支持sys.unraisablehook接口,我们可以通过劫持该钩子实现异常触发时立刻断点,无需等待pytest测试结束后才上报告警。

方案1:代码注入Hook(兼容PyCharm/pdb)

在测试入口或项目初始化代码中加入以下逻辑,异常发生时会直接中断在当前调用栈:

import sys
# 保留原有钩子逻辑,避免破坏pytest等工具的告警上报
original_unraisable_hook = sys.unraisablehook

def debug_unraisable_hook(unraisable):
    # pdb调试用下一行,PyCharm也可以直接在本行点击左侧添加图形断点
    import pdb; pdb.set_trace()
    # 执行原有钩子逻辑
    original_unraisable_hook(unraisable)

sys.unraisablehook = debug_unraisable_hook

该方案覆盖所有不可抛出异常场景:包括CFFI回调返回前的异常、对象析构/终结时触发的异常,中断时可直接查看完整调用栈,定位嵌套回调的真实报错位置。

方案2:PyCharm图形化断点(无需修改代码)

  • 打开断点设置面板:快捷键⇧⌘F8(Mac)/Ctrl+Shift+F8(Windows/Linux),或点击菜单栏「Run → View Breakpoints」
  • 点击「+」选择「Python Exception Breakpoint」,搜索你遇到的异常类型(比如示例中的TypeError,或全局匹配BaseException)
  • 勾选「Notify when exception is uncaught」,取消勾选「Skip library files」(避免CFFI相关代码被过滤导致断点不触发)
  • 启动调试模式运行测试即可,异常发生时会直接中断。

额外加固:统一回调装饰器

如果是自己实现的CFFI回调,可以统一加调试装饰器,所有回调异常第一时间触发断点:

from functools import wraps

def cffi_callback_debug(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            # 此处加断点,捕获所有回调内部异常
            import pdb; pdb.set_trace()
            raise
    return wrapper

# 使用示例:所有CFFI回调都加该装饰器
@cffi_callback_debug
def your_callback(...):
    # 回调逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 16:36:03