记忆问题很难找到,因为您不使用ASAN

来源:爱酷猪责编:网络时间:2025-06-19 14:52:23

大家好,今天来为大家解答记忆问题很难找到,因为您不使用ASAN这个问题的一些问题点,包括也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~

2.为什么我们需要ASAN

在c/c++开发过程中,经常出现内存异常使用的问题,比如踩内存,被踩的内存如果未被使用对外无影响。而一旦使用了被踩的内存,可能会出现进程core,死循环,进入异常分支等等各种千奇百怪的问题。这个时候要去定位这段内存为什么被踩,相当困难,因为已经错过了案发现场。如果不幸,遇到了这种问题,常用手段是:

1)分析被踩内存的特征值,比如是否是一个magic值,然后从代码库中找特征值,分析代码,缩小排查方向。

2)找到必现条件,通过gdb的watch功能,watch被踩的内存地址,一旦被踩,gdb将会打出踩内存的堆栈。

所以,我们迫切的希望,能在踩内存的第一现场就把凶手抓住,而不是在破坏已经表现出来的时候再去分析定位。而asan就能达到这个目的,它会接管内存的申请和释放,每次的内存的读写都会检查,因此可以做到快速的定位踩内存的问题。在asan之前也有其他的内存分析工具,但是asan是这些工具中比较优秀的,并不会损失大量的性能和内存(官方数据,性能下降两倍,而valgrind下降20倍:https://github.com/google/sanitizers/wiki/AddressSanitizerComparisonOfMemoryTools)。

3.ASAN可以定位哪些内存使用问题

1、堆 OOB(堆内存越界)

int main(int argc, char **argv) { int *array = new int[100]; array[0] = 0; int res = array[argc + 100]; // BOOM delete [] array; return res;}

2、栈外界栈越界

int main(int argc, char **argv) { int stack_array[100]; stack_array[1] = 0; return stack_array[argc + 100]; // BOOM}

3、Global OOB(GlobalOutOfBounds 全局变量越界)

记忆问题很难找到,因为您不使用ASAN

int global_array[100] = {-1};int main(int argc, char **argv) { return global_array[argc + 100]; // BOOM}

4、UAF(UseAfterFree 内存释放后使用)

int main(int argc, char **argv) { int *array = new int[100]; delete [] array; return array[argc]; // BOOM}

5、UAR(UseAfterReturn 栈内存回收后使用,该功能还存在少量bug,默认未开启,开启ASAN_OPTIONS=detect_stack_use_after_return=1)

int *ptr;__attribute__((noinline))void FunctionThatEscapesLocalObject() { int local[100]; ptr = &local[0];}int main(int argc, char **argv) { FunctionThatEscapesLocalObject(); return ptr[argc];}

6、UMR(uninitialized memory reads读取未初始化内存)

7、Leaks(内存泄露)

4.怎么使用ASAN工具

现在大部分编译器已经集成了支持asan的能力,编译的时候加上编译选项即可。

常见的编译选项:

  • -fsanitize=address 开起asan能力,gcc 4.8版本开启支持。
  • -fsanitize-recover=address :asan检查到错误后,不core继续运行,需要配合环境变量ASAN_OPTIONS=halt_on_error=0:report_path=xxx使用。gcc 6版本开始支持。

下面开始我们的阿桑之旅

记忆问题很难找到,因为您不使用ASAN

1、写个bug,写一个释放后的内存还在使用的例子。

#include <stdlib.h>int main(){ int *p = malloc(sizeof(int)*10); free(p); *p = 3;//该程序正常情况下并不会导致进程core,因为free后的内存被glibc的内存分配器缓存着 return 0;}

2、加上编译选项编译:gcc -fsanitize=address -g ./test.c -lasan -L /root/buildbox/gcc-10.2.0/lib64/ 其中-L指定的是 libasan.so 存放的位置。

3、指定asan的so的目录,export LD_LIBRARY_PATH=/root/buildbox/gcc-10.2.0/lib64/,执行./a.out执行程序,将可以看到asan报错。指出了内存异常使用的位置和原因。

4、在工程中,我们更希望程序遇到错误能不中断,而继续执行下去,我们可以使用 -fsanitize-recover=address 方法。这次我们更改下代码,多引入几个错误。

#include <stdlib.h>int main(){ int *p = malloc(sizeof(int)*10); free(p); *p = 3; //错误1.释放后继续使用 p = malloc(sizeof(int)*10); p[11] = 3;//错误2,越界写 return 0;}

5、编译:gcc -fsanitize=address -fsanitize-recover=address -g ./test.c -lasan -L /root/buildbox/gcc-10.2.0/lib64/

6、设置环境变量:export ASAN_OPTIONS=halt_on_error=0:log_path=/var/log/err.log,执行程序./a.out

记忆问题很难找到,因为您不使用ASAN

7、查看日志路径:在/var/log目录下,形成一个err.log.212的文件,212是执行./a.out的进程号。文件记录了详细的错误信息。

5. ASAN的原理是什么

ASAN要记录每一块内存的可用性。把用户程序所在的内存区域叫做主内存, 而记录主内存可用性的内存区域,则叫做影子内存 (Shadow memory)。

所有主内存的分配都按照 8 字节的方式对齐。然后按照 1:8 的压缩比例对主内存的可用性进行记录,然后存入影子内存中。影子内存无法被用户直接读写, 需要编译器生成相关的代码来访问。

每一次内存的分配和释放, 都会写入影子内存。每次读/写内存区域前, 都会读取一下影子内存, 获得这块内存访问合法性 (是否被分配, 是否已被释放)。

对影子内存的写入只在分配内存的时候发生, 所以只要分配内存是多线程安全的, ASan 就是多线程安全的, 这在大部分情况下也确实成立。

用户评论

陌上蔷薇

这篇文章太棒了!我一直对内存问题感到头疼,都不知道从哪里下手。使用ASAN真是个好方法,以后一定要尝试一下看看效果怎么样。

    有16位网友表示赞同!

颓废人士

我也是经常遇到这种内存问题!调试起来简直要命,不知道该怎么查找泄露漏洞。ASAN听名字就很厉害的样子,应该好好研究一下。

    有5位网友表示赞同!

何年何念

说的太对了!以前总觉得内存问题很难抓住,感觉像在找一根针一样。使用ASAN就能帮我更快找到问题所在吗?

    有18位网友表示赞同!

我怕疼别碰我伤口

我之前也是这样,总是花费大量时间去定位内存泄漏,弄得心烦意乱。现在越来越看重工具的作用,ASAN 确实是个不错的选择。希望以后能让我少愁些。

    有5位网友表示赞同!

棃海

这篇文章很有帮助,我感觉学习一下ASAN应该可以提升我的开发效率不少。之前总是靠着调试器慢慢查找,太慢了!

    有16位网友表示赞同!

权诈

虽然标题很吸引人,但我不太了解ASAN具体怎么用?有人能详细说说吗?还是说它只能编译特定代码?

    有16位网友表示赞同!

短发

感觉很多时候内存问题不是那么明显的,尤其是在大型项目中。ASAN 能真的像文章说的那样有效地解决这些隐藏的问题吗?

    有19位网友表示赞同!

安陌醉生

文章讲得太专业了,我看不懂好多术语。希望有更多针对小白的学习资源可以更容易理解ASAN的使用方法。

    有6位网友表示赞同!

剑已封鞘

我之前也用过类似于 ASAN 的工具,效果确实不错!但它对代码性能也会有影响吗?文章里面提到没有吗?

    有12位网友表示赞同!

(り。薆情海

这篇文章让我意识到自己开发过程中很多地方需要改进。学习新技术是一个持续的过程,我会去多了解一下ASAN的用法!

    有16位网友表示赞同!

优雅的叶子

还是喜欢直接用调试器来找内存问题,觉得更直观一点。ASAN这个工具看起来太复杂了,我暂时没必要学习.

    有19位网友表示赞同!

花花世界总是那么虚伪﹌

感觉使用ASAN可能会增加开发难度一些,毕竟需要理解更多新的知识和工具。除非内存问题真的很严重,否则还是尽量避免使用吧!

    有8位网友表示赞同!

青衫故人

虽然 ASAN 可以加快定位内存问题的速度,但我更希望开发阶段就能避免这些问题出现。写出更加严谨的代码才是根本解决方案啊!

    有8位网友表示赞同!

七级床震

ASAN 听起来很厉害,可惜我目前开发的项目规模不大,使用这样的工具似乎有些 overkill 了。

    有7位网友表示赞同!

坠入深海i

感觉这篇文章只提到了ASAN的好处,并没有详细介绍它的缺点和局限性。这样写的文章容易让人一味相信,我觉得需要更全面地分析才能做出判断.

    有18位网友表示赞同!

哭着哭着就萌了°

我比较好奇 ASAN 能识别所有类型的内存问题吗?比如 stack overflow 这种问题也能解决吧?

    有9位网友表示赞同!

花容月貌

这篇文章让我对ASAN有了新的认识,以后遇到内存问题一定试试看。希望也能提高我的程序开发水平!

    有14位网友表示赞同!

微信名字

学习新工具总是一件不容易的事情。我需要花些时间去研究ASAN的原理和使用方法才能真正理解它。期待这个新工具能给我带来帮助!

    有6位网友表示赞同!

猜你喜欢
最新游戏更多
热门专题更多
最新资讯更多