当前位置: 首页 > news >正文

使用 AddressSanitizer 检测栈内存越界错误

一、概述

        在 C/C++ 编程中,栈内存越界 是一种常见而危险的内存错误,通常发生在局部变量数组被访问时索引越界。由于栈空间的结构特点,越界写入可能覆盖返回地址或其他局部变量,导致不可预测的行为甚至程序崩溃。传统的调试手段难以定位此类错误,而 AddressSanitizer(ASan) 提供了一种强大的检测手段。

二、什么是栈内存越界?

栈内存越界通常表现为对局部数组或变量的非法访问:

  • 写入超出数组边界

  • 读取未定义的栈空间

这类错误在编译阶段不会报错,运行阶段也可能不会立刻崩溃,因而很难发现。

三、示例代码

下面是一个典型的栈越界示例:

#include <stdio.h>void stack_overflow_example() {char buffer[10];for (int i = 0; i <= 10; ++i) {  // 注意:i <= 10 会写入 buffer[10],越界!buffer[i] = 'A';}printf("Buffer: %s\n", buffer);
}int main() {stack_overflow_example();return 0;
}

这段代码分配了一个大小为 10 的栈数组 buffer,但循环访问了 11 个元素(下标 0 到 10),导致栈内存越界。

四、使用 ASan 编译和运行

要使用 ASan 检测该问题,请用支持 ASan 的编译器(如 GCC 或 Clang)加上 -fsanitize=address -g 选项进行编译:

clang -fsanitize=address -g stack_overflow.c -o stack_overflow

或者使用 GCC:

gcc -fsanitize=address -g stack_overflow.c -o stack_overflow
运行:
./stack_overflow

五、ASan 报告解读

运行程序后,ASan 会输出类似如下的错误信息:


报告说明:

  • stack-buffer-overflow 表示捕获栈缓冲区溢出错误。

  • WRITE of size 1 at 0x7ffff130b6ba thread T0:越界写入了 1 字节。

  • 0x7ffff130b6ba :发生越界的地址。

  • [32, 42) 'buffer' (line 4) <== Memory access at offset 42 overflows this variable
    buffer
    :显示了哪一个局部变量被越界访问。

  • [32, 42):指出了越界的地方,buffer 占据了栈帧中的offset 32~41 的空间(共10字节)访问 offset 42触发越界。

六、修复建议

将循环条件修正为:

for (int i = 0; i < 10; ++i)

避免越界访问

buffer[10]

七、总结

  • 栈内存越界是一种常见的低级错误,极易引发程序崩溃或漏洞。

  • AddressSanitizer 提供了即时、高精度的栈越界检测功能,是定位此类错误的利器。

  • 养成使用 -fsanitize=address 编译调试程序的习惯,有助于在开发阶段及时发现问题。

http://www.dtcms.com/a/185499.html

相关文章:

  • 什么是数据集市(Data Mart)?
  • 如何查看电脑处理器配置 电脑处理器查看方法
  • Koa知识框架
  • 菊厂0510面试手撕题目解答
  • 一、HAL库的设计理念详解:从架构到实践
  • 简述DNS域名服务器
  • 前端面试每日三题 - Day 32
  • Browserless 快速上手
  • 全栈工程师实战手册:LuatOS日志系统开发指南!
  • C 语言_可变参数宏详解
  • temu自养号采购如何解决多账号防关联问题
  • (done) 补充:xv6 的一个用户程序 init 是怎么启动的 ?它如何启动第一个 bash ?
  • ARM64内核内存空间布局
  • The 2024 Sichuan Provincial Collegiate Programming Contest部分题解(L,H,E,B,I)
  • Ethereum Pectra 的升级
  • TWASandGWAS中GBS filtering and GWAS(1)
  • 《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》
  • 使用PhpStudy搭建Web测试服务器
  • 每日一题洛谷P8662 [蓝桥杯 2018 省 AB] 全球变暖c++
  • Ubuntu20.04 搭建Kubernetes 1.28版本集群
  • WSL 安装 Debian 12 后,Linux 如何安装 redis ?
  • C#WPF里不能出现滚动条的原因
  • SysAid On-Prem XML注入漏洞复现(CVE-2025-2776)
  • 栈和队列复习(C语言版)
  • Java笔记4
  • Go语言即时通讯系统 开发日志day1
  • OpenCV CUDA 模块中在 GPU 上对图像或矩阵进行 翻转(镜像)操作的一个函数 flip()
  • beyond compare 免密钥进入使用(删除注册表)
  • 信息安全模型全解:从机密性到完整性的理论基石
  • OpenCVCUDA 模块中在 GPU 上对图像或矩阵进行 边界填充(padding)函数copyMakeBorder()