C ++程序中非常奇怪的堆栈溢出 [英] VERY strange stack overflow in C++ program
问题描述
前段时间,我编写了一个程序(Mac OS X,C ++,SDL,FMOD),并且效果不错.但是最近我想扩展它的功能并添加更多代码.现在,当我运行它并尝试测试新功能时,该程序会因SIGABRT而崩溃.
I wrote a program some time ago (Mac OS X, C++, SDL, FMOD) and it perfomed rather good. But lately I wanted to extend its functionality and added some more code to it. And now, when I run it and try to test the new functionality, the program crashes with SIGABRT.
查看调试器,在函数堆栈上,我看到:
Looking into debugger, on function stack I see:
- _kill
- kill $ UNIX2003
- 提高
- __ abort
- __ stack_chk_fail
- odtworz<-我的功能已被修改
据我所知,"__ stack_chk_fail"表示堆栈溢出.但这不是最奇怪的事情.在此功能"odtworz"中,我有一些类似这样的代码:
As far as I know, "__stack_chk_fail" indicates a stack overflow. But that's not the weirdest thing about it. In this function "odtworz", I have some code like this:
...
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语句(模式== 3),该语句永远不会在此模式下执行,则程序不会崩溃!删除甚至无法执行的代码有助于解决问题!
mode is a global variable and is set to value "2" in a function before. And now imagine - if I delete the third if statement (mode == 3) which never gets executed in this mode, the program doesn't crash! Deleting code that doesn't even get to be executed helps the situation!
现在,我不想删除此代码,因为它用于我程序的其他模式.它在那里工作正常.那么有什么提示我可以搜索的吗?这可能是什么问题?
Now, I don't want to delete this code because it's for other mode of my program. And it works fine there. So any hints where I can search? What could be possibly wrong with this?
推荐答案
不是堆栈溢出错误.当检测到堆栈帧损坏时,将调用__stack_chk_fail.粉碎堆栈的传统方法是缓冲区溢出.导致它的代码不在您的代码段中,而是在点中.
It is not a stack overflow error. __stack_chk_fail is called when stack frame corruption is detected. The traditional way to smash the stack is a buffer overflow. The code that causes it is not in your snippet, it is in the dots.
使用注释中的代码更新问题之后:strcpy和sprintf调用都是堆栈损坏的理想选择.我在原始答案中提到的缓冲区溢出问题.猜一猜:nowyPiesnPlik看起来很小. sprintf()函数将过多的字符写入缓冲区并覆盖"canary".当金丝雀踩踏时,运行时将鸣叫鸡:)
After updating the question with code from a comment: both the strcpy and the sprintf calls are excellent candidates for stack corruption. The buffer overflow problem I mentioned in my original answer. Taking a guess: nowyPiesnPlik looks very small. The sprintf() function will write too many characters to the buffer and overwrite the "canary". When the canary gets stomped on, the runtime will whistle fowl :)
您可以使数组更大.这不是真正的解决方案,请对这些功能使用安全的替代方法,例如snprintf().我将避免提及strncpy().
You could make the array bigger. Not a real solution, use safe alternatives for these functions, like snprintf(). I'll avoid mentioning strncpy().
这篇关于C ++程序中非常奇怪的堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!