使用 C++ STL 理解 addr2line 消息
Making sense of the addr2line message with C++ STL
我一直遇到这种罕见的段错误,在调试它时,我设法从 addr2line 程序获得以下输出。
void std::string::_S_copy_chars<__gnu_cxx::__normal_iterator<unsigned char
const*, std::vector<unsigned char, std::allocator<unsigned char> > > >
(char*, __gnu_cxx::__normal_iterator<unsigned char const*,
std::vector<unsigned char, std::allocator<unsigned char> > >,
__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char,
std::allocator<unsigned char> > >)
??:?
由于_S_copy_chars()是std::string中的私有函数,我显然不是直接调用它。但我无法猜测哪个 public 函数正在调用它。如果我能找出 public 函数,我就可以将导致段错误的空解除引用归零。
我怀疑下面的代码...
std::string CInProtocolBase::RetrieveStr(std::vector<unsigned
char>::const_iterator& iter)
{
unsigned long sizeOfStr;
const unsigned char& size = *iter;
memcpy(&sizeOfStr,&size,4);
sizeOfStr =
boost::asio::detail::socket_ops::network_to_host_long(sizeOfStr);
std::string str(iter+4,iter+4+sizeOfStr); // <= Could this be culprit??
iter += (4 + sizeOfStr);
return str;
}
另一位候选人是:
std::string CInProtocolBase::VectorToStr(const std::vector<unsigned char>& vec)
{
return std::string(vec.begin(),vec.end());
}
使用 memcpy(&sizeOfStr,&size,4)
我看到两个问题。
第一个是从一个单字节变量中复制四个字节。那是明确的undefined behavior.
第二个是 sizeOfStr
可能是 8 个字节(在 64 位系统上,GCC 通常 long
是 64 位)。这将使部分变量未初始化,因此不确定,再次导致 undefined behavior.
使用正常赋值并让编译器为您正确地进行转换:
sizeOfStr = size;
我一直遇到这种罕见的段错误,在调试它时,我设法从 addr2line 程序获得以下输出。
void std::string::_S_copy_chars<__gnu_cxx::__normal_iterator<unsigned char
const*, std::vector<unsigned char, std::allocator<unsigned char> > > >
(char*, __gnu_cxx::__normal_iterator<unsigned char const*,
std::vector<unsigned char, std::allocator<unsigned char> > >,
__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char,
std::allocator<unsigned char> > >)
??:?
由于_S_copy_chars()是std::string中的私有函数,我显然不是直接调用它。但我无法猜测哪个 public 函数正在调用它。如果我能找出 public 函数,我就可以将导致段错误的空解除引用归零。
我怀疑下面的代码...
std::string CInProtocolBase::RetrieveStr(std::vector<unsigned
char>::const_iterator& iter)
{
unsigned long sizeOfStr;
const unsigned char& size = *iter;
memcpy(&sizeOfStr,&size,4);
sizeOfStr =
boost::asio::detail::socket_ops::network_to_host_long(sizeOfStr);
std::string str(iter+4,iter+4+sizeOfStr); // <= Could this be culprit??
iter += (4 + sizeOfStr);
return str;
}
另一位候选人是:
std::string CInProtocolBase::VectorToStr(const std::vector<unsigned char>& vec)
{
return std::string(vec.begin(),vec.end());
}
使用 memcpy(&sizeOfStr,&size,4)
我看到两个问题。
第一个是从一个单字节变量中复制四个字节。那是明确的undefined behavior.
第二个是 sizeOfStr
可能是 8 个字节(在 64 位系统上,GCC 通常 long
是 64 位)。这将使部分变量未初始化,因此不确定,再次导致 undefined behavior.
使用正常赋值并让编译器为您正确地进行转换:
sizeOfStr = size;