问题标签 [stack-unwinding]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 深栈展开
首先,这绝对是关于 C 的,不需要 C++ 解决方案。
目标:返回调用函数(A
)超出多个堆栈帧。
我有一些解决方案,但没有一个是最好的选择。
实现意义上最简单的一个是 longjmp/setjmp,但我不确定它是否会破坏自动变量,因为正如 wiki 所指,如果执行 longjmp,则不会参与正常的堆栈展开。
以下是程序流程的简短描述:A
函数调用file processing
函数,这会导致许多内部和递归调用。在某些时候,文件阅读器遇到了 EOF,所以工作
file processing
已经完成并且应该控制A
功能。
将每个读取的字符与 EOF 或 '\0' 进行比较?不,谢谢。UPD:我可以避免 setjmp 和 longjmp 之间的调用链中的动态分配。
不确定自动变量,我不知道顺序调用会发生什么file processing
(有多个文件)。
所以:
1) longjmp 的“无堆栈展开”怎么样?如果我得到所有可用的数据持有者(指针),那有多危险。
2) 其他简洁有效的返回A
框架的方法?
c++ - 异常c ++中的堆栈展开
我开始学习 C++ 中的异常主题。我遇到了术语“堆栈展开”,据我了解,这意味着每当抛出异常,并且“抛出函数”内部没有 catch 块时,函数堆栈将“展开”,因此所有本地对象的 d' tor 将被调用(在外部函数中也会发生同样的情况,直到遇到合适的 catch 块)。
我的问题:
假设异常是在带有合适的后续捕获的 try 块内引发的,是否将为 try 块内定义的所有对象调用 d'tor?还是对 try 块中定义的所有对象,直到发生异常?或者根本没有对象,他们会“等待”函数退出?
debugging - gdb ARM Cortex-M 异常展开
我一直在使用由我编译的 GCC (v4.7.2)、BinUtils (v2.22)、Newlib (v1.20) 和 GDB (v7.5) 编译的一些 Cortex-M4 (Freescale K60) 设备。我一直对 GDB 无法摆脱硬异常感到恼火。
最近我有机会使用 FreeScale 的 CodeWarrior,我在其中加载了我的二进制文件进行调试(由我的工具编译),它可以解除异常。看起来 CodeWarrior 正在后台运行 GDB v7.4.1。我错过了 GDB 的一些补丁,还是一些配置选项?
这是用于构建 GDB 的脚本: TOOLCHAIN=gdb-7.5 mkdir -p BUILD/gdb cd BUILD/gdb ../../${TOOLCHAIN}/configure --prefix=${PREFIX} --target=${目标} --enable-interwork --enable-multilib --with-expat=yes --with-python --without-auto-load-safe-path 2>&1 | tee configure.out make all install cd ../../
谢谢!
ios - 在 iOS 应用中设置退出按钮
我有一个用 Swift 开发的简单游戏应用程序。我在选项屏幕中有一个按钮,允许用户退出当前游戏并返回开始屏幕。我已经研究了几种方法来做到这一点,但我不确定哪种方法是正确的。
选项 1:我创建了一个退出函数并在主 ViewController 中定义了该函数,它看起来像这样:
然后我只是控制从选项视图控制器内的退出按钮拖动到退出图标。这有效,但给了我一些意想不到的结果。当它通过我的视图控制器展开时,它会一路触发代码,当它返回根 VC 时,会发生一些错误。
选项 2:控制从退出按钮拖回根 VC。这可行,并且不会导致任何错误,但我只是不知道这是否是一种好习惯。这会从堆栈中删除所有其他 VC,还是我只是在旧游戏之上开始新游戏?
c - 遍历堆栈帧是否安全?
在我之前的问题中,我试图查看是否可以以编程方式从其父进程获取子进程的堆栈跟踪。
我已经成功地做到了,但现在另一个问题出现在我的脑海中——在程序执行期间直接检查这些帧是否安全?我在这里将“安全”定义为“不会修改孩子堆栈上的值”。
例如,这是我从运行 NPB-Serial CG A 类基准测试中获得的示例堆栈跟踪:
我想通过复制每个堆栈指针条目处的值来获得堆栈的转储 - 例如,通过0x7ffe5e368e10
从该地址开始并将每个值复制到当前堆栈指针到一个单独的位置。
这样做有什么风险吗?或者我是否错误地考虑了这一点(例如,有一种更简单的方法可以做到这一点)?
c++ - 将关键函数放在析构函数中以“增强原子性”?
假设我有两个 C++ 函数 foo1() 和 foo2(),我想最小化 foo1() 开始执行但由于某些外部事件而没有调用 foo2() 的可能性。我不介意两者都没有被调用,但是如果 foo1() 被调用,则 foo2() 必须执行。这两个函数可以连续调用并且不会抛出异常。
将函数包装在对象中并在析构函数中调用两者有什么好处/缺点?如果应用程序是多线程的(比如父线程崩溃),情况会改变吗?只要 foo1() 被调用,是否有任何其他选项可以确保调用 foo2() ?
我认为将它们放在析构函数中可能有助于例如 SIGINT,尽管我了解到 SIGINT 会立即停止执行,即使在析构函数的中间也是如此。
编辑:
澄清一下: foo1() 和 foo2() 都将被抽象出来,所以我不担心其他人以错误的顺序调用它们。我的担忧仅与应用程序执行期间的崩溃、异常或其他中断有关(例如,有人按下 SIGINT、另一个线程崩溃等)。
windows - 在展开期间在 Windows x64 上恢复 SIMD 寄存器
在 Windows x86-64 上,如何在展开期间恢复被调用方保存的 SIMD 寄存器?如果一个人正在编写汇编代码,如何确保这正确发生?
c++ - Linux/GCC下将NULL指针访问转换为C++异常
有什么方法可以将 NULL 指针访问转换为 Linux 下的 C++ 异常?类似于 Java 中的 NullPointerException。我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法计算出这个 NULL 指针访问):
我不期待任何标准的方法,因为 C++ 下的 NULL 指针访问是未定义的行为,只是想知道如何在 x86_64 Linux/GCC 下完成它。
我对此做了一些非常原始的研究,有可能:
- 在 Linux 下访问 NULL 指针时,会产生一个 SIGSEGV。
- 在 SIGSEGV 处理程序内部,程序的内存和寄存器信息将可用(如果
sigaction()
用于注册信号处理程序)。如果程序被反汇编,导致 SIGSEGV 的指令也可用。 - 修改程序的内存和/或寄存器,并创建/伪造一个异常实例(可能通过调用低级展开库函数,如_Unwind_RaiseException等)
- 最后从信号处理程序返回,希望程序会像抛出正常异常一样启动 C++ 堆栈展开过程。
这是来自 GCC 手册页(-fnon-call-exceptions)的引用:
生成允许捕获指令抛出异常的代码。请注意,这需要并非随处都存在的特定于平台的运行时支持。此外,它只允许捕获指令抛出异常,即内存引用或浮点指令。它不允许从诸如“SIGALRM”之类的任意信号处理程序中抛出异常。
看来这个“特定于平台的运行时”正是我想要的。有人知道 Linux/x86_64 这样的运行时吗?或者如果不存在这样的运行时,请给我一些关于如何实现这样的运行时的信息?
我希望该解决方案也能在多线程程序中工作。
c++ - 在堆栈展开时使用 RAII 是否安全?
问题是 - 当 AutoSomething 的析构函数被调用时,Object 的状态会好吗?