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可能在代码的其他地方,远离您发布的代码片段。从最近修改的代码开始

    编辑:您已经自己编写了一个很好的堆栈损坏示例,这是您发现的。这里有一个:

    void foo (){ 
        int x[0];
        x[-99] = -1;
    }
    
    找到了

    culrpit是在我给出代码之前出现的,但是Hans Passant给了我一个看什么的线索。看起来是这样的:

    ...
    
    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);
        }
    }
    
    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);
    
    因此,我今天添加了第三个if which user“piesnPlik”变量。但是“nazwaNagraniaMP3”比复制到那里的其他两个变量长,所以它破坏了堆栈。但令人难以置信的是,它成功地在之后处理了所有SDL内容,但在从函数返回后却崩溃了


    谢谢大家的建议

    我遇到了一个非常类似的问题,在
    \uu堆栈\u chk\u失败时代码崩溃

    在我的例子中,上面推荐的解决方案是去掉
    sprintf()

    听起来像是过时的构建。你重建了所有使用这个函数的东西了吗?你知道为什么擦除
    模式==3
    部分对他的情况有帮助吗?没有,它只是隐藏了缓冲区溢出正在发生的事实。在。。。在模式==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。