Объект Protobuf повреждается при передаче в динамическую библиотеку c - PullRequest
1 голос
/ 28 апреля 2020

Я работаю над интеграцией моей библиотеки с некоторой структурой глубокого обучения, и у меня возникли некоторые проблемы с памятью. Я подозреваю, что проблема здесь в protobuf, но я хотел спросить вас, ребята, о мнении и некоторой помощи, потому что я уже потратил слишком много времени. Короче говоря, фреймворк работает на моделях глубокого обучения в формате ONNX. Он читает их в память для onnx::ModelProto объектов. Затем эти объекты передаются в мою библиотеку, где они преобразуются (и оптимизируются) в мое пользовательское представление и возвращаются обратно в среду. onnx::ModelProto - это класс C ++, сгенерированный с помощью protoc из https://github.com/onnx/onnx/blob/master/onnx/onnx.proto - обычного сообщения protobuf. * ​​1007 *

Проблема возникает, когда ModelProto достигает моей библиотеки. Основным членом ModelProto является график, который является указателем: onnx::GraphProto* onnx::ModelProto::graph_. Когда объект передается в мою библиотеку, указатель на граф устанавливается по другому адресу, который не является правильным GraphProto расположением объекта:

framework:
model_proto: 0x2ccb450
graph address: 0x2cc1d20
---
mylib:
model_proto: 0x2ccb450
graph address: 0x7fb6529c2560

Раздражает то, что это происходит только в сборках Release. Когда я компилирую оба в отладке - это работает правильно.

Кроме того, до того, как эта ошибка появилась, я передавал объект ModelProto в мою библиотеку, используя std::stringstream - я сначала сериализовал модель в рамках в строку, создал поток из него и десериализовал в моей библиотеке. График тоже был поврежден сразу после завершения десериализации, и это было настолько плохо, что я продолжал падать segfaults в своем коде.

Может ли это быть как-то связано с тем, что и фреймворк, и моя библиотека ссылаются статически со своими копиями протобуф? Protobuf добавляется как зависимость и компилируется как с фреймворком, так и с моей библиотекой. Я убедился, что использую ту же версию (сейчас она 3.11). Я также использую ту же версию ONNX (1.6).

Вот как выглядят зависимости и рабочий процесс:

dependencies

Ответы [ 2 ]

2 голосов
/ 28 апреля 2020

Поскольку в C ++ нет стандартного ABI, планка для передачи объектов между библиотеками, построенными по отдельности, довольно высока.

Вся причина использования protobuf состоит в том, чтобы преобразовать объекты в строки и затем обменять эти символьные массивы между двумя конечными точками. Таким образом вы решаете все проблемы, связанные с объектами, имеющими различные макеты, форматы, точность и порядковый номер.

Если вы абсолютно хотите передавать указатели, параметры сборки должны быть идентичными. Все. Все версии компилятора и компоновщика, настройки, все #defines, уровни оптимизации и т. Д. c ... Это путь, по которому очень трудно следовать, и который ведет к хрупкому решению.

1 голос
/ 28 апреля 2020

Я думаю, что нашел решение, но я все еще не уверен на 100%, в чем причина root.

Библиотека ONNX позволяет вам настроить пространство имен, в котором будут находиться сгенерированные классы https://github.com/onnx/onnx/blob/master/CMakeLists.txt#L76 -L78

Я установил произвольное значение в моей библиотеке и, наконец, исправил проблему. Я переключился обратно на версию istringstream, и она, кажется, работает. Он прошел много проверок CI, поэтому все выглядит хорошо.

...