gpt4 book ai didi

c - 使用 fstack-check 时出现意外的 valgrind "invalid write"

转载 作者:太空狗 更新时间:2023-10-29 15:06:48 29 4
gpt4 key购买 nike

我有以下非常简单的 C 程序 (test.c):

int f(int i)
{
return i;
}

int main(int argC, char* argV[])
{
int x = f(12);
return 1;
}

我用 valgrind 做了一些测试,在两个不同的系统中使用 -fstack-check 编译器标志。

使用 gcc 4.9.2 和 valgrind 3.10.0 在 Debian 8.6 上完成测试。

没有-fstack-check:

$ gcc test.c -o test
$ valgrind ./test
==103703== Memcheck, a memory error detector
==103703== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==103703== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==103703== Command: ./test
==103703==
==103703==
==103703== HEAP SUMMARY:
==103703== in use at exit: 0 bytes in 0 blocks
==103703== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==103703==
==103703== All heap blocks were freed -- no leaks are possible
==103703==
==103703== For counts of detected and suppressed errors, rerun with: -v
==103703== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

使用-fstack-check:

$ gcc -fstack-check test.c -o test
$ valgrind ./test
==103726== Memcheck, a memory error detector
==103726== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==103726== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==103726== Command: ./test
==103726==
==103726==
==103726== HEAP SUMMARY:
==103726== in use at exit: 0 bytes in 0 blocks
==103726== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==103726==
==103726== All heap blocks were freed -- no leaks are possible
==103726==
==103726== For counts of detected and suppressed errors, rerun with: -v
==103726== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

CentOS 6.6 中使用 gcc 4.4.7 和 valgrind 3.8.1 进行的测试:

没有-fstack-check:

$ gcc test.c -o test
$ valgrind ./test
==16390== Memcheck, a memory error detector
==16390== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==16390== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==16390== Command: ./test
==16390==
==16390==
==16390== HEAP SUMMARY:
==16390== in use at exit: 0 bytes in 0 blocks
==16390== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==16390==
==16390== All heap blocks were freed -- no leaks are possible
==16390==
==16390== For counts of detected and suppressed errors, rerun with: -v
==16390== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

使用-fstack-check:

$ gcc -fstack-check test.c -o test
$ valgrind ./test
==16441== Memcheck, a memory error detector
==16441== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==16441== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==16441== Command: ./test
==16441==
==16441== Invalid write of size 8
==16441== at 0x400497: main (in /home/fermin/valgrindtest/test)
==16441== Address 0x7feffd058 is not stack'd, malloc'd or (recently) free'd
==16441==
==16441==
==16441== Process terminating with default action of signal 11 (SIGSEGV)
==16441== Access not within mapped region at address 0x7FEFFD058
==16441== at 0x400497: main (in /home/fermin/valgrindtest/test)
==16441== If you believe this happened as a result of a stack
==16441== overflow in your program's main thread (unlikely but
==16441== possible), you can try to increase the size of the
==16441== main thread stack using the --main-stacksize= flag.
==16441== The main thread stack size used in this run was 10485760.
==16441==
==16441== HEAP SUMMARY:
==16441== in use at exit: 0 bytes in 0 blocks
==16441== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==16441==
==16441== All heap blocks were freed -- no leaks are possible
==16441==
==16441== For counts of detected and suppressed errors, rerun with: -v
==16441== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)

在这种情况下,此外,程序以段错误结束。

总结,虽然在 Debian 中使用 -fstack-check 似乎一切正常,但在 CentOS 中我收到“无效写入”错误无法根据我的程序代码进行解释。

正在阅读 the -fstack-check flag也许错误跟踪是由于堆栈检查机制在堆空间中为 x 变量分配了 8 个字节,但 valgrind(由于某种原因)无法意识到这一点,因此将其标记为作为无效写入。也许这是 valgrind 3.8.1 中的限制,已在 3.10.0 中解决(考虑到在 Debian 设置中,使用 3.10.0,我没有得到该跟踪)?

此外,我还查看了valgring FAQ -fomit-frame-pointer-fstack-check 会使堆栈跟踪变得更糟” 但它们没有提供太多关于这样做的原因所以我不知道问题是否相关...

非常感谢任何有助于解释这一点的帮助或提示。

编辑:正如一条评论中所建议的,我包括了 CentOS 6.x 案例的反汇编代码,使用 -g3 编译并使用 objdump --源测试。我在这里包含了与 main() 和 f() 函数对应的部分,但是可以找到完整的转储 here .

使用 -fstack-check 编译的二进制文件:

0000000000400474 <f>:
int f(int i)
{
400474: 55 push %rbp
400475: 48 89 e5 mov %rsp,%rbp
400478: 89 7d fc mov %edi,-0x4(%rbp)
return i;
40047b: 8b 45 fc mov -0x4(%rbp),%eax
}
40047e: c9 leaveq
40047f: c3 retq

0000000000400480 <main>:

int main(int argC, char* argV[])
{
400480: 55 push %rbp
400481: 48 89 e5 mov %rsp,%rbp
400484: 48 83 ec 20 sub $0x20,%rsp
400488: 89 7d ec mov %edi,-0x14(%rbp)
40048b: 48 89 75 e0 mov %rsi,-0x20(%rbp)
int x = f(12);
return 0;
40048f: 48 8d 84 24 08 d0 ff lea -0x2ff8(%rsp),%rax
400496: ff
400497: 48 c7 00 00 00 00 00 movq $0x0,(%rax)
return i;
}

int main(int argC, char* argV[])
{
int x = f(12);
40049e: bf 0c 00 00 00 mov $0xc,%edi
4004a3: e8 cc ff ff ff callq 400474 <f>
4004a8: 89 45 fc mov %eax,-0x4(%rbp)
return 0;
4004ab: b8 00 00 00 00 mov $0x0,%eax
}
4004b0: c9 leaveq
4004b1: c3 retq

没有 -fstack-check 编译的二进制文件:

0000000000400474 <f>:
int f(int i)
{
400474: 55 push %rbp
400475: 48 89 e5 mov %rsp,%rbp
400478: 89 7d fc mov %edi,-0x4(%rbp)
return i;
40047b: 8b 45 fc mov -0x4(%rbp),%eax
}
40047e: c9 leaveq
40047f: c3 retq

0000000000400480 <main>:

int main(int argC, char* argV[])
{
400480: 55 push %rbp
400481: 48 89 e5 mov %rsp,%rbp
400484: 48 83 ec 20 sub $0x20,%rsp
400488: 89 7d ec mov %edi,-0x14(%rbp)
40048b: 48 89 75 e0 mov %rsi,-0x20(%rbp)
int x = f(12);
40048f: bf 0c 00 00 00 mov $0xc,%edi
400494: e8 db ff ff ff callq 400474 <f>
400499: 89 45 fc mov %eax,-0x4(%rbp)
return 0;
40049c: b8 00 00 00 00 mov $0x0,%eax
}
4004a1: c9 leaveq
4004a2: c3 retq

EDIT2:我目前在 CentOS 6.8 中使用最新的 valgrind 版本 (3.13.0) 进行了测试,我遇到了同样的问题。

最佳答案

我已经在我的 CentOS 6.6 系统中安装了 gcc 4.7.2(使用 this procedure )并使用 -fstack-check 重新编译测试:

$ /opt/centos/devtoolset-1.1/root/usr/bin/gcc --version
gcc (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ /opt/centos/devtoolset-1.1/root/usr/bin/gcc -fstack-check test.c -o test
$ valgrind ./test
==19374== Memcheck, a memory error detector
==19374== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==19374== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==19374== Command: ./test
==19374==
==19374==
==19374== HEAP SUMMARY:
==19374== in use at exit: 0 bytes in 0 blocks
==19374== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==19374==
==19374== All heap blocks were freed -- no leaks are possible
==19374==
==19374== For counts of detected and suppressed errors, rerun with: -v
==19374== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

请注意,现在“无效写入”错误未显示。因此,这似乎是 gcc 编译器中的一个问题,某种在 4.4.7 和 4.7.2 之间修复的错误,如@n.m。在评论中建议。

关于c - 使用 fstack-check 时出现意外的 valgrind "invalid write",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44758939/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com