最近我正在开发一个用c编写的软件,它有大约3-4万行代码。当我开始出现分段错误时,我添加了一个SIGSEGV处理程序。这帮我把pin指向错误作为处理程序被用来做回溯。
我的问题是除了SIGSEGV之外,当我们拥有一个大软件时应该处理的重要信号是什么,以便错误检测很容易。
这可以选择用于防止攻击。 Ex软件在进行关键更新/操作时接收中止信号。标准告诉SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGTERM和一些其他信号具有默认属性来终止传递此信号的进程。
因此,要为我的软件添加另一层保护,我将不得不改变这些信号的行为。通过保护,我的意思是我不希望我的软件在介于更新之间时终止,我将决定什么时候中止
编辑:我想知道设计良好的软件,处理SIGNAL,如同安全网一样使用它们,这有助于软件的构建。
答案 0 :(得分:8)
嗯,你不是100%清楚你对答案的期望,但我会试着掩盖一般的想法。
首先,你可以称之为'调试'的信号是什么(以及何时期待它们):
SIGILL
,SIGFPE
- 如果程序试图运行非法指令,通常会出现错误的CFLAGS
和/或自己的程序集(或严重的随机破坏); SIGABRT
- 由abort()
电话引起,例如assert()
。它也可以来自库,所以你通常应该处理它; SIGSEGV
- 内存访问无效,您可能已经知道了所有内容; SIGBUS
- 在使用mmap()
进行I / O并尝试读取/写入无法访问的内存时可能会发生;当基于mmap()
的I / O跑出空间时,它也发生在我身上; SIGPIPE
- 在管道上进行I / O时,管道与另一侧断开连接; SIGSYS
,您可能也希望捕获它(尽管我从未设法看到它)。如果您使用相关操作,我会说您需要处理这些信号。它们都在POSIX中,但我不确定是否所有系统都实现了它们,所以你可能想要为它们使用#ifdef
(SIG*
保证是宏,因此适用于{{1 }})。
您在程序运行时可能遇到的其他信号是:
#ifdef
- 使用SIGALRM
时,alarm()
- 使用投票时,SIGPOLL
- 产生进程时...... 这些基本上是你在使用相关操作时正在处理的信号,虽然它们默认终止,但你还是应该有其他的处理程序。
最后,如果您希望处理用户发送的信号,这是一个严酷的情况 - 因为用户几乎可以发送每个信号。因此,如果您想要优雅地处理它,您需要捕获来自SIGCHLD
的每个信号,默认为终止或中止操作。
如果你想捕捉一个你可以预期的共同信号子集,那么它们将是:
man signal
当带有程序的终端(或其他一些父级,如果相关)死亡时,SIGHUP
表示^ c键,SIGINT
表示^ \ key,SIGQUIT
表示终止请求(默认情况下由SIGTERM
程序和其他类似工具发送),kill
和SIGUSR1
是用户定义的信号,通常用于执行特定于程序的操作。它们由用户发送,并且 - 由于某种原因 - 默认为终止程序。还有SIGUSR2
,但标准不允许捕获它。
我希望我能够涵盖最重要的信号。请注意,我是Linux用户,其他* nixes可能有一些您可能想要捕获的特定信号。
通常一切都取决于你想要达到的目标。虽然防止软件被随机信号中断是一个好主意,但通常不值得防止它被所有这些软件杀死,特别是那些只是由用户直接发送的软件。
如果用户想要杀死该应用,他无论如何都可以实现它,并且应足以处理常见的应用 - SIGKILL
和SIGINT
。我个人希望SIGTERM
(^ \ key)杀死应用程序而不让它完成甚至是关键任务(如SIGQUIT
那样)。
修改的。作为最后一句话的理由,请考虑以下几点:我刚刚做了一些愚蠢的事情,比如删除了一些重要的数据。或者只是注意到清理退出程序有问题。我确实想要终止程序,确保我的信号不会被捕获,但会导致它立即返回 。即使它会导致数据损坏,有时候我真的更愿意破坏数据(希望我能够恢复我需要的)而不是没有数据。