Почему я получаю сообщение «Недействительное чтение размера 8»? (Валгринд) - PullRequest
1 голос
/ 29 мая 2020

Я уже читал похожие сообщения в Stackoverflow, но они не решают мою проблему.

Моя проблема

Я получаю следующее сообщение об ошибке от Valgrind, когда запускаю отладочную версию исполняемого файла с Valgrind.

==16631== Invalid read of size 8
==16631==    at 0x217890: std::__detail::__variant::_Uninitialized<long long, true>::_Uninitialized<long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:222)
==16631==    by 0x2178C9: std::__detail::__variant::_Variadic_union<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variadic_union<long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:342)
==16631==    by 0x2178FD: std::__detail::__variant::_Variant_storage<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:399)
==16631==    by 0x2156F0: std::__detail::__variant::_Copy_ctor_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:504)
==16631==    by 0x215716: std::__detail::__variant::_Move_ctor_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:532)
==16631==    by 0x21573C: std::__detail::__variant::_Copy_assign_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:592)
==16631==    by 0x215762: std::__detail::__variant::_Move_assign_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:649)
==16631==    by 0x215791: std::__detail::__variant::_Variant_base<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_base<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:701)
==16631==    by 0x213F29: std::variant<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::variant<0ul, long long const&, long long, void>(std::in_place_index_t<0ul>, long long const&) (variant:1398)
==16631==    by 0x213F6B: std::variant<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::variant<long long const&, void, void, long long, void>(long long const&) (variant:1369)
==16631==    by 0x20B8ED: tgbot::Endpoints::deleteMessage(long long const&, int const&) const (Endpoints.cpp:1957)
==16631==    by 0x2B17F6: ChatCleaner::run(std::shared_ptr<tgbot::Bot> const&) (ChatCleaner.cpp:40)
==16631==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==16631== 
==16631== 
==16631== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==16631==  Access not within mapped region at address 0x0
==16631==    at 0x217890: std::__detail::__variant::_Uninitialized<long long, true>::_Uninitialized<long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:222)
==16631==    by 0x2178C9: std::__detail::__variant::_Variadic_union<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variadic_union<long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:342)
==16631==    by 0x2178FD: std::__detail::__variant::_Variant_storage<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:399)
==16631==    by 0x2156F0: std::__detail::__variant::_Copy_ctor_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:504)
==16631==    by 0x215716: std::__detail::__variant::_Move_ctor_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:532)
==16631==    by 0x21573C: std::__detail::__variant::_Copy_assign_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:592)
==16631==    by 0x215762: std::__detail::__variant::_Move_assign_base<false, long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_storage<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:649)
==16631==    by 0x215791: std::__detail::__variant::_Variant_base<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::_Variant_base<0ul, long long const&>(std::in_place_index_t<0ul>, long long const&) (variant:701)
==16631==    by 0x213F29: std::variant<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::variant<0ul, long long const&, long long, void>(std::in_place_index_t<0ul>, long long const&) (variant:1398)
==16631==    by 0x213F6B: std::variant<long long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<tools::InputFile> >::variant<long long const&, void, void, long long, void>(long long const&) (variant:1369)
==16631==    by 0x20B8ED: tgbot::Endpoints::deleteMessage(long long const&, int const&) const (Endpoints.cpp:1957)
==16631==    by 0x2B17F6: ChatCleaner::run(std::shared_ptr<tgbot::Bot> const&) (ChatCleaner.cpp:40)
==16631==  If you believe this happened as a result of a stack
==16631==  overflow in your program's main thread (unlikely but
==16631==  possible), you can try to increase the size of the
==16631==  main thread stack using the --main-stacksize= flag.
==16631==  The main thread stack size used in this run was 8388608.
==16631== 
==16631== HEAP SUMMARY:
==16631==     in use at exit: 317,149 bytes in 4,488 blocks
==16631==   total heap usage: 1,171,900 allocs, 1,167,412 frees, 359,098,054 bytes allocated
==16631== 
==16631== LEAK SUMMARY:
==16631==    definitely lost: 0 bytes in 0 blocks
==16631==    indirectly lost: 0 bytes in 0 blocks
==16631==      possibly lost: 0 bytes in 0 blocks
==16631==    still reachable: 317,045 bytes in 4,487 blocks
==16631==         suppressed: 104 bytes in 1 blocks
==16631== Reachable blocks (those to which a pointer was found) are not shown.
==16631== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==16631== 
==16631== For lists of detected and suppressed errors, rerun with: -s
==16631== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Speicherzugriffsfehler (Speicherabzug geschrieben)

Подходящий исходный код

"m_msgs_to_delete" является вектором stati c в классе ChatCleaner.

32void ChatCleaner::run(const tgbot::Bot::ptr &bot) noexcept
33{
34  if(!m_msgs_to_delete.empty())
35  {
36      //Reverse to have the oldest message at the end.
37      std::reverse(m_msgs_to_delete.begin(), m_msgs_to_delete.end());
38
39      //Delete the message.
40      bot->get_endpnts()->deleteMessage(m_msgs_to_delete.at(m_msgs_to_delete.size() - 1)->chat->id, m_msgs_to_delete.at(m_msgs_to_delete.size() - 1)->message_id);
41      m_msgs_to_delete.pop_back();
42
43      //Reverse again.
44      std::reverse(m_msgs_to_delete.begin(), m_msgs_to_delete.end());
45
46      m_last_time = tools::Tools::get_time();
47      m_msgs_to_delete.shrink_to_fit();
48  }
49}
1953    bool Endpoints::deleteMessage(const long long &chat_id, const int &message_id) const noexcept
    {
        //HTTP arguments
        std::vector<tools::HttpArg> http_args;
1957        http_args.push_back(tools::HttpArg("chat_id", chat_id));
        http_args.push_back(tools::HttpArg("message_id", message_id));

        tools::HttpClient http_client("https://api.telegram.org/bot" + m_token + "/deleteMessage", http_args);
        std::string json = http_client.send_post_req_multipart().m_body;

1963        rapidjson::Document doc;
        doc.Parse(json.c_str());

        if(doc.IsObject())
            if(doc.HasMember("result"))
                if(doc["result"].IsBool())
1969                    return doc["result"].GetBool();
                else
                    tools::Tools::write_err_log(Messages::field_does_not_contain_bool("result"));
            else
                tools::Tools::write_err_log_tmp(Messages::field_non_existent("result"));
        else
            tools::Tools::write_err_log(Messages::server_resp_not_json_object);
1976
1977        return false;
1978    }

От чего Я вижу, что ошибка возникает в строке 40 фрагмента выше, поскольку это отрывок из файла ChatCleaner. cpp. Эта строка обращается к вектору, что полностью может быть ошибкой, поскольку у пользователей с аналогичными проблемами в Stackoverflow также были проблемы с доступом к вектору или массиву. К сожалению, я не вижу, что я сделал не так. Эта ошибка возникает совершенно произвольно, и я не могу ее воспроизвести.

Дополнительные примечания, которые могут помочь

  • Код взят из моего чат-бота для Telegram, который работает круглосуточно и без выходных.
  • Ошибка может произойти через несколько минут после запуска программного обеспечения или через несколько дней или недель.
  • Вектор содержит std :: shared_ptr <> отправленных сообщений, которые будут удалены через некоторое время.
  • Я уже проверил, может ли векторный контент быть поврежден, чего не было, когда произошла ошибка. Чат и идентификатор сообщения были в полном порядке. Я очень полагаю, что это всего лишь проблема с доступом к памяти, но я не могу понять причину проблемы.

Вопрос

В чем причина проблемы?

1 Ответ

0 голосов
/ 30 мая 2020

Я наконец нашел источник проблемы с помощью подсказок, которые дал @ cdhow ie. Переменная-член "chat" объекта Message вызвала проблему, поскольку, как вы можете видеть здесь

if(doc.HasMember("chat"))
{
    if(doc["chat"].IsObject())
        chat = std::make_shared<Chat>(tools::Tools::get_json_as_string(doc["chat"]));
    else
        tools::Tools::write_err_log(Messages::field_does_not_contain_json_obj("chat"));
}

, эта часть конструктора сообщения создает экземпляр чата только в том случае, если переданное тело ответа HTTP содержит правильное поле. Следовательно, этот член доступа m_msgs_to_delete.at(m_msgs_to_delete.size() - 1)->chat->id в строке 40 ChatCleaner. cpp вызвал нулевой указатель, поскольку в этом случае «chat» не существует в куче.

PS: объект do c выше происходит из библиотеки Rapid json. Определение rapidjson::Document doc;. Его цель - разобрать JSON объектов и сделать данные доступными. Весь исходный код взят от моего чат-бота Telegram.

...