简体   繁体   English

简单的C ++程序的间歇性分段错误

[英]Intermittent segmentation faults with straightforward C++ program

I'm currently working through Thinking in C++, and chapter 9, exercise 15 gives instructions to time the difference between inline and non-inline constructors. 我目前正在使用C ++进行思考,第9章练习15提供了指示时间以内联和非内联构造函数的时间。 In doing so, I created a metric shedload of object instances in an array, but when I get up to a certain point, the program begins segfaulting intermittently. 通过这样做,我在数组中创建了对象实例的度量负载,但是当达到特定点时,该程序会间歇性地开始段错误。 I'm not doing anything peculiar, and the number doesn't seem to be magical (close to a power of 2 or anything), so it strikes me as very strange. 我没有做任何奇怪的事情,而且这个数字似乎并不神奇(接近2的幂或任何幂),所以让我感到非常奇怪。 Indeed, the objects are all very small, containing a single integer. 实际上,对象都非常小,只包含一个整数。

I'm not using any custom compilation or optimization options, and using standard g++ (not icc or anything). 我没有使用任何自定义的编译或优化选项,而没有使用标准的g++ (而不是icc或任何东西)。

I'm stumped as heck by this, in what should be a straightforward program. 我对此感到迷惑不解,这应该是一个简单的程序。 Any insight would be appreciated, as even the strace output (below) doesn't give me any hints. 任何见识将不胜感激,因为即使strace输出(如下)也没有给我任何提示。

Thank you in advance. 先感谢您。

ex15.cc: ex15.cc:

#include <ctime>
#include <iostream>
using namespace std;

class A
{
    static int max_id;
    int id;
public:
    A() { id = ++max_id; }
};
int A::max_id = 0;

class B
{
    A a;
public:
    B() {}
};

int main()
{
    clock_t c1, c2;
    cout << "Before" << endl;
    c1 = clock();
    B b[2093550];   // intermittent segfault around this range
    c2 = clock();
    cout << "After; time = " << c2 - c1 << " usec." << endl;
    getchar();
}

Run log: 运行日志:

$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Segmentation fault
$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Segmentation fault
$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Segmentation fault

The strace output shows it dying here: strace输出显示它死在这里:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f93000
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

And from a successful run: 从成功的运行:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f4c000
write(1, "Before\n", 7)                 = 7
times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = -1160620642
times({tms_utime=4, tms_stime=0, tms_cutime=0, tms_cstime=0}) = -1160620637
write(1, "After; time = 40000 usec.\n", 26) = 26
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f4b000
read(0, "\n", 1024)                     = 1
munmap(0xb7f4c000, 4096)                = 0
exit_group(0)                           = ?

Allocating an array of 2093550 B objects on the stack most probably causes a stack overflow. 在堆栈上分配2093550 B对象的数组很可能会导致堆栈溢出。 Dynamically allocate it with new to avoid the segmentation fault. 使用new动态分配它,以避免分段错误。

If sizeof(B) is 4 bytes, that puts the size of that array (b) at 8374200 bytes. 如果sizeof(B)为4字节,则该数组(b)的大小为8374200字节。 That's pretty close to what I'm guessing is your default maximum thread stack size of 8 MiB (8388608 bytes). 这与我猜测的是您的默认最大线程堆栈大小8 MiB(8388608字节)非常接近。 So it looks like you're overflowing your stack. 因此,看来您正在溢出堆栈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM