Я сталкиваюсь со странной проблемой с protobuf в C ++ в Windows с Visual Studio 2017 с protobuf 3.10.0.
Поскольку я пока не смог выделить основную причину и не смог создатьполезный минимальный пример кода, которым я мог бы поделиться, я пытаюсь объяснить проблему как можно лучше. Моя цель состоит в том, чтобы получить некоторую информацию, если кто-то сталкивался с той же или подобной проблемой, чтобы получить представление о том, как отладить проблему. Ищите любые полезные идеи.
Я добавил буферы протокола для сериализации в сложный, существующий проект. До сих пор это работало очень хорошо.
Но в последнее время мы начали видеть проблему, заключающуюся в том, что сериализованные потоки не могут быть снова десериализованы теми же исполняемыми файлами.
Проблема: Мы не можем десериализовать поток protbuf, который мы сериализовали ранее (не всегда, но, кажется, повторяется для определенных данных).
Анализируя сериализованный исходный поток protbuf, он обнаруживает, что в потоке protobuf есть одиночные дополнительные байты (обычно 0xCD
...), обычно в двоичном представлении отдельных полей (между длиной и содержимым поля). Размер сообщений и полей кажется «правильным» (если злонамеренный лишний байт не присутствует).
Есть некоторые подсказки, которые, кажется, указывают, что это проблема с VS2017 C ++Оптимизация компилятора :
Наш сервер сборки и большинство компьютеров наших разработчиков работают с VS 2017 Vers. 15.9.x . Проблема может возникнуть в исполняемых файлах, созданных на этих машинах. Это начало происходить при перемещении на новый сервер сборки с версиями 15.9.x.
У меня есть компьютер, который все еще работает на VS 2017 V.15.7.6 ;до сих пор мы не смогли выявить проблему с исполняемыми сборками на этом ПК.
До сих пор не удалось воспроизвести проблему на любых сборках debug .
Ранее мы сталкивались с той же или очень похожей проблемой с protobuf 3.5.1 (во время сериализации protobuf выдавал исключение FatalException, указывающее, что прогнозируемый размер не соответствует длине потока), также толькоприсутствует в версиях выпуска с рассматриваемой версией инструментальной панели VS2017, но она временно исчезла, когда мы переключились на protobuf 3.10.0. С 3.10.0 похоже, что проверки, которые вызвали FatalException, были удалены (я знаю, что парсеры / сериализатор были изменены в 3.10.0), и FatalException больше не генерируется. Эта проблема возникает и в меньшем количестве ситуаций.
Кроме того, данные, которые мы имеем в наших сообщениях, по-видимому, влияют на то, возникает ли проблема.
Это немного сложно для отладки илиВыделить проблему в форму, где я мог бы точно определить в качестве виновника определенную оптимизацию или фрагмент кода. Попытка воссоздать проблему в «минимальных рабочих примерах», которые должны выявить проблему, до сих пор не удалась. Я не вижу ничего подозрительного в коде protobuf. У меня заканчиваются идеи, и я хотел знать, сталкивается ли кто-нибудь с подобными проблемами или есть какие-либо идеи, какие дальнейшие шаги я мог бы предпринять. Да, я искал в интернете, но пока ничего не нашел по этому вопросу. Если я смогу опубликовать больше информации по этой проблеме (кроме: исходного кода ...), пожалуйста, дайте мне знать.
Информация:
Сборка буферов протоколаиз исходного кода, используя cmake и тот же набор инструментов VS2017, который использовался для создания основного проекта.
Он статически связан с основным приложением.
C ++время выполнения во внешней dll (/ MD) как для библиотеки protobuf, так и для основного проекта.
компилятор protobuf (protoc), используемый для генерации кода, происходит из той же сборки, что и связанные библиотеки protobufв проект и файлы заголовков, скомпилированные для.
Мы не одновременно получаем доступ к объекту сообщения protobuf для сериализации из других потоков.