首页 > 解决方案 > 在 SIGSEGV 处理程序中分配内存

问题描述

我正在学习信号。我创建了一个简单的代码来处理分段错误:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

volatile char *p = NULL;

void segv_handler(int signum) {
    char text[100];
    sprintf(text, "Segv handler! p: %p\n", p);
    if (p == NULL)
        p = malloc(sizeof p);
    write(STDOUT_FILENO, text, strlen(text));
}

int main() {
    signal(SIGSEGV, segv_handler);

    *p = 1;
}

我想,在指针取消引用不成功后,p我的处理程序会分配内存,p并且重新执行*p = 1会正常工作。然而,发生的事情是段错误无限期地发生,即使在为p.

我查看了编译器为 main 函数生成的程序集,它看起来像这样:

main:
.LFB7:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    leaq    segv_handler(%rip), %rax
    movq    %rax, %rsi
    movl    $11, %edi
    call    signal@PLT
    movq    p(%rip), %rax
    movb    $1, (%rax)
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc

如您所见,导致段错误的汇编指令是movb $1, (%rax). 虽然按计划为工作分配内存p,但指令并没有使用 的新地址p,所以段错误再次发生。

这提出了我的问题:我们能否以某种方式更正代码以使其按计划工作?

标签: cassemblyoperating-systemsegmentation-faultsignals

解决方案


推荐阅读