C+中非常奇怪的堆栈溢出+;程序 我在前一段时间编写了一个程序(Mac OS X,C++,SDL,FMOD),效果相当不错。但最近我想扩展它的功能,并添加了更多的代码。现在,当我运行它并尝试测试新功能时,程序会因SIGABRT崩溃
查看调试器,我在函数堆栈上看到:C+中非常奇怪的堆栈溢出+;程序 我在前一段时间编写了一个程序(Mac OS X,C++,SDL,FMOD),效果相当不错。但最近我想扩展它的功能,并添加了更多的代码。现在,当我运行它并尝试测试新功能时,程序会因SIGABRT崩溃,c++,macos,stack-overflow,callstack,C++,Macos,Stack Overflow,Callstack,查看调试器,我在函数堆栈上看到: _杀死 杀死$UNIX2003 提高 __流产 __堆栈_chk_失败 odtworz这不是堆栈溢出错误__当检测到堆栈帧损坏时,调用stack_chk_fail。打破堆栈的传统方法是缓冲区溢出。导致它的代码不在代码段中,而是在点中 使用注释中的代码更新问题后:strcpy和sprintf调用都是堆栈损坏的最佳候选。我在原始答案中提到的缓冲区溢出问题。猜猜看:nowyPiesnPlik看起来很小。函数的作用是:将过多的字符写入缓冲区,并覆盖“金丝雀”。当金丝
- _杀死
- 杀死$UNIX2003
- 提高
- __流产
- __堆栈_chk_失败
- odtworz这不是堆栈溢出错误__当检测到堆栈帧损坏时,调用stack_chk_fail。打破堆栈的传统方法是缓冲区溢出。导致它的代码不在代码段中,而是在点中
使用注释中的代码更新问题后:strcpy和sprintf调用都是堆栈损坏的最佳候选。我在原始答案中提到的缓冲区溢出问题。猜猜看:nowyPiesnPlik看起来很小。函数的作用是:将过多的字符写入缓冲区,并覆盖“金丝雀”。当金丝雀被踩在地上时,运行时会吹口哨(foll:)
你可以把阵列放大。不是真正的解决方案,请为这些函数使用安全的替代方案,如snprintf()。我将避免提及strncpy()。一点也不奇怪。当涉及到堆栈溢出或堆损坏时,您应该会感到奇怪。堆栈指针、程序计数器或其他程序状态已损坏,因此调试器或跟踪工具无法准确报告崩溃时程序所在的位置。该bug可能在代码的其他地方,远离您发布的代码片段。从最近修改的代码开始 编辑:您已经自己编写了一个很好的堆栈损坏示例,这是您发现的。这里有一个:
找到了 culrpit是在我给出代码之前出现的,但是Hans Passant给了我一个看什么的线索。看起来是这样的:void foo (){ int x[0]; x[-99] = -1; }
... 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); } }
因此,我今天添加了第三个if which user“piesnPlik”变量。但是“nazwaNagraniaMP3”比复制到那里的其他两个变量长,所以它破坏了堆栈。但令人难以置信的是,它成功地在之后处理了所有SDL内容,但在从函数返回后却崩溃了char piesnPlik[25]; if ( mode == TRYB_PIANINO ) sprintf(piesnPlik, "%spiano/%s.mp3", PIESNI_DIR.c_str(), wybranaPiesn); else if ( tryb == TRYB_ORKIESTRA ) sprintf(piesnPlik, "%sorch/%s", PIESNI_DIR.c_str(), piesniOrkiestrowe); else if ( tryb == TRYB_NAGRANIE ) sprintf(piesnPlik, "%s/%s", NAGRANIA_DIR.c_str(), nazwaNagraniaMP3);
谢谢大家的建议 我遇到了一个非常类似的问题,在
。\uu堆栈\u chk\u失败时代码崩溃
在我的例子中,上面推荐的解决方案是去掉
听起来像是过时的构建。你重建了所有使用这个函数的东西了吗?你知道为什么擦除sprintf()
部分对他的情况有帮助吗?没有,它只是隐藏了缓冲区溢出正在发生的事实。在。。。在模式==3?如果是这样,删除该分支可能会影响堆栈布局;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)@mav:可能在模式==3
中声明了一些变量,因此,如果包含此代码,堆栈框架的布局将以不同的方式结束。然后堆栈的其他部分恰好被损坏,而不是堆栈检查函数验证的部分。您能给我一些可能导致堆栈损坏的代码示例吗?我的程序大量使用cstring和string。模式==3