如何观察不正确的堆栈展开?

时间:2016-05-10 17:25:17

标签: c++

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

我想补丁一下,也想知道如何,但不知道如何观察和比较变化。我能以某种方式看到这个吗?可能在OS X上?

1 个答案:

答案 0 :(得分:1)

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

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

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

如果你想使行为可见:使用析构函数创建一个有趣的对象 - 比如在某处记录消息。或者,也许在构造它时,它会创建一个具有特定名称的文件,并在销毁时删除它。在main()中声明此对象的实例。在静态范围内声明另一个(具有不同的消息)。所以现在你的环境中有一个可观察到的效果。

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

[[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.