如何观察不正确的堆叠展开

How to observe improper stack unwinding?

本文关键字:不正确 何观察 观察      更新时间:2023-10-16

我们有一些c++代码,可以通过用户API调用exit(3)。我的假设是,我们没有正确地展开堆栈,这在c++中被认为是糟糕的。此外,还涉及一个很大的c++库,必须将其视为黑盒。

我想修补这个问题,也知道如何修补,但不知道如何观察和比较变化。我能以某种方式让它可见吗?可能在OS X上?

exit()显然进行了一些清理。这在标准的第18.5节[support.start.term]中有描述,但经常正确的网站www.cplusplus.com对此进行了总结。

所以它说,具有静态存储或线程存储的对象将被清理,整个I/O系统也将被清理(文件将被刷新等)。

但是还有其他方法可以在不运行C++清理的情况下退出。例如,如果它是调用exit,并且它是C语言库(而不是C++),那么它可能会也可能不会执行C++清理。或者有对abortquick_exit的调用。而且,如果您直接调用操作系统(例如,Windows上的ExitProcess()),则进程会立即退出,并且不会执行C++清理。

如果你想让行为可见:制作一个带有析构函数的对象,它可以做一些有趣的事情,比如在某个地方记录消息。或者,当它被构造时,它会创建一个具有特定名称的文件,当被破坏时,它就会删除它。在main()中声明一个实例——这个对象。在静态作用域中声明另一个(带有不同消息)。所以现在你在你的环境中有一个可以观察到的效果。

以下是N4140的18.5(2014-10-07):

[[noreturn]] void exit(int status) 
8 The function exit() has additional behavior in this International Standard:
(8.1) First, objects with thread storage duration and associated with the current
      thread are destroyed. Next,objects with static storage duration are destroyed
      and functions registered by calling `atexit` are called. See 3.6.3 for the
      order of destructions and calls. (Automatic objects are not destroyed as a
      result of calling `exit()`.) If control leaves a registered function called by
      `exit` because the function does not provide a handler for a thrown exception,
      `std::terminate()` shall be called (15.5.1).
(8.2) Next, all open C streams (as mediated by the function signatures declared in
      `<cstdio>`) with unwritten buffered data are flushed, all open C streams are
      closed, and all files created by calling `tmpfile()` are removed.
(8.3) Finally, control is returned to the host environment. If `status` is zero or
      `EXIT_SUCCESS`, an implementation-defined form of the status _successful 
      termination_ is returned. If `status` is `EXIT_FAILURE`, an implementation-
      defined form of the status _unsuccessful termination_ is returned. Otherwise 
      the status returned is implementation-defined.