c++ - C++ 程序中非常奇怪的堆栈溢出

标签 c++ macos stack-overflow callstack

我前段时间写了一个程序(Mac OS X、C++、SDL、FMOD),它的性能相当不错。但最近我想扩展它的功能并向它添加更多代码。现在,当我运行它并尝试测试新功能时,程序因 SIGABRT 而崩溃。

查看调试器,在函数堆栈上我看到:

  • _kill
  • 杀死$UNIX2003
  • 提高
  • __中止
  • __stack_chk_fail
  • odtworz <-- 我的函数被修改了

据我所知,“__stack_chk_fail”表示堆栈溢出。但这还不是最奇怪的地方。在这个函数“odtworz”中,我有一些这样的代码:

...

koniec = 0;
while ( koniec == 0 ) {
    ...
    if (mode == 1) {
        ...
    }
    else if (mode == 2) {
        ...
    }
    else if (mode == 3) {
       piesniOrkiestrowe[0] = '\0'; 
       while ( piesniOrkiestrowe[0] == '\0' ) { 
           losowaPiesn(); 
           char * piesnOrkiestrowa = szukajPiesniOrkiestrowej(); 
           if ( piesnOrkiestrowa != NULL ) 
              strcpy(piesniOrkiestrowe, piesnOrkiestrowa); 
       } 
       char nowyPiesnPlik[25]; 
       sprintf(nowyPiesnPlik, "%sorch/%s", PIESNI_DIR.c_str(), piesniOrkiestrowe);
    }
}

mode 是一个全局变量,之前在一个函数中被设置为值“2”。现在想象一下——如果我删除第三个 if 语句(mode == 3),它永远不会在这种模式下执行,程序不会崩溃!删除甚至没有被执行的代码有助于解决这个问题!

现在,我不想删除这段代码,因为它用于我程序的其他模式。它在那里工作得很好。那么我可以在哪里搜索的任何提示?这可能有什么问题?

最佳答案

不是堆栈溢出错误。检测到堆栈帧损坏时调用 __stack_chk_fail。粉碎堆栈的传统方法是缓冲区溢出。导致它的代码不在您的代码段中,而是在点中。


用评论中的代码更新问题后:strcpy 和 sprintf 调用都是堆栈损坏的极好候选者。我在原回答中提到的缓冲区溢出问题。猜一猜:现在的 PiesnPlik 看起来非常小。 sprintf() 函数会将过多的字符写入缓冲区并覆盖“金丝雀”。当金丝雀被踩到时,运行时会吹口哨 :)

你可以让数组更大。这不是真正的解决方案,请为这些函数使用安全的替代方案,例如 snprintf()。我将避免提及 strncpy()。

关于c++ - C++ 程序中非常奇怪的堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3037636/

相关文章:

c++ - 在 C++ 中加载共享库导致段错误

c++ - 即使关闭预编译 header 并包含 <string>,Visual Studio 也无法识别 stod()

c++ - 使用类、私有(private)、公共(public)、构造函数、函数、整数和字符串进行进一步学习的程序

c++ - 主机和目标的 Makefile

python - 如何在 Mac OSX 10.9 上为 python 3.3.5 安装 NumPy

excel - 如果列中的字符串左对齐,如何获取信息以及如何在另一个工作表中使用此信息创建新单元格?

OS X 应用程序的 XCode 5 远程调试

recursion - 提前编译时 Clojure fn 名称泄漏到其范围之外

java - Android Firebase 实时异常 java.lang.StackOverflowError : stack size 8MB

c++堆栈溢出未处理的异常与大数组