fsantinize 弱智

2023-09-16 10:35:49 +08:00
 zzzkkk

fsantinize 还没智能到那种程度 简直给码农添加负担 给一个静态字符数组前面添加几个空格都会报错

请看

图 1

图 2

图 3

编译时报图 3 的错误 运行就报 ==1856626==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff15ef59e9 at pc 0x55d429175340 bp 0x7fff15ef5940 sp 0x7fff15ef5938

5388 次点击
所在节点    C++
85 条回复
Kumo31
2023-09-16 13:39:45 +08:00
建议还是放弃使用 c/cpp 吧
leaflxh
2023-09-16 13:57:03 +08:00
能留个微信吗,用 sha256 加密一下发出来
liuguangxuan
2023-09-16 14:08:07 +08:00
@leaflxh 哈哈,这个梗我居然看懂了
zzzkkk
2023-09-16 14:48:33 +08:00
@leaflxh
你以为我连这都不知道吗 无法还原
cnbatch
2023-09-16 16:23:56 +08:00
人眼数很容易数错的,对于比较长的字符串,最好还是写成
char s[] = "这是字符串"
中括号内不写任何数字

如果想知道 s 数组有多长,那就 sizeof(s)

以 14 楼的图为例,把 s[31]的数字去掉,改成 s[],接着下面一行加一句
printf("sizeof s: %d\n", (int)sizeof(s));
就可以准确知道实际大小
zzzkkk
2023-09-16 16:41:52 +08:00
@cnbatch
是把字符串连双引号拷贝进浏览器 console 用.length 算出来的 是 30 再加 1 等于 31

刚才把下标 31 去掉了 用 sizeof 打印出来是 31

但编译加上 fsanitize 还是报错

这贴讨论的是 fsanitize 的弱智 但它还想做全面的事情 限制了码农的能力 增加了繁琐

你们着眼的细节是我在增加了很多空格后 无非是忘了改下标

你们自己去加上 fsanitize 编译看看
cy18
2023-09-16 17:22:11 +08:00
@zzzkkk #26 "无非”是忘了改下标...
fsantinize 帮你找出了这么严重的问题,这时候你就应该默默在心中唱一首《感恩的心》。
zzzkkk
2023-09-16 17:27:13 +08:00
@cy18
关键是没有下标 或刚好等于 或远远大于数组元素个数 fsanitize 都报错 这不是假阳性么?所以说它弱智 但还想干全能的事
geelaw
2023-09-16 17:32:24 +08:00
请问楼主期待这段代码发生什么?

int a[1];
a[0] = 1;
a[1] = 2;

用超长字符串初始化不够长的字符数组的效果和上面差不多。另外楼主并不是忘了改下标,而是忘了改长度,这是两个不同的概念。

另外 char s[] = "..."; char s2[strlen(s) + 1]; 不是合法的 C++ 代码,没有拒绝编译已经很给面子了。
zzzkkk
2023-09-16 17:36:20 +08:00
@geelaw
是 gcc 编译器

你那段代码 不就是越界么 段错误

这贴的主题是 fsanitize 检查出假阳性 因为正确的数组长度比如 31 它也报错

我当然知道越界
zzzkkk
2023-09-16 17:40:52 +08:00
这个是合法的 char s2[strlen(s)+1]

不合法的话 你用数组长度+1 的 size 用 malloc 返回指针都不合法
zzzkkk
2023-09-16 17:46:08 +08:00
我不知道越界的话

这种高质量 while 循环都写不出来
zzzkkk
2023-09-16 17:52:19 +08:00
一开始数组下标是正确的 我当时好像去掉了下标 后来又加上正确下标 我发现 fsanitize 报假阳性

为了截图 才改了代码 改了字符串

你们没有关注假阳性 反而关注细枝末节
geelaw
2023-09-16 17:52:54 +08:00
@zzzkkk #30 所以你对 char s[25] = "长度为 30 的字符串长度为 30 的字符串"; 出错有什么异议呢?

另外 s 以空格开头的时候,在

while (start > s) {
flag = 0;
while (*start == ' ') start--;

这段代码里面会把 start 减到 s 之前,这也是未定义行为。

https://gist.github.com/GeeLaw/47dea7677eb48e1b9896bfe9d006b5f4
qbqbqbqb
2023-09-16 17:53:01 +08:00
你的 while 里面的

while(*start==' ') start--;

在字符串以空格开头的时候可能会越界,访问到 s[-1]
cnbatch
2023-09-16 17:53:43 +08:00
简单写了一小段

#include <stdio.h>

int main()
{
char str[30] = "https://www.v2ex.com/t/974343";
printf("sizeof str: %d\n", (int)sizeof(str));
printf("%s\n", str);
}


无论 GCC 还是 Clang ,编译和运行都没报错

编译的命令行:cc -fsanitize=address
GCC 版本(运行在 Debian 11 ):10.2.1
Clang 版本(运行在 FreeBSD 13.2 ):14.0.5
geelaw
2023-09-16 17:53:55 +08:00
@zzzkkk #31 C++ 不存在变长数组,所以 int n; scanf("%d", &n); int a[n]; 是完全错误的,即使 n 输入的是 1 也是错误的。
zzzkkk
2023-09-16 17:55:32 +08:00
减到 s 之前也没问题

下面 start2++ 刚好指向空格

下面的代码不会执行
zzzkkk
2023-09-16 17:57:46 +08:00
@qbqbqbqb
后面先+1 了 刚好指向空格
zzzkkk
2023-09-16 17:58:29 +08:00
@geelaw
这里没有 c 板块 只有 c++

我本来想发 c 板块

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/974343

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX