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

使用已弃用Google Assistant Python库时释放内存触发段错误求助

解决已弃用Google Assistant Python库中assistant_free触发的段错误

我目前在使用已弃用的Google Assistant Python库,因为只有它支持“Hey Google”这类热词唤醒功能,暂时没有替代方案所以不得不继续用。现在遇到一个问题:调用self._lib.assistant_free(self._inst)时会触发Segmentation Fault(段错误),明明self._inst已经在构造函数里初始化过,而且全程都在正常使用。添加自定义语音命令或者退出程序的时候都会触发这个错误,相关信息如下:

栈追踪

Thread 0xb6f8fb40 (most recent call first):
  File "/home/steven/env/lib/python3.7/site-packages/google/assistant/library/assistant.py", line 119 in __exit__
  File "/home/steven/GassistPi/src/main.py", line 1105 in main
  File "/home/steven/GassistPi/src/main.py", line 1110 in <module>
Segmentation fault

相关代码

构造函数

def __init__(self, credentials, device_model_id):
    warnings.warn('Google Assistant Library for Python is deprecated', DeprecationWarning)
    if not device_model_id:
        raise ValueError("device_model_id must be a non-empty string")

    self._event_queue = IterableEventQueue()
    self._load_lib()
    self._credentials_refresher = None
    self._shutdown = False

    self._event_callback = EVENT_CALLBACK(self)
    self._inst = c_void_p(
        self._lib.assistant_new(
            self._event_callback,
            device_model_id.encode('ASCII'), None))
    print(self._inst)
    self._credentials_refresher = CredentialsRefresher(
        credentials, self._set_credentials)
    self._credentials_refresher.start()

__exit__方法

def __exit__(self, exception_type, exception_value, traceback):
    """Frees allocated memory belonging to the Assistant."""
    if self._credentials_refresher:
        self._credentials_refresher.stop()
        self._credentials_refresher = None
    self._shutdown = True
    self._lib.assistant_free(self._inst)

可能的原因与解决办法

1. 重复释放或野指针问题

段错误大概率是因为assistant_free被调用多次,或者self._inst已变成野指针。可以增加判断逻辑,确保只释放一次,且释放后置空指针:

def __exit__(self, exception_type, exception_value, traceback):
    """Frees allocated memory belonging to the Assistant."""
    if self._credentials_refresher:
        self._credentials_refresher.stop()
        self._credentials_refresher = None
    self._shutdown = True
    # 增加判断避免重复释放,释放后置空指针
    if self._inst and self._inst.value is not None:
        self._lib.assistant_free(self._inst)
        self._inst = None

2. 线程资源竞争问题

CredentialsRefresher是独立线程,可能存在资源竞争。停止刷新器后需等待线程完全退出,再释放实例:

def __exit__(self, exception_type, exception_value, traceback):
    """Frees allocated memory belonging to the Assistant."""
    if self._credentials_refresher:
        self._credentials_refresher.stop()
        # 等待刷新器线程完全退出
        self._credentials_refresher.join()
        self._credentials_refresher = None
    self._shutdown = True
    if self._inst and self._inst.value is not None:
        self._lib.assistant_free(self._inst)
        self._inst = None

3. 回调事件未处理完成

绑定的回调事件可能还有未处理的队列任务,导致释放实例时触发错误。先清空事件队列再执行释放:

def __exit__(self, exception_type, exception_value, traceback):
    """Frees allocated memory belonging to the Assistant."""
    self._shutdown = True
    # 清空事件队列,确保无 pending 回调
    while not self._event_queue.empty():
        try:
            self._event_queue.get_nowait()
        except queue.Empty:
            pass
    if self._credentials_refresher:
        self._credentials_refresher.stop()
        self._credentials_refresher.join()
        self._credentials_refresher = None
    if self._inst and self._inst.value is not None:
        self._lib.assistant_free(self._inst)
        self._inst = None

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:42:40