【积土成山】AddressSanitizer: heap

编程入门 行业动态 更新时间:2024-10-08 18:33:51

【积土成山】<a href=https://www.elefans.com/category/jswz/34/1760643.html style=AddressSanitizer: heap"/>

【积土成山】AddressSanitizer: heap

背景,不同场景,内在原理,参考文献

一、背景

1.1 问题背景

1 在做leetcode时,总是会遇到关于“heap-buffer-overflow”的问题;
2 下面对这些场景进行归纳,提出潜在检查点,以及尝试揭示出其内在原理;

1.2 AddressSanitizer

1 快速内存错误检测工具;
2 这里还提供一种方法,进行本地安装和调试;
3 那么在之后如果leetcode不过,然后给出的堆溢出信息又不全的情况下,可以使用这种方法进行调试;

二、场景分析

2.1 自己做leetcode时,遇到的问题

1 报错现象

==46==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000030 at pc 0x000000405074 bp 0x7ffe12fc3280 sp 0x7ffe12fc3270
R
READ of size 8 at 0x603000000030 thread T0#2 0x7f68203db82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0
0x603000000030 is located 0 bytes to the right of 32-byte region [0x603000000010,0x603000000030)
a
allocated by thread T0 here:#0 0x7f68213f6f88 in  (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bf88)#3 0x7f68203db82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
S
Shadow bytes around the buggy address:
char ** stringMatching(char ** words, int wordsSize, int* returnSize){returnSize = (int *)malloc(sizeof(int));int i, j, k;for (i = 0; i < wordsSize; i++) {printf("%d, %s, %p", wordsSize, words[i], &(words[i]));}*returnSize = wordsSize;return words;

2 READ,指出线程名是T0,操作数是READ,大小是8个byte;
‘read of size 1 at address…’
It means you read single byte form the given address
3 原因是传入的是一个二重指针,确实是可以通过访问words[i],找到其指向的内容;
但是在返回时,由于words二重指针的内容是分配在栈中,返回之后,就会删除,因此该指针返回之后,没有任何价值;
4 应该的做法是:将该指针所指向的字符串内容,重新malloc一块内存进行存储;
(64位操作系统 int和指针的长度都是八个字节)

2.2 之前同学遇到一个类似问题

1 在leetcode上做题,测试用例是过的,但是在跑全部测试用例时,出现问题,然后通过查看代码,是因为对非法入参没有判空导致;
2 然后通过修改之后,可以顺利通过;

2.3 csdn博客1

1 AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318
2 LeetCode使用了AddressSanitizer检查了是否存在内存非法访问;数组访问越界,也是绝大部分的内存访问题
3 原因:把for循环内的i <= nums.size() 修改成 i < nums.size()即可
4 此外,有其他几位同学也是类似的情况,即数组越界导致;

综上,有两种途径解决类似问题
1 着重排查通过申请内存,来给指针赋值的方式,获取的数组,查看这些数组的被访问地方是否存在越界;
2 在本地安装addressSanitizer,进行本地调试,获取全部调试信息;

三、内在原理

3.1 函数入参的传递

1 传入的值,在函数所属的栈上,新分配一块空间,用于传递;
2 比如int型,那么传入的这个值,位于栈中,类似局部变量,函数退出时会释放,不会传递给外层;
3 比如int*, 传入的是整型数值所存储的地址,这样可以通过在内部修改传入指针所执行地址的值,来实现出参的传递;
4 同理,如果需要修改结构体的值,那么也需要传入能够访问到这个结构体位置的地址的值,而由于能够访问到这个结构体的位置,是一个指针,所以传入的是一个二重指针,其实本质,与int *是一致的;

3.2 malloc分配及memset的使用

int value = (int)malloc(n * sizeof(int));
(void)memset(value, 0, sizeof(n * sizeof(int));

3.3 通过strncpy拷贝字符串后,是否需要加上’\0’

strncpy举例
需要在后面,加上’\0’,不然会出现乱码,但是用strncpy_s就不会出现;

四、参考文献

1 介绍AddressSanitize
2 使用AddressSanitize在linux下进行安装和使用
3 csdn案例一
4 stackoverflow介绍告警字段含义
5 CSDN另一个总结

更多推荐

【积土成山】AddressSanitizer: heap

本文发布于:2024-03-06 15:54:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1715732.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:积土成山   AddressSanitizer   heap

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!