【问题标题】:How to write signal handler for sigabrt signal?如何为 sigabrt 信号编写信号处理程序?
【发布时间】:2012-02-01 13:41:41
【问题描述】:

我正在尝试删除一个已删除的对象,并且收到一个 SIGABRT 信号。 我知道这个信号会中止我的程序,但我想在信号处理程序中捕获这个信号并显示我正在删除一个已经删除的对象的消息......

这是我尝试过的代码,但它似乎不起作用。 请帮我弄清楚其中有什么问题?

using namespace std;

class myclass
{
public:
   myclass()  { cout <<"myclass constructed\n"; }
   ~myclass() { cout <<"myclass destroyed\n"; }
};

void func(int);

int main (void)
{
  signal(SIGABRT,func);
  myclass * pt;

  pt = new myclass[3];

  delete[] pt;
  delete[] pt;

  return 0;
}

void func(int)
{ 
   signal(SIGABRT,func);
   cout << "trying to delete unallocated memory, exiting....\n";
   exit(0);
}

【问题讨论】:

  • “似乎不起作用”是什么意思? (顺便说一句,在这里工作正常。请尝试格式化您的代码。)
  • 它只是中止而不给我消息“试图删除未分配的内存,退出......”
  • 如果你是这样定义“工作”的,我看到消息打印得很好 (g++4.6.1/ubuntu 11 x86)。
  • 如果我不想中止程序并在正常模式下继续,可以做些什么修改...?
  • 双重释放是代码中的一个错误。试图找到一种方法来解决这个问题是错误的。防止它是(唯一的)解决方案。

标签: c++ signals


【解决方案1】:

C 标准说(C99C11 的第 7.14 节第 4 段):

实现不需要生成任何这些信号,除非是显式的结果 调用 raise 函数。

C++ 标准不提供任何额外的额外保证。

POSIX 说:

abort() 函数会导致进程异常终止,除非信号 SIGABRT 被捕获并且信号处理程序没有返回。

异常终止处理应包括为 SIGABRT 定义的默认操作,并且可能包括尝试对所有打开的流执行 fclose()。

SIGABRT 信号应该被发送到调用进程,就像通过带有参数 SIGABRT 的 raise() 一样。

abort() 为 wait() 或 waitpid() 提供的状态应是由 SIGABRT 终止的进程的状态信号。 abort() 函数应覆盖阻塞或忽略 SIGABRT 信号。

所以,是的,您完全没有理由期望看到 SIGABRT;你很幸运没有遇到nasal demons

【讨论】:

    猜你喜欢
    • 2012-02-14
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    相关资源
    最近更新 更多