已关闭
【缺陷报告】内存泄漏 - 文件test_geir_indexer_quant_cache.cpp - 函数main - 行号246 #4792
zhangjunkai9创建于  8月31日关闭于  9月4日
zhangjunkai9
8月31日 创建

缺陷信息

缺陷类型memoryLeak (内存泄漏)
函数main
文件attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp
行号246
置信度90%
分析模型maas-glm-5.1-zhipu

缺陷描述

在 main 函数中,第246行通过 'ge::Session *session = new Session(build_options)' 在堆上分配了 Session 对象。在 RunGraph 失败路径(第268-273行)有 'delete session' 释放,但在成功路径上(第274-313行),函数执行到第313行 'return SUCCESS' 时从未调用 delete session,导致 Session 对象泄漏。第307行调用的 GEFinalize() 负责终结 GE 引擎,但不负责释放用户 new 出的 Session 对象——失败路径显式 delete 证明了开发者意图需手动释放,成功路径遗漏了该释放。

同类问题

        {
          "file": "attention/scatter_pa_kv_cache_with_k_scale/examples/test_geir_scatter_pa_kv_cache_with_k_scale.cpp",
          "func": "main",
          "line": 229,
          "description": "在 main 函数中,第229行通过 new Session(build_options) 在堆上分配了 Session 对象。第251行 RunGraph 失败的错误路径中有 delete session(第253行),但成功路径从第257行继续执行到第298行 return SUCCESS,期间未 delete session。GEFinalize() 是全局清理函数,不负责释放用户 new 创建的 Session 对象,导致成功路径上 session 堆内存泄漏。"
        },
        {
          "file": "attention/stem_oam_prep_varlen_q/examples/test_geir_stem_oam_prep_varlen_q.cpp",
          "func": "main",
          "line": 272,
          "description": "在 main 函数中,第272行通过 new Session(build_options) 在堆上分配了 Session 对象。第294行 RunGraph 失败的错误路径中有 delete session(第296行),但成功路径从第300行继续执行到第341行 return SUCCESS,期间未 delete session。GEFinalize() 是全局清理函数,不负责释放用户 new 创建的 Session 对象,导致成功路径上 session 堆内存泄漏。"
        },
        {
          "file": "ffn/ffn_worker_batching/examples/test_geir_ffn_worker_batching.cpp",
          "func": "main",
          "line": 228,
          "description": "在 main 函数中,第228行通过 new Session(build_options) 在堆上分配了 Session 对象。第249行 RunGraph 失败的错误路径中有 delete session(第252行),但成功路径从第256行继续执行到第297行 return SUCCESS,期间未 delete session。GEFinalize() 是全局清理函数,不负责释放用户 new 创建的 Session 对象,导致成功路径上 session 堆内存泄漏。"
        },
        {
          "file": "ffn/swin_attention_ffn/examples/test_geir_swin_attention_ffn.cpp",
          "func": "main",
          "line": 314,
          "description": "在 main 函数中,第254行通过 new Session(build_options) 在堆上分配了 Session 对象。第275行 RunGraph 失败的错误路径中有 delete session(第278行),但成功路径从第282行继续执行到第320行 return SUCCESS,期间未 delete session。GEFinalize() 是全局清理函数,不负责释放用户 new 创建的 Session 对象,导致成功路径上 session 堆内存泄漏。"
        },
        {
          "file": "moe/moe_re_routing/examples/test_geir_moe_re_routing.cpp",
          "func": "main",
          "line": 253,
          "description": "函数 main 在第253行通过 new Session(build_options) 创建堆对象 session。在第274行 RunGraph 失败的分支(第277行)执行了 delete session,但在 RunGraph 成功的正常执行路径(第281行之后到第322行 return SUCCESS)中,session 从未被 delete 释放。函数在成功路径上直接返回 SUCCESS,导致 session 对象的堆内存泄漏。GEFinalize() 不会释放由 new Session 分配的堆内存。"
        },
        {
          "file": "posembedding/rope_quant_kvcache/examples/test_geir_rope_quant_kvcache.cpp",
          "func": "main",
          "line": 261,
          "description": "函数 main 在第261行通过 new Session(build_options) 分配堆内存 session。在错误路径上(RunGraph 失败,第285行)有 delete session 释放,但在成功执行路径上(第289行之后至第329行 return SUCCESS),session 从未被 delete 释放。对比同仓其他测试文件(如 test_geir_inplace_partial_rotary_mul_grad.cpp 第321行)在成功路径上均有 delete session,本文件遗漏了成功路径的释放。main 为程序入口函数(depth=0),必然可达,泄漏可被实际触发。"
        }

事实核查

核查1(模式成立):第246行 ge::Session *session = new Session(build_options) 堆分配 Session 对象;

失败路径第270行有 delete session 释放(证明开发者意图需手动释放),但成功路径(第274-313行)执行到第313行 return SUCCESS 时从未调用 delete session;

第307行 GEFinalize() 仅终结 GE 引擎不释放 session 对象(失败路径同时调用 delete session 和 GEFinalize 佐证)。

核查2(防护无效):成功路径无任何 session 释放防护。

核查3(函数可达):main 为入口函数,depth 0,可达。

核查4(触发可满足):泄漏发生在成功路径即正常执行路径,RunGraph 成功后函数正常返回时 session 泄漏,触发条件满足。

模式成立+无防护+可达+触发可满足,确认为真实缺陷。

数据流证据

Source(问题源头)

attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp:246 行 ge::Session *session = new Session(build_options) 在堆上分配 Session 对象

Sink(问题爆发点)

attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp:313 行 return SUCCESS 成功路径返回,session 指针从未被 delete 释放

传播路径:

# 文件 行号 说明
1 attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp 246 ge::Session *session = new Session(build_options) 堆分配 Session 对象,session 指针持有该对象
2 attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp 259 ret = session->AddGraph(graph_id, graph, graph_options) 使用 session 对象
3 attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp 267 ret = session->RunGraph(graph_id, input, output) 使用 session 对象
4 attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp 270 delete session 仅在 RunGraph 失败路径释放 session(对比证明成功路径应同样释放)
5 attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp 307 ret = ge::GEFinalize() 终结 GE 引擎但不释放 session 对象
6 attention/indexer_quant_cache/examples/test_geir_indexer_quant_cache.cpp 313 return SUCCESS 成功返回,session(第246行 new 分配)未被 delete,造成堆内存泄漏

调用链

可达调用链1 起点:(entry functions) → 终点:main 深度:0

# 文件 函数 函数起始行 调用点行
1 attention/attention_update/examples/test_aclnn_attention_update.cpp main 77 —

修复建议

// 在第307行 GEFinalize 之前、成功路径上释放 session
printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str());
delete session;  // 释放成功路径上的 session 对象
ret = ge::GEFinalize();
if (ret != SUCCESS) {
    printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str());
    return FAILED;
}
printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str());
return SUCCESS;
likedislike
Zzhangjunkai9
8月31日 修改了issue 的描述
weihao18成员
9月1日 评论:

你好,建议汇总到具体算子进行集中处理

likedislike
游游震成员
9月3日 将 luwei_1104 设为负责人
游震成员
9月3日 评论:

/assign @luwei_1104

likedislike
CANN-robot
CANN-robot成员
9月3日 评论:

Notice

This issue is already assigned to luwei_1104. Please do not assign repeatedly.

likedislike
CANN-robot
CANN-robot成员
9月3日 评论:

Notice

This issue can not be assigned to qq_37913898. Please try to assign to the repository members.

likedislike
chendunyangchendunyang
9月4日 关联了pull request:fix(indexer_quant_cache): 修复GEIR内存泄漏并补充数值golden
CANN-robotCANN-robot成员
9月4日 关闭了 issue
CANN-robotCANN-robot成员
9月4日 添加了label:resolved