#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
одновременно имитируется только один поток, поэтому вы можете не соблюдать условия гонки, возникающие в результате одновременного выполнения потоков.