我在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() ()
这是有问题的代码似乎触发了段错误:
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编译
谢谢!
内特
答案 0 :(得分:2)
使用静态变量(Buffer)不是线程安全的。可能会导致崩溃。
您应该添加Line
不是NULL
的支票。
顺便说一句,行Buffer = std::string("");
可以是Buffer.clear();
答案 1 :(得分:1)
除静态变量问题外,您确定收到的数据是否包含嵌入的NULL字符吗?
如果生成的Buffer包含嵌入的NULL字节,则此行不会使用+ =运算符执行正确的连接:
Buffer += Bucket;
+ =重载假定Bucket是一个c风格的字符串,因此遇到的第一个NULL字节将在连接发生时用作终结符。
看一下代码,似乎情况是如果Bucket确实包含嵌入的NULL chracters,执行上面的连接可能会导致你的“iter”迭代器指向传递Buffer的end()(in while()循环后的那些行。
相反,你可以这样做:
Buffer.append(Bucket, BytesRecv)
这可以保证Bucket正在寻址的所有字符将连接到现有字符串上。
但在进行任何更改之前,请确保您确切知道问题所在,特别是因为您声明错误不会经常发生。在不首先知道错误的真正原因的情况下更改代码可能只是掩盖错误,从而使得更难以诊断真正的问题。