简体   繁体   English

Linux分段错误与std :: string :: iterator

[英]Linux Segmentation fault with std::string::iterator

I keep getting unusual segmentation faults inside libc.so.6 on a CentOS 6.4 64bit machine. 我在CentOS 6.4 64位机器上的libc.so.6中不断出现异常的分段错误。 This is the backtrace that gdb most often reports: 这是gdb最常报告的回溯:

0x00007ffff60d9b3f in memcpy () from /lib64/libc.so.6
(gdb) backtrace
#0  0x00007ffff60d9b3f in memcpy () from /lib64/libc.so.6
#1  0x00000000004b6a6b in std::string::_S_construct<__gnu_cxx::__normal_iterator<char*, std::string> > ()
#2  0x00000000004b719b in NewsMAIL::SMTPClient::receiveLine(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*) ()
#3  0x00000000004b776f in NewsMAIL::SMTPClient::handleResponse() ()

And this is the code in question that seems to trigger the segfault: 这是有问题的代码似乎触发了段错误:

bool SMTPClient::receiveLine(std::string* Line)
{
    static std::string Buffer;
    std::string::iterator iter;

    while((iter = std::find(Buffer.begin(), Buffer.end(), '\n')) == Buffer.end()) {

        char Bucket[MAX_BUCKET_SIZE + 1] = {};
        int BytesRecv = read(m_Socket, Bucket, MAX_BUCKET_SIZE);

        //Did we get a socket error?
        if(BytesRecv == -1) {

            //This is generally considered a bad thing..
            *Line = Buffer;
            Buffer = std::string("");
            return false;
        }

        Bucket[BytesRecv] = 0;
        Buffer += Bucket;
    }

    *Line = std::string(Buffer.begin(), iter);
    Buffer = std::string(iter + 1, Buffer.end());

    return true;
}

Sometimes it works 100% without any failures so it is not everytime unfortunately. 有时它100%没有任何故障,所以不幸的是每次都没有。 The above code is a slightly modified version of this: https://stackoverflow.com/a/1584620/3133245 以上代码是对此的略微修改版本: https//stackoverflow.com/a/1584620/3133245

Does anyone have any thoughts on why this might be happening? 有没有人对为什么会发生这种情况有任何想法? I am compiling with g++ 4.7.2 我正在使用g ++ 4.7.2进行编译

Thanks! 谢谢!

Nate 内特

Using a static variable (Buffer) is not thread safe. 使用静态变量(Buffer)不是线程安全的。 Could cause a crash. 可能导致崩溃。

You should add a check that Line is not NULL . 您应该添加一个Line不为NULL的检查。

BTW, the line Buffer = std::string(""); BTW,行Buffer = std::string(""); could be Buffer.clear(); 可能是Buffer.clear();

In addition to the static variable issue, are you sure that the data that is received contains no embedded NULL characters? 除了静态变量问题,您确定收到的数据不包含嵌入的NULL字符吗?

If the resulting Buffer contains embedded NULL bytes, this line will not do the correct concatenation using the += operator: 如果生成的Buffer包含嵌入的NULL字节,则此行不会使用+ =运算符执行正确的连接:

Buffer += Bucket;

The += overload assumes that Bucket is a c-style string, thus the first NULL byte encountered will be used as the terminator when the concatenation occurs. + =重载假定Bucket是一个c风格的字符串,因此遇到的第一个NULL字节将在连接发生时用作终结符。

Taking a glance at the code, it would seem to be the case that if the Bucket does indeed contain embedded NULL chracters, doing the above concatenation could result in your "iter" iterator pointing passed the end() of Buffer (in those lines after the while() loop). 看一下代码,似乎情况是如果Bucket确实包含嵌入的NULL chracters,执行上面的连接可能会导致你的“iter”迭代器指向传递Buffer的end()(在那些行之后) while()循环)。

Instead, you can do this: 相反,你可以这样做:

Buffer.append(Bucket, BytesRecv)

This guarantees that all characters that Bucket is addressing will be concatenated onto the existing string. 这可以保证Bucket正在寻址的所有字符将连接到现有字符串上。

But before making any changes, make sure you know exactly what the issue is, especially since you stated the error doesn't happen very often. 但在进行任何更改之前,请确保您确切知道问题所在,特别是因为您声明错误不会经常发生。 Changing around code without first knowing the true cause of the error may just mask the error, thus making it harder to diagnose the real issue. 在不首先知道错误的真正原因的情况下更改代码可能只是掩盖错误,从而使得更难以诊断真正的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM