运行以下代码的进程崩溃并出现Segmentation fault:
#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
调用深度崩溃了一些函数。根据{{1}}中调用的额外函数或放在堆栈上的数据,它会在不同的地方崩溃。在gdb中,有时堆栈对函数调用的顺序没有意义。从此我推断堆栈已损坏。
我发现有一些problems with multi-threaded applications calling fork()(另见两条提到堆栈损坏的评论)。分析/克隆进程会复制文件描述符(如果它们未设置为f()
)。但是,没有明确创建的文件描述符。 (我尝试在FD_CLOEXEC
和FD_CLOEXEC
上设置fileno( stdout )
而没有任何正面更改。)
即使没有明确的文件描述符,我也不能混合线程和fileno( stderr )
?我是否只需要用等效功能替换fork()
来电?或者内核中是否存在导致此崩溃的错误,并且已在2.6.30之后修复?
我在ARM AT91处理器(armv5tejl)上运行它,使用Linux 2.6.30(我的特定外设集合的一些覆盖和补丁)用GCC 4.3.2编译。
system()
我曾[{1}}和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
中崩溃,但有时其他函数指针或数据会被破坏并且之前会崩溃。
它加载的库(来自strace):
-fstack-protector-all
注意:由于它有时不会崩溃并且对__stack_chk_fail()
没有真正的响应,我通常会在后台运行它:
libpthread.so.0
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
我已经针对一些不同的体系结构和Linux内核版本编译了这个程序,但我还没有看到它在其他任何地方崩溃:
^C
编辑:请注意,在相同的架构(armv5tejl)上,它不会因Linux 3.10.29而崩溃。此外,在早期版本的“设备”(较旧的服务器和客户端应用程序)上运行时,它不会崩溃,具有相同版本的Linux - 2.6.30。因此,操作系统的环境会产生一些影响。
BusyBox v1.20.1提供了$ killall -9 system_thread; rm -f log; system_thread >log &
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
次来电。{/ p>
答案 0 :(得分:2)
这在使用您提到的2.6.30内核的ARM处理器上是可重现的,但不在master中。我们可以使用git bisect
来查找修复此错误的位置(大约需要16次迭代)。请注意,由于git bisect
旨在找到回归,但在这种情况下,主人是好的&#34;但过去的版本很糟糕,&#34;我们需要reverse the meanings of "good" and "bad"。
二分法发现的罪魁祸首是this commit,以修复用户空间数据损坏的实例&#34;涉及fork()。此症状与您描述的症状非常相似,并且还可能损坏堆栈外部的内存。将此提交和the required parent向后移植到2.6.30内核后,您发布的代码不再崩溃。