gpt4 book ai didi

c++ - 线程循环 system() 和 cout 破坏堆栈

转载 作者:太空狗 更新时间:2023-10-29 21:43:00 26 4
gpt4 key购买 nike

运行以下代码的进程因段错误而崩溃:

#include <stdlib.h>
#include <iostream>
#include <pthread.h>

void* f( void* )
{
while( true )
{
// It crashes inside this call (with cerr, too).
std::cout << 0;
}
return NULL;
}

int main()
{
pthread_t t;
pthread_create( &t, NULL, &f, NULL );

while( true )
{
// It crashes with any script/app; true is just simple.
system( "true" );
}
return 0;
}

它会在几秒钟内崩溃(输出有数千到数百万个“0”)。它使 cout << 0 中的一些函数崩溃。用上面的代码调用。取决于在 f() 中调用的额外函数或放入堆栈的数据,它在不同的地方崩溃。在 gdb 中,有时堆栈对于函数调用的顺序没有意义。据此我推断堆栈已损坏。

我发现有一些 problems with multi-threaded applications calling fork() (另请参阅其中两条提到堆栈损坏的评论)。如果未将文件描述符设置为 FD_CLOEXEC,则 fork /克隆进程会复制文件描述符。 .但是,没有明确创建的文件描述符。 (我尝试在 FD_CLOEXECfileno( stdout ) 上设置 fileno( stderr ),但没有任何积极的变化。)

即使没有明确的文件描述符,我也不能混合使用线程和 fork() ?我是否只需要更换 system()调用具有同等功能?还是内核中存在导致此崩溃的错误并已在 2.6.30 之后修复?

其他详情

我在 ARM AT91 处理器 (armv5tejl) 上运行它,Linux 2.6.30(针对我的特定外围设备集有一些覆盖和补丁)用 GCC 4.3.2 编译。

Linux 2.6.30 #1 Thu May 29 15:43:04 CDT 2014 armv5tejl GNU/Linux

我一直在用 -g [交叉] 编译它和 -O0 ,但没有这些它仍然会崩溃:

arm-atmel-linux-gnueabi-g++ -o system_thread system_thread.cpp -lpthread

我也试过 -fstack-protector-all标志:有时它会在 __stack_chk_fail() 中崩溃,但有时其他函数指针或数据会损坏,并且会更早崩溃。

它加载的库(来自 strace):

libpthread.so.0
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6

注意:因为它有时不会崩溃并且不会真正响应 ^C ,我通常在后台运行它:

$ killall -9 system_thread; rm -f log; system_thread >log &

我已经为几个不同的体系结构和 Linux 内核版本编译了这个程序,但我没有看到它在其他任何地方崩溃:

Linux 3.10.29 #1 Wed Feb 12 17:12:39 CST 2014 armv5tejl GNU/Linux
Linux 3.6.0-dirty #3 Wed May 28 13:53:56 CDT 2014 microblaze GNU/Linux
Linux 3.13.0-27-generic #50-Ubuntu SMP Thu May 15 18:06:16 UTC 2014 x86_64 x86_64 GNU/Linux
Linux 3.8.0-35-generic #50~precise1-Ubuntu SMP Wed Dec 4 17:25:51 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

编辑:请注意,在相同的体系结构 (armv5tejl) 上,它不会与 Linux 3.10.29 一起崩溃。此外,在我的“设备”(较旧的服务器和客户端应用程序)的早期版本上运行时,它不会崩溃,具有相同版本的 Linux - 2.6.30。所以操作系统的环境有一定的影响。

BusyBox v1.20.1 提供shsystem()电话。

最佳答案

这可以在使用您提到的 2.6.30 内核的 ARM 处理器上重现,但不能在 master 中重现。我们可以使用 git bisect 找到修复此错误的位置(大约需要 16 次迭代)。请注意,由于 git bisect 旨在寻找回归,但在这种情况下 master 是“好”的,而过去的版本是“坏的”,我们需要 reverse the meanings of "good" and "bad" .

二分法发现的罪魁祸首是this commit , 以修复涉及 fork() 的“用户空间数据损坏实例”。此症状与您描述的症状非常相似,也可能损坏堆栈外的内存。在向后移植此提交和 the required parent 之后到 2.6.30 内核,您发布的代码不再崩溃。

关于c++ - 线程循环 system() 和 cout 破坏堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23966310/

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