расширение в буфере протокола Google, приводящее к прерыванию

#c #protocol-buffers #abort

#c #протокол-буферы #прервать

Вопрос:

Моя проблема с исходным классом сообщений протокола, он работает нормально.

 message StrategyMessage {
  required bytes name = 1;
  optional int64 timestamp = 3;
  extensions 33 to 63;

}

extend StrategyMessage {
    /// many optional fields

    optional int64 best_bid=39;
}
  

И всякий раз, когда я использую расширенные поля, вставленные ниже, выдает мне ошибки.

 strategy_message_.SetExtension(utils::strategy_controller::best_bid,best_bid_);
LOG_DEBUG(logger_, " Sending message to U/I n");
if (!strategy_controller_client_->send_message(strategy_message_)) {
            LOG_DEBUG(logger_, "ERROR: couldn't send message to U/In");
}
  

Это выдает ошибку.

 10/03/16 17:48:07.593132144 D  Sending message to U/I 

libprotobuf FATAL google/protobuf/message_lite.cc:270] CHECK failed: (end) == (reinterpret_cast<uint8*>(data)   byte_size): 

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffd8de8700 (LWP 63533)]
0x00007ffff4ef25d7 in raise () from /lib64/libc.so.6
(gdb) 
  

но когда я запускаю его после изменения, как показано ниже, это сработало.

 strategy_message_.set_timestamp(timestamp);
LOG_DEBUG(logger_, " Sending message to U/I n");
if (!strategy_controller_client_->send_message(strategy_message_)) {
            LOG_DEBUG(logger_, "ERROR: couldn't send message to U/In");
}
  

Функция send_message() реализована так, как показано ниже.

 bool StrategyControllerClient::send_message(StrategyMessageamp; msg) {
  if (server_side_fd_ < 0) {
    return false;
  }
  msg.set_server_ip(local_interface_ip_);
  return send_message_impl(msg, server_side_fd_);
}

bool StrategyControllerClient::send_message_impl(const ::google::protobuf::Messageamp; msg, int fd) {
  uint32_t size = msg.ByteSize();
  if (size > nMaxSizeOfMessageToServer) {
    ERROR_LOG << ::utils::current_time_ns() << " Msg to Server is too big: " << size << "n";
    ERROR_LOG << msg.DebugString() << "n";
    return false;
  }
  message_allocator_lock_.lock();
  MessageToServer* tm = message_allocator_->allocate();
  message_allocator_lock_.unlock();
  tm->msg.fd_identifier = fd;
  tm->msg.data_iov[0].iov_len = size;
  msg.SerializeToArray(tm->msg.data_iov[0].iov_base, size);
  if (!network_io_manager_->send_msg(amp;tm->msg)) {  // We won't get a callback so deallocate
    ERROR_LOG << ::utils::current_time_ns() << " Error in sending message to Server(2)n";
    ERROR_LOG << msg.DebugString() << "n";
    message_allocator_lock_.lock();
    message_allocator_->deallocate(tm);
    message_allocator_lock_.unlock();
    return false;
  }
  return true;
}
  

РЕДАКТИРОВАТЬ: в программе нет утечек.

 ==68909== LEAK SUMMARY:
==68909==    definitely lost: 0 bytes in 0 blocks
==68909==    indirectly lost: 0 bytes in 0 blocks
==68909==      possibly lost: 19,778 bytes in 404 blocks
==68909==    still reachable: 280,616 bytes in 964 blocks
==68909==         suppressed: 0 bytes in 0 blocks
==68909== Reachable blocks (those to which a pointer was found) are not shown.
==68909== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==68909== 
==68909== ERROR SUMMARY: 322 errors from 322 contexts (suppressed: 2 from 2)
  

EDIT2: программа прерывается в строке.

 msg.SerializeToArray(tm->msg.data_iov[0].iov_base, size);
  

Комментарии:

1. Возможно, у вас где-то повреждение памяти. Сначала проверьте свое приложение valgrind .

2. @MaximEgorushkin, обновил результаты

3. Вы хотите сказать, что ваше приложение не завершается сбоем valgrind ?

4. @MaximEgorushkin, похоже, на этот раз прерывание не вызывается.

5. Если он выходит из строя без valgrind , но не с ним, это, вероятно, означает, что существует условие гонки. valgrind одновременно имитируется только один поток, поэтому вы можете не соблюдать условия гонки, возникающие в результате одновременного выполнения потоков.