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

使用Python subprocess运行带Sanitizer的C程序无法捕获LeakSanitizer信息

问题描述

我用Sanitizer编译C代码,编译命令为:gcc -fsanitize=address -fsanitize=leak -o test test.c。在shell中直接运行./test时,可获取LeakSanitizer的错误信息,但通过Python的subprocess模块运行该程序时,无法捕获stderr内容,且returncode始终为0。我的Python代码如下:

cmd = './test'
return_info = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
outs, errs = return_info.communicate(timeout=15)
errmsg = errs.decode()
if errmsg == '':
    print('err None')
print(f'return code: {return_info.returncode}')

请问如何在Python中监控LeakSanitizer的检测结果?

解决方法

LeakSanitizer默认不会因内存泄漏修改程序退出码,且它的输出可能直接写入stdout而非stderr,加上shell=True可能干扰输出捕获,可按以下方式调整:

  • 强制LeakSanitizer修改退出码
    设置环境变量LSAN_OPTIONS=exitcode=1,这样只要检测到内存泄漏,程序就会以非0状态退出。

  • 调整subprocess参数
    避免使用shell=True(非必要时),直接传列表形式命令更可靠;可合并捕获stdout和stderr,确保拿到所有输出;同时将环境变量传递给子进程。

调整后的Python代码示例:

import subprocess
import os

# 复制当前环境变量并添加LSAN配置
env = os.environ.copy()
env['LSAN_OPTIONS'] = 'exitcode=1'

cmd = ['./test']
return_info = subprocess.Popen(
    cmd,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE,
    env=env
)
outs, errs = return_info.communicate(timeout=15)

# 合并输出内容,因为LSAN可能输出到任意一端
full_output = outs.decode() + errs.decode()
print(f"检测输出:\n{full_output}")
print(f"返回码: {return_info.returncode}")

# 根据返回码判断是否存在泄漏
if return_info.returncode != 0:
    print("检测到内存泄漏")
  • 额外注意事项
    若程序本身会向stdout输出内容,可单独区分两者输出;若必须使用shell=True,可将环境变量设置嵌入命令,比如cmd = 'LSAN_OPTIONS=exitcode=1 ./test',但不推荐该方式;确保编译时已正确添加-fsanitize=leak参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:42:18