【问题标题】:How to fix SIGSEGV Segmentation fault error? [closed]如何修复 SIGSEGV Segmentation fault 错误? [关闭]
【发布时间】:2019-08-07 06:20:23
【问题描述】:

我从一篇研究论文中运行open source code,遇到了分段错误错误。

我用gdb查看生成的core文件,用bt full详细了解出了什么问题,但是我对c++非常陌生,所以不知道如何使用给出的信息进一步调试此错误。

Program terminated with signal SIGSEGV, Segmentation fault.
#0  __GI_____strtof_l_internal (nptr=0x0, endptr=0x7ffecd484cd8, group=<optimized out>, loc=0x7f32914c5560 <_nl_global_locale>)
    at strtod_l.c:609
609 strtod_l.c: No such file or directory.
(gdb) bt full
#0  __GI_____strtof_l_internal (nptr=0x0, endptr=0x7ffecd484cd8, group=<optimized out>, loc=0x7f32914c5560 <_nl_global_locale>)
    at strtod_l.c:609
        negative = 0
        num = {0, 0, 0, 511101108348, 390842024046, 0, 0, 4, 18446744073709551504, 140732342488280}
        numsize = 0
        exponent = 0
        base = 10
        den = {140732342488280, 0, 4, 139855159296252, 139855168706208, 0, 14395410707824902144, 4, 140732342488288, 139855165608536}
        densize = <optimized out>
        retval = {206158430210}
        bits = 0
        cp = 0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>
        tp = <optimized out>
        startp = <optimized out>
        start_of_digits = <optimized out>
        expp = <optimized out>
        dig_no = <optimized out>
        int_no = <optimized out>
        lead_zero = <optimized out>
        c = <optimized out>
        decimal = 0x7f329128e7d8 <dot> "."
        decimal_len = 1
        thousands = 0x0
        grouping = 0x0
        cnt = <optimized out>
        current = <optimized out>
        __PRETTY_FUNCTION__ = "____strtof_l_internal"
        lowc = <optimized out>
#1  0x0000562b2bf93133 in get_all_cooked_time_bw(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
No symbol table info available.
#2  0x0000562b2bf8f2ab in main ()
No symbol table info available.
(gdb) quit

我猜这是出了问题的地方: cp = 0xffffffffffffffff &lt;error: Cannot access memory at address 0xffffffffffffffff&gt;, 但我不知道cp 代表什么,也不知道在哪里以及如何解决这个问题。

以下是相关代码:

void split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss;
    ss.str(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
}

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}

ALL_COOKED_TIME_BW get_all_cooked_time_bw(std::string path) {
    ALL_COOKED_TIME_BW all_cooked_time_bw;
    struct dirent *entry;
    DIR *dir = opendir(path.c_str());
    if (dir != NULL) {
        while ((entry = readdir(dir)) != NULL) {
            if (entry->d_name[0] == '.') continue;  // read . or ..

            std::string file_name = "";
            file_name += COOKED_TRACE_FOLDER;
            file_name += entry->d_name;
            printf("%s\n", file_name.c_str());

            std::ifstream in_file(file_name);
            std::string line;
            std::vector<float> cooked_time;
            std::vector<float> cooked_bw;

            if (in_file.is_open())
            {

                while ( getline (in_file, line) )
                {
                    std::vector<std::string> parse = split(line, '\t');
                    cooked_time.push_back(std::stof(parse[0]));
                    cooked_bw.push_back(std::stof(parse[1]));
                }
                in_file.close();
            }

            all_cooked_time_bw.all_cooked_time.push_back(cooked_time);
            all_cooked_time_bw.all_cooked_bw.push_back(cooked_bw);
            all_cooked_time_bw.all_file_names.push_back(entry->d_name);

        }
    }
    closedir(dir);

    return all_cooked_time_bw;
}

【问题讨论】:

  • 很难说cp 来自暴露的数据。这可能是真正的问题(如果它是例如要在strtod_l.c 中处理的参数之一)。它也可能是一个尚未初始化或分配的变量,因此是无害的。为了解决这个问题,您应该“向上走”堆栈并检查数据的外观,这些数据在相应的情况下传递。函数调用。
  • 而且,顺便说一句。 &lt;optimized out&gt; 变量也可能有问题(崩溃时可能存储在寄存器中)。
  • 看了两遍,我认出了__GI_____strtof_l_internal (nptr=0x0, endptr=0x7ffecd484cd8, group=&lt;optimized out&gt;, loc=0x7f32914c5560 &lt;_nl_global_locale&gt;)。 nptr=0x0 看起来也有点可疑,但没有更多信息,这只是一个意外。所以,我再次提示:走上堆栈检查函数调用中的参数...
  • 你没有可用的c运行时源代码
  • 损坏意味着在某种程度上无效,没有任何源代码很难说更多

标签: c++ c++11 segmentation-fault gdb ubuntu-18.04


【解决方案1】:

如果此处传递给 split 的行不包含 2 个(或更多)元素:

std::vector<std::string> parse = split(line, '\t');

那么以下 2 行通过将无效字符串传递给 std::stof 导致未定义的行为:

cooked_time.push_back(std::stof(parse[0]));
cooked_bw.push_back(std::stof(parse[1]));

这应该通过一些更具防御性的编程来解决:

if ( parse.size() != 2 )
{
   throw std::invalid_argument("invalid file: " + file_name);
}
cooked_time.push_back(std::stof(parse[0]));
cooked_bw.push_back(std::stof(parse[1]));

在大多数情况下,您还应该将pos 参数传递给std::stof,否则它会忽略字符串末尾的非数字字符。例如:

size_t pos;
cooked_time.push_back(std::stof(parse[0], &pos));
if (pos != parse[0].size())
{
   throw std::invalid_argument("invalid file: " + file_name);
}

【讨论】:

  • 非常感谢,您的意见真的很有帮助。结果证明这是一个愚蠢的错误,我所要做的就是将 '\t' 更改为 ' '。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
  • 2021-03-18
  • 2011-08-16
  • 2021-01-16
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多