stack_t信号处理函数的备用栈

Posted tongyishu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stack_t信号处理函数的备用栈相关的知识,希望对你有一定的参考价值。

信号处理函数默认会在进程栈创建一个栈帧,但当进程栈的大小到达了限制值的时候,进程会收到SIGSEGV信号,于是进程便不能创建栈帧了,所以程序就直接执行其默认行为(终止进程) 。

为了解决这个情况,提出了一个备用栈的概念 使得栈帧在这里创建。

操作如下:
    首先要分配一块内存,可以是静态申请的也可以是动态申请的,这个主要使用结构体 struct stack_t。

    然后使用系统调用 int sigaltstack(const stack_t *sigstack , stack_t * old_sigstack ); //头文件 signal.h

    之后创建信号处理器函数的时候将标志设置成 SA_ONSTACK ,通知内核在备选栈中创建栈帧。

以下给出 struct stack_t 的结构体:

typedef struct {
    void *ss_sp; // 备选栈的地址
    int ss_flags; // 各种设置掩码
    size_t ss_size; // 备选栈的大小,一般设置为宏SIGSTKSZ
} stack_t ;

代码示例:

#define _GNU_SOURCE
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

static void Recursive()
{
    char buffer[1000000];
    printf("buffer position : %p
", buffer);
    Recursive();
}

static void SignalHandler(int signal)
{
    printf("signal : %s
", strsignal(signal));
    fflush(0);
    _exit(-1);
}

int main()
{
    // stack_t signalStack;
    // signalStack.ss_flags = 0;
    // signalStack.ss_size = SIGSTKSZ;
    // signalStack.ss_sp = malloc(SIGSTKSZ);

    // sigaltstack(&signalStack, 0);

    // struct sigaction signalAction;
    // signalAction.sa_handler = SignalHandler;
    // sigemptyset(&signalAction.sa_mask);
    // signalAction.sa_flags = SA_ONSTACK;

    // sigaction(SIGSEGV, &signalAction, 0);
    Recursive();
    return 0;
}

去掉注释的执行结果:

技术图片

 

 加上注释的执行结果:

技术图片

以上是关于stack_t信号处理函数的备用栈的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat主要配置项-请求处理相关

2018/10/03-函数调用约定cdeclstdcallfastcall- 《恶意代码分析实战》

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段

PHP多进程处理并行处理任务实例(转,备用)

函数栈帧 详解