std::string::迭代器的Linux分段错误



我在一台CentOS 6.4 64位机器上的libc.so.6中不断出现异常的分段错误。这是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() ()

这是有问题的代码,似乎触发了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;
}

有时它能100%工作,没有任何故障,所以不幸的是,并非每次都是这样。上面的代码是此代码的一个稍微修改的版本:https://stackoverflow.com/a/1584620/3133245

有人想过为什么会发生这种事吗?我正在使用g++4.7.2 进行编译

谢谢!

内特

使用静态变量(Buffer)不是线程安全的。可能导致崩溃。

您应该添加一个检查Line不是NULL

BTW,线路Buffer = std::string("");可以是Buffer.clear();

除了静态变量问题外,您确定接收到的数据不包含嵌入的NULL字符吗?

如果生成的Buffer包含嵌入的NULL字节,则此行将不会使用+=运算符进行正确的串联:

Buffer += Bucket;

+=重载假设Bucket是一个c风格的字符串,因此当发生串联时,遇到的第一个NULL字节将用作终止符。

看一眼代码,似乎是这样的情况:如果Bucket确实包含嵌入的NULL chracter,那么进行上述连接可能会导致"iter"迭代器指向传递了Buffer的end()(在while()循环之后的那些行中)。

相反,你可以这样做:

Buffer.append(Bucket, BytesRecv)

这保证了Bucket正在寻址的所有字符都将连接到现有字符串上。

但在做出任何更改之前,请确保您确切地知道问题所在,尤其是因为您声明错误不会经常发生。在不知道错误真正原因的情况下更改代码可能会掩盖错误,从而使诊断真正问题变得更加困难。

相关内容

  • 没有找到相关文章

最新更新