mav*_*mav 2 c++ stack-overflow macos callstack
我不久前写了一个程序(Mac OS X,C++,SDL,FMOD),它表现得相当不错.但最近我想扩展其功能并为其添加更多代码.现在,当我运行它并尝试测试新功能时,程序会与SIGABRT崩溃.
查看调试器,在函数堆栈上我看到:
据我所知,"__ 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),程序不会崩溃!删除甚至无法执行的代码有助于这种情况!
现在,我不想删除此代码,因为它适用于我的程序的其他模式.它在那里工作得很好.那么我可以搜索的任何提示?这可能有什么问题?
Han*_*ant 16
它不是堆栈溢出错误.检测到堆栈帧损坏时调用__stack_chk_fail.粉碎堆栈的传统方法是缓冲区溢出.导致它的代码不在您的代码段中,而是在点中.
用注释中的代码更新问题后:strcpy和sprintf调用都是堆栈损坏的绝佳候选者.我在原始答案中提到的缓冲区溢出问题.以一个猜测:nowyPiesnPlik看起来非常小.sprintf()函数会向缓冲区写入太多字符并覆盖"canary".当金丝雀被踩到时,运行时会吹口哨:)
你可以让阵列更大.不是真正的解决方案,请使用snprintf()这些函数的安全替代方案.我会避免提到strncpy().