Page 241 - 《软件学报》2026年第3期
P. 241
1204 软件学报 2026 年第 37 卷第 3 期
题的影响. 微观上, IssueAnalyzer 分别对 Issues/PRs 采样并获得匹配的 Issues/PRs 对, 人工总结常见的内存问题模
式, 并基于配对的 Issues/PRs 对, 统计修复时间和代码变更规模. 依据分析结果, 为开发者和静态分析工具开发者
提供建议, 帮助识别和解决内存问题.
Keywords
memory leak
invalid memory address
or nil pointer
dangling pointer
Condition
keywords in
title/body/comments Sample Issue-pattern: ...
996
fix-pattern: ...
Repos Issues/PRs Issues/PRs
Condition
updated in Fix time/scale
5 years Issues/PRs, Repo#, distribution
Search Issues/PRs# per Repo Repo#
Issues/PRs
Repo
domains
Keywords
Issues/PRs Repo domain
distribution distribution
图 4 内存安全问题分析工具 IssueAnalyzer
● Issue 和 PR 的匹配. 为了获得更加准确的结论, 我们对图 4 中采样得到的 Issues 和 PRs 进行了人工配对. 具
体来说, 对于一条 Issue, 人工查找提及这些 Issue 的 PR; 对于一条 PR, 查找 PR 可能修复的 Issue. 在完成 Issue 和
PR 的配对后, 判断这些 PR 是否被成功合并. 如果成功合并, 则认为该 PR 修复了对应的 Issue, 并将其作为最终的
Issue 和 PR 对保留下来.
● 修复记录统计规则. 在完成 Issue 和 PR 的配对分析后, IssueAnalyzer 统计了 PRs 的修复时间和代码变更规
模, 以评估 PRs 涉及的内存问题需要多长时间、多少代码变更才能被修复, 从而回答这些内存问题是否容易被
修复.
本文采用的修复时间间隔定义为: 当一个 PR 与某个 Issue 匹配时, 以 Issue 的创建时间作为修复的开始时间,
否则以 PR 的创建时间作为开始时间; 当一个 PR 被关闭时, 以 PR 的关闭时间作为修复结束时间, 若 PR 仍处于
open 状态时, 则以本文获取到该 PR 的时间为修复结束时间. 修复的时间间隔为修复结束时间减去修复开始时间.
这样的定义方式可以尽可能准确地反映一个问题从发现到最终修复所花费的时间.
为了评估代码变更的复杂性, IssueAnalyzer 将一个 PR 中所涉及的代码增加与删除行数的和作为代码变更
规模.
2.3 RQ3: L2-3 问题模式的检测
基于 RQ2 中归纳的内存安全问题模式, 本文探索可能的自动检测方法. 以 L2-3 模式为例, 本文编写了相应的
检测语句, 使用 QLStat 对 966 个项目数据库进行扫描分析. 检测结果展示了 L2-3 模式在真实 Go 语言项目中的分
布情况. 最终, 本文将检测到的问题反馈给相关项目, 以协助开发者改进代码质量和内存安全性.
3 RQ1: Go 语言程序的基本访存特征
基本访存操作的分布对编译器优化和性能分析的建模具有重要意义. 本文使用 QLStat 工具在程序的抽象语
法树上, 基于 966 个 Go 语言项目数据库进行了静态代码特征的分析, 主要包括以下两个方面.
(1) 基本访存模式分布 (第 3.1 节): 揭示 Go 语言中的基本访存模式及它们在实际程序中的分布情况, 统计各
类访存操作的频率.
(2) 接口类型与隐式内存分配 (第 3.2 节): 接口类型的使用可能引发隐式内存分配, 造成潜在的内存性能问题.

