堆栈是临时内存地址空间,用于保留子程序或函数调用期间的参数和自动变量。如果线程堆栈的大小太小,则可能会出现堆栈溢出,从而导致无提示的数据损坏或段故障。
正在执行的程序为执行该程序的初始线程(或主线程)维护一个主堆栈。使用 limit C shell 命令或者 ulimit Bourne 或 Korn shell 命令可显示或设置初始线程(或主线程)的堆栈大小。
另外,程序中的每个 OpenMP 辅助线程有自己的线程堆栈。此堆栈模拟初始(或主)线程堆栈,但对于线程是唯一的。线程的 private 变量在线程堆栈上进行分配。对于 32 位应用程序,辅助线程堆栈的缺省大小为 4 MB;对于 64 位应用程序,缺省值为 8 MB。使用 OMP_STACKSIZE 环境变量设置辅助线程堆栈的大小。
请注意,使用 -stackvar 选项编译 Fortran 程序将强制在堆栈中分配局部变量和数组,就好像它们是自动变量。对于使用 -xopenmp、-xopenmp=parallel 或 -xopenmp=noopt 选项编译的程序,-stackvar 为隐式选项。如果为堆栈分配的内存不足,会导致堆栈溢出。请务必确保堆栈足够大。
C shell 示例:
% limit stacksize 32768 <- Sets the main thread stack size to 32 Megabytes % setenv OMP_STACKSIZE 16384 <- Sets the helper thread stack size to 16 Megabytes
Bourne shell 或 Korn shell 示例:
$ ulimit -s 32768 <- Sets the main thread stack size to 32 Megabytes $ OMP_STACKSIZE=16384 <- Sets the helper thread stack size to 16 Megabytes $ export OMP_STACKSIZE
要检测堆栈溢出,请使用 -xcheck=stkovf 编译器选项编译 C、C++ 或 Fortran 程序。语法如下所示:
-xcheck=stkovf[:detect | :diagnose]
如果指定了 -xheck=stkovf:detect,则通过执行通常与错误关联的信号处理程序来处理检测到的堆栈溢出错误。
如果指定了 -xcheck=stkovf:diagnose,则通过捕获关联的信号来处理检测到的堆栈溢出错误并通过调用 stack_violation(3C) 来诊断错误。如果诊断到堆栈溢出错误,则会向 stderr 输出错误消息。如果只指定了 -xcheck=stkovf,这是缺省行为。
有关 -xcheck=stkovf 编译器选项的更多信息,请参见 cc(1)、CC(1) 或 f95(1) 手册页。