【问题标题】:boost::filesystem::exists segfault on linuxboost::filesystem::exists linux上的段错误
【发布时间】:2016-08-06 18:28:33
【问题描述】:

我的 Kubuntu 上的函数 boost::filesystem::exists() 段错误,我不知道为什么。

这是我的功能:

if (!boost::filesystem::exists("./sthg"))
{
  // ....
}

我检查了 valgrind,他告诉我错误在 xstat.c:35 中,错误是“系统调用参数(文件名)包含未初始化的字节。”

这是我的编译行:

g++ ... -o ... -lboost_system -lboost_filesystem

编辑 1:

调用创建目录的函数的函数:

void TCPConnection::enable(void)
{
    try {
        StaticTools::CreateFolder("./clients");
    } catch (std::exception const& e) {
        std::cerr << e.what() << std::endl;
    }
}

创建目录的函数:

void StaticTools::CreateFolder(std::string const& path)
{
    if (!boost::filesystem::exists(path)) {                                                                                                                         
       if (!boost::filesystem::create_directory(path)) {
          throw (std::runtime_error("..."));
       }
    }                                                                                                                                                                     
}

Valgrind 日志: http://pastebin.com/gbzFDDNg

【问题讨论】:

  • 最可能的解释是您实际上传递给boost::filesystem::exists 的字符串无效。第二种最有可能的解释是您的 Boost 安装与核心 C++ 运行时库不一致或不一致。为了帮助我们找出这两者中的哪一个,请提供minimal, complete verifiable example 而不仅仅是片段。
  • 您可以告诉我们的其他有帮助的事情:dpkg-query -W -f '${db:Status-Abbrev} ${Version} ${Package}\n' g++* libstdc++* boost* libboost* | grep '^ii' | column -t精确的、未经编辑的 输出;您是否手动安装了任何软件(尤其是 boost 或编译器)而不是通过包管理器;以及您从 valgrind 获得的完整堆栈跟踪。
  • 顺便说一句,检查文件是否存在几乎总是一个错误,因为它有一个内在的竞争:在检查和您根据检查采取的行动之间,其他一些程序可能创建或删除文件,使检查无效。相反,只需继续执行您想要对文件执行的操作,并检查该文件是否失败。 (系统原语 open 有一个选项 O_EXCL 对此非常有用。不幸的是,stdio 和 iostreams 都没有公开该选项。)
  • 感谢您的回答,确实,我只是删除了 exists() 验证,它工作正常,但很奇怪......如果您仍然对这个问题感兴趣,我将编辑我的问题并添加你问的日志。 - 字符串是有效的,我通过复制而不是通过引用进行测试 - 我已经使用 apt-get install 命令安装了 boost,与 g++ 相同 - 我的 boost::asio 有效,所以我认为它对安装有好处?
  • 请发布导致错误的实际代码。我们在看不到的代码中找不到错误。

标签: c++ boost segmentation-fault filesystems


【解决方案1】:

1) 如果 boost::filesystem 非常不清楚的文档是我认为的意思,那么创建目录的函数应该简单地阅读

void StaticTools::CreateFolder(std::string const& path)
{
    boost::filesystem::create_directory(path);
}

因为,如果create_directory 在没有抛出异常的情况下返回,那么该目录确实存在。 (返回值只告诉你目录是刚刚创建还是已经作为目录存在。你可能不在乎。)

2) 如果对这个函数的调用真的是

    StaticTools::CreateFolder("./clients");

以字符串文字“./clients”作为参数,and“Syscall param stat(file_name) contains uninitialised byte(s)”确实是第一个valgrind 发出的错误,那么,我很遗憾地说,您可能会遇到 boost 与 C++ 运行时库不一致的不幸情况。具体来说,我认为您的 libstdc++.so 可能默认为 C++11 std::string 而您的 libboost_filesystem.so 期待 C++98 std::string,反之亦然。您没有解决此问题的好方法;负责 boost 和/或 C++ 运行时的 Kubuntu 人员必须这样做。最省力的路径可能是停止使用 boost。这不是开玩笑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多