c++ - 仅在打开编译器优化的情况下,某些地方的缓冲区溢出

标签 c++ c linux makefile compiler-optimization

所以我遇到了一个问题,某段代码给我这个错误 *** BUFFER OVERFLOW DETECTED *** .这只是在我打开某些编译器优化选项后才开始发生(这不是我的程序,所以我必须使用这些选项)。我已经缩小到它是哪个选项。我还找到了一种方法来阻止缓冲区溢出,但是,我在程序的另一部分中有非常相似的代码,当我保持原样时,不会给我同样的错误。这让我对我的修复感到非常困惑和非常不自信,因此希望能提供一些指导。

这是来自 makefile 的优化选项

CXXFLAGS+=-Os -O2 -fomit-frame-pointer 
CXXFLAGS+=-fno-aggressive-loop-optimizations

我已将范围缩小到 -O2开始导致错误的标志。

这是在 realpath() 缓冲区溢出时失败的函数仅当 -O2指定标志

static std::string getRealTargetPath (std::string baseTarget)
    {
    char nextTargetLink[MAXPATHLEN];
    memset (nextTargetLink, 0, MAXPATHLEN);

    if (realpath (baseTarget.c_str(), nextTargetLink) == NULL)
        return "";
    else
       //etc...
    }

如果我更改 MAXPATHLEN,上面的函数将按预期运行(尺寸 1024)至 PATH_MAX (尺寸 4096)。好,可以。但是下面这段代码在使用 same std::string baseTarget 后执行了大约 20 行像之前一样。

char realLinkPath[MAXPATHLEN];
memset (realLinkPath, 0, MAXPATHLEN);

do
    {         
    if (realpath (linkPath.c_str(), realLinkPath) != NULL)
        if (strcmp(linkPath.c_str(), realLinkPath) != 0)
            return true;

    size_t eraseFrom = linkPath.rfind('/');
    if (std::string::npos != eraseFrom)
        linkPath.erase(eraseFrom);
    } while ( !linkPath.empty() );

总而言之,即使这两个 realpath功能使用相同的 const char* path变量如果缓冲区不是 PATH_MAX,第一个将失败长度但第二个不会,这一切只发生在-O2标志被指定用于编译。

如有任何帮助,我们将不胜感激。

编辑:正如用户指出的那样,我也将其标记为 C因为程序很老,内核写在C我最好尽可能将它保留为 C 而不要使用太多 C++特点

最佳答案

好吧,第二部分有不同的输入,所以它碰巧运行良好偶然realpath() 是一个非常糟糕的函数,即使是 manpage指出(参见BUGS)。

你能做的最好的事情就是重新编写代码,以便使用 null 指针调用 realpath 作为它的第二个参数,并注意你返回的分配缓冲区是 free()正确地

关于c++ - 仅在打开编译器优化的情况下,某些地方的缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31617589/

相关文章:

c - 为什么 C 编译器在为有符号类型分配过高的整数值时不发出警告?

c++ - 取消引用时指向变量的指针不会更新变量

linux - glibc 中的getpid 工作程序是什么?

c++ - OpenCV InputArray 和 getMat 方法

c++ - 是否可以在 C 或 C++ 中创建另一个函数?

c++ - 在 free/malloc、外部内存 Hook 上花费了大量时间?

C++ 打印二叉搜索树

c - 使用 free 与变量指针

MySQL进程运行时间长,服务器抓取变慢,如何调试

c - 如何并行 mmap 以加快文件读取速度?