Осмысление сообщения addr2line с помощью C++ STL

У меня был этот редкий segfault, и во время отладки мне удалось получить следующий вывод из программы 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, я, очевидно, не вызываю ее напрямую. Но я не могу угадать, какая публичная функция его вызывает. Если я могу выяснить публичную функцию, я могу сосредоточиться на нулевой разыменовке, которая вызывает segfault.

Я подозреваю следующий код...

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());
}

1 ответ

Решение

С memcpy(&sizeOfStr,&size,4) Я вижу две проблемы.

Во-первых, вы копируете четыре байта из однобайтовой переменной. Это явное неопределенное поведение.

Второе, что sizeOfStr может быть 8 байт (в 64-битных системах GCC обычно long будучи 64 битами). Это позволит части переменной быть неинициализированной и, следовательно, быть неопределенной, что снова приведет к неопределенному поведению.

Используйте обычное назначение и позвольте компилятору правильно выполнить преобразование для вас:

sizeOfStr = size;
Другие вопросы по тегам