欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Linux下编程之内存检查

Linux下编程之内存检查

2025/2/24 22:21:39 来源:https://blog.csdn.net/DIANZI520SUA/article/details/140095725  浏览:    关键词:Linux下编程之内存检查

前言       

        我们在进行编程时,有时不免会无意中写出一些容易导致内存问题(可能一时表象上正常)的代码,导致的后果肯定是不好的,就像一颗颗“哑弹”,令人心慌。网上推荐的辅助工具很多,此篇文章只简单介绍其中的一种---经典的asan。

编译选项

        一般gcc和交叉编译工具链里面应该都集成了(如果没有,自行添加或换个工具,本文免读),只需在编译代码之前加上支持asan的编译选项即可。

        具体情况见下方代码块,根据自己的需求添加对应的编译选项。

Makefile
# 假设您的源文件是 main.c  # 原来的编译命令可能是这样的  
main.o: main.c  gcc -c main.c  # 修改后的编译命令,添加 -fsanitize=address 选项  
main.o: main.c  gcc -c -fsanitize=address main.c  # 在链接时,您也需要添加相同的选项  
my_program: main.o  gcc -fsanitize=address main.o -o my_programCMake
# CMakeLists.txt  # 添加编译器选项  
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")  # 或者使用 add_compile_options(对于较新的CMake版本)  
add_compile_options(-fsanitize=address)  # 其余的CMake指令...GCC命令行
gcc -fsanitize=address -o my_program my_program.cQt(.pro)
C++工程
QMAKE_CXXFLAGS += -fsanitize=address
C工程
QMAKE_CFLAGS += -fsanitize=address

示例

        下面只以gcc为例,演示asan的用法。

代码

        首先编写一份简单有内存泄漏的C代码(test.c),如下:

#include<stdio.h>int main(int argc, char *argv[])
{char hello[6] = "hello";for(int i = 0; i <= 6; i++){printf("hello[%d] = %c\n", i, hello[i]);}return 0;
}

编译

gcc -fsanitize=address -o test_asan test.c

运行

root@ubuntu:/tmp# ./test_asan 
hello[0] = h
hello[1] = e
hello[2] = l
hello[3] = l
hello[4] = o
hello[5] = 
=================================================================
==11068== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffde1c9dd66 at pc 0x400919 bp 0x7ffde1c9dd10 sp 0x7ffde1c9dd08
READ of size 1 at 0x7ffde1c9dd66 thread T0#0 0x400918 (/tmp/test_asan+0x400918)#1 0x7f62939f6f44 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21f44)#2 0x4007a8 (/tmp/test_asan+0x4007a8)
Address 0x7ffde1c9dd66 is located at offset 38 in frame <main> of T0's stack:This frame has 1 object(s):[32, 38) 'hello'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext(longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:0x10003c38bb50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bb60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bb70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bb80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bb90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10003c38bba0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[06]f4 f4 f40x10003c38bbb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bbc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bbd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bbe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003c38bbf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):Addressable:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:     faHeap righ redzone:     fbFreed Heap region:     fdStack left redzone:    f1Stack mid redzone:     f2Stack right redzone:   f3Stack partial redzone: f4Stack after return:    f5Stack use after scope: f8Global redzone:        f9Global init order:     f6Poisoned by user:      f7ASan internal:         fe
==11068== ABORTING

从上面可以看出程序内存有溢出,溢出的地址也标明。

        如果将上述测试代码循环条件修改正确(i<6),重新编译再执行,结果如下,没有报错误。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词