c-断开SIGSEVG信号后的无限循环



我正试图用我的程序找到我的最大堆栈大小。我知道,在我的操作系统上,堆栈的最大大小大约是8MB。所以我试着做无限循环,直到它导致分段错误。然后我需要打破这个循环,这样我就可以计算大小了。我该怎么做?有没有办法打破SIGSEGV信号后的无限循环?

static void handler(int signo)
{
if(signo == SIGSEGV)
{
printf("Waoh, caught signaln");
}
}
int main()
{
int counter = 8964;
stack_t sigstack;
sigstack.ss_sp = malloc(SIGSTKSZ);
if( sigstack.ss_sp == NULL)
{
printf("Err: malloc errorn");
exit(EXIT_FAILURE);
}
sigstack.ss_size = SIGSTKSZ;
sigstack.ss_flags = 0;
if(sigaltstack(&sigstack, NULL) == -1)
{
printf("Err: sigaltstack errorn");
exit(EXIT_FAILURE);
}
struct sigaction act;
act.sa_flags = SA_ONSTACK;
sigemptyset(&act.sa_mask);
act.sa_handler = handler;
sigaction(SIGSEGV, &act, NULL);
do
{
char a[counter];
counter += 8964;
} while (1);
return 0;
}

我修改了您的程序,以计算堆栈大小的估计值,然后使用siglongjmp从信号处理程序返回到main中分配可变长度数组的循环之前的一个可能安全的位置。(请注意,可变长度数组的分配方式取决于编译器,在main溢出堆栈后,可能没有安全的方法恢复执行(。

信号处理程序中的printf仅用于调试;它们可以在不影响程序其余部分的情况下被删除。

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
ptrdiff_t s_size_computed;
void *s_base_estimated;
sigjmp_buf env;
void handler (int signo, siginfo_t *info, void *ucontext)
{
printf("Caught signal %dn", signo);
if (signo == SIGSEGV)
{
printf("faulting address %pn", info->si_addr);
s_size_computed = (char *)s_base_estimated - (char *)info->si_addr;
siglongjmp(env, 1);
}
}
int main()
{
int counter = 8964;
stack_t sigstack;
sigstack.ss_sp = malloc(SIGSTKSZ);
if (sigstack.ss_sp == NULL)
{
printf("Err: malloc errorn");
exit(EXIT_FAILURE);
}
sigstack.ss_size = SIGSTKSZ;
sigstack.ss_flags = 0;
if (sigaltstack(&sigstack, NULL) == -1)
{
printf("Err: sigaltstack errorn");
exit(EXIT_FAILURE);
}
s_base_estimated = &counter;
printf("&locals %pn", s_base_estimated);
struct sigaction act;
act.sa_flags = SA_ONSTACK|SA_SIGINFO;
sigemptyset(&act.sa_mask);
act.sa_sigaction = handler;
sigaction(SIGSEGV, &act, NULL);
if (sigsetjmp(env, 0) == 1)
{
printf("computed stack size %tdn", s_size_computed);
exit(1);
}
do
{
char a[counter];
counter += 8964;
a[0] = 0;         /* access element closest to top of stack (x86) */
} while (1);
return 0;
}

以下是我的Ubuntu系统的输出:

mp:~$ ./stack
&locals 0x7fffeb60e0dc
Caught signal 11
faulting address 0x7fffeae0d960
computed stack size 8390524
mp:~$ ulimit -s
8192

最新更新