如何用断言做一些有用的事情
How to do something useful with assert?
我想用assert
做一些更有用的事情,而不仅仅是abort
ing,包括刷新一些打开的文件和打印堆栈跟踪。
我读了一些关于断言的文章,比如安德烈·亚历山德雷斯库(Andrei Alexandrescu(的断言,其中谈到了如何实现断言。但是,即使在我的程序使用的第三方库中,我也想用我自己的断言处理程序替换断言处理程序。我知道大多数(但不是全部(编译器(gcc,MSVC,clang(和库(Qt,boost(我使用它们都有设置用户定义的断言处理程序的选项。但是目前我对断言的功能不感兴趣Abort,Retry,Ignore
因此不在编译器/库特定的断言处理程序中查找我的代码。
据我了解,assert
调用abort
发送SIGABRT
信号,我可以捕获此信号并执行有用的任务吗?
用自己的实现劫持assert()
怎么样?在Unix系统上,您可以使用LD_PRELOAD技巧来劫持__assert_fail
(assert()
本身只是一个调用后者的宏(。
另一种可能性是按照您的建议捕获SIGABRT。但是,我看到一些要求:
-
一种区分
assert()
呼叫与接收 SIGABRT 的其他可能原因的方法。这可能是来自另一个线程或进程的调用kill()
,甚至是从堆管理函数的健全性检查中调用abort()
自身(free()
,malloc()
...这可以通过 ABRT 信号处理程序来完成,通过检查进程的执行堆栈或在某些系统中传递给sigaction()
的上下文(没有人知道如何使用的 void* 参数(。 -
如果您决定捕获SIGABRT,您应该记住,信号处理程序在法律上不允许做很多事情(甚至不是呼叫printf(,这使得它们不适合按照您的要求做"更有用的事情"。
所以最好有一个专用线程永久敬畏对于带
sigwait()
的信号(基于abort()
实现这可能不是一个选项(或通过信号通知处理程序 每当收到信号时,它就可以完成大部分工作信号处理程序上下文之外的工作。此外,重要的是要注意,如果在其实现中,SIGABRT 由
abort()
专门发送到其调用线程,那么它的接收将是同步的,您可以自由调用异步不安全函数。
通过自己捕获信号 并修改线程的信号掩码,可能会影响您提到的第三方库的信号行为(他们可能自己捕获SIGABRT(。
即使您使用自己的信号处理程序捕获 SIGABRT,您也无法恢复正常执行信号是从调用发送到
abort()
的,因为(引用自 alarm(8((:
如果 SIGABRT 信号被忽略,或被返回的处理程序捕获, abort(( 函数仍将终止进程。 它确实如此 这是通过恢复SIGABRT的默认处置,然后第二次发出信号来实现的。
- 如何用数字处理log(0)
- 如何用转义符替换字符串中的所有特殊字符
- 如何用参数值调用函数(仅在运行时已知)
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 如何用RISC-V GD32VF103CBT6开发板卸载精确的ADC过采样
- 如何用for循环在c++中生成单词三角形
- 如何用C++编写BFS函数
- 当对话框被接受时,如何用参数调用槽
- 我不明白这段代码是如何对这个pythonlist()进行排序的,也不明白如何用C++中的向量来重现它
- 其中降频广播实际上是有用的
- 如何用前导零填充数组?
- 如何用 2 个对象过度引导运算符
- 如何用C / C++编写钢琴程序
- C++:如何用单个命令替换复杂的迭代?
- 如何用文本填充 std::vector<int64_t>
- 既然我们有内联变量,extern const 还有用吗?
- 如何用 C 编译,但如果使用任何C++,则会抛出错误?
- 如何用 gcc 或 clang 模仿_mm256_loadu_epi32?
- 如何用正确的路径建立提升
- 如何用断言做一些有用的事情