c - 在 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
,所以段错误再次发生。
这提出了我的问题:我们能否以某种方式更正代码以使其按计划工作?
解决方案
推荐阅读
- python - 什么时候在 OOP 期间使用多处理/多线程不安全?
- elasticsearch - 如何在“Elasticsearch”上创建元数据?
- javascript - Javascript 检测是否支持原生表情符号
- android-studio - 如何使用 android studio 生成的注释将 dart 文件保存在文件系统中?
- quire-api - 需要一次性令牌功能
- haskell - 通过给定的跟踪 Hakell 查找子树
- javascript - 几行 javasript 来格式化货币
- javascript - 为什么 String.prototype.match() 返回 null 而不是空数组?
- javascript - 如何将图像的原始大小设置为不超过父容器的宽度
- uwp - UWP WebView 中的 Xterm.js - 以编程方式粘贴