简体   繁体   English

为什么使用信号处理程序在此代码中出现分段错误?

[英]Why do I get a segmentation fault in this code with a signal handler?

I write a signal handler in my program, but in this file structure I get a segmentation fault.我在我的程序中编写了一个信号处理程序,但是在这个文件结构中我遇到了分段错误。 But if everything is all in one file, then everything works correctly.但是,如果一切都在一个文件中,那么一切正常。 As I understand it, it can't access the return address.据我了解,它无法访问返回地址。 How can I fix it?我该如何解决?

"test.h" “测试.h”

#ifndef TEST_H
#define TEST_H
#include <string.h>
#include <setjmp.h>
#include <signal.h>
static jmp_buf g_env;
void sig_handler(int sig);
endif TEST_H

"test.c" “测试.c”

#include "test.h"
void sig_handler(int sig) {
  psignal(sig, "Signal");
  siglongjmp(g_env, 1);
}

"main.c" “主要.c”

#include "test.h"
int main(void) {
  struct sigaction act;
  memset(&act, 0, sizeof(act));
  act.sa_handler = sig_handler;
  sigemptyset(&act.sa_mask);
  sigaddset(&act.sa_mask, SIGSEGV);
  sigaction(SIGSEGV, &act, 0);

  if (!sigsetjmp(g_env, 1)) {
    raise(SIGSEGV);
  }
  return (1);
}

"Result:" “结果:”

Signal: Segmentation fault
Segmentation fault (core dumped)

"Valgrind:" “瓦尔格林德:”

==44698== Command: ./a.out
==44698==
Signal: Segmentation fault
==44698== Warning: client switching stacks?  SP change: 0x1ffeffee08 --> 0xf7c1f413060a2966
==44698==          to suppress, use: --max-stackframe=593925450715481250 or greater
==44698== Jump to the invalid address stated on the next line
==44698==    at 0xF7C1F413060A2966: ???
==44698==  Address 0xf7c1f413060a2966 is not stack'd, malloc'd or (recently) free'd
==44698==
==44698==
==44698== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==44698==  Bad permissions for mapped region at address 0xF7C1F413060A2966
==44698==    at 0xF7C1F413060A2966: ???
==44698== Invalid write of size 8
==44698==    at 0x482F120: _vgnU_freeres (vg_preloaded.c:59)
==44698==  Address 0xf7c1f413060a295e is not stack'd, malloc'd or (recently) free'd
==44698==
==44698==
==44698== Process terminating with default action of signal 11 (SIGSEGV)
==44698==  General Protection Fault
==44698==    at 0x482F120: _vgnU_freeres (vg_preloaded.c:59)

It's because you have different instances of g_env - each translation unit gets a different g_env .这是因为您有不同的g_env实例 - 每个翻译单元都有不同的g_env As a result, the g_env buffer used in sigsetjmp isn't same as that's used by siglongjmp .因此, sigsetjmp 中使用的g_env缓冲区与sigsetjmp中使用的siglongjmp

Just drop the static from:只需从以下位置删除static

static jmp_buf g_env;

Now, there'll be just one global instance of g_env .现在,将只有一个g_env的全局实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM