I have a generated code via protoc
from proto
files. After I have creating protobuf object and serialize then to string
when function ends was called destructor in created proto
objects, and in this moment I get error caused internal desctructo form not editable generated code.
CORRUPT HEAP: Bad head at 0x3fcf7090. Expected 0xabba1234 got 0x313a3446
assert failed: multi_heap_free multi_heap_poisoning.c:253 (head != NULL)
Backtrace: 0x403760ca:0x3fcf6d50 0x40380d39:0x3fcf6d70 0x403886dd:0x3fcf6d90 0x4038784f:0x3fcf6eb0 0x40376662:0x3fcf6ed0 0x4038870d:0x3fcf6ef0 0x4220c769:0x3fcf6f10 0x42052fed:0x3fcf6f30 0x42047af1:0x3fcf6f50 0x42047f02:0x3fcf6f70 0x4203b61a:0x3fcf7000 0x4201fa93:0x3fcf7130 0x4201fdcd:0x3fcf71b0 0x42009ff5:0x3fcf7280 0x4225b0d0:0x3fcf7350 0x40384751:0x3fcf7370
0x403760ca: panic_abort at /home/x/esp/esp-idf/components/esp_system/panic.c:402
0x40380d39: esp_system_abort at /home/x/esp/esp-idf/components/esp_system/esp_system.c:128
0x403886dd: __assert_func at /home/x/esp/esp-idf/components/newlib/assert.c:85
0x4038784f: multi_heap_free at /home/x/esp/esp-idf/components/heap/multi_heap_poisoning.c:253 (discriminator 1)
0x40376662: heap_caps_free at /home/x/esp/esp-idf/components/heap/heap_caps.c:361
0x4038870d: free at /home/x/esp/esp-idf/components/newlib/heap.c:39
0x4220c769: operator delete(void*) at /builds/idf/crosstool-NG/.build/xtensa-esp32s3-elf/src/gcc/libstdc++-v3/libsupc++/del_op.cc:49
0x42052fed: StructureReport::~StructureReport() at /home/x/y/Project/x-x/x-x-x/components/protobufParser/protobuf-c/structure.pb.cc:147
0x42047af1: GatewayReport::clear_report() at /home/x/y/Project/x-x/x-x-x/components/protobufParser/protobuf-c/reports.pb.cc:1150 (discriminator 1)
0x42047f02: GatewayReport::SharedDtor() at /home/x/y/Project/x-x/x-x-x/components/protobufParser/protobuf-c/reports.pb.cc:1113
(inlined by) GatewayReport::~GatewayReport() at /home/x/y/Project/x-x/x-x-x/components/protobufParser/protobuf-c/reports.pb.cc:1105
The proto files is.
message GatewayReport {
string mac = 1;
oneof report {
DeviceReport device = 3;
StructureReport structure = 7;
}
}
message StructureReport {
string mac = 1;
string type = 2;
string revision = 3;
repeated StructureNode nodes = 4;
}
message StructureNode {
bytes uuid = 1;
repeated string capabilities = 2;
}
And the simply code:
std::string ProtobufParser::parseGatewayReportMsg()
{
std::string parsedMsg;
StructureReport structureRep;
GatewayReport gatewayReport;
structureRep.set_mac("FF:FF:FF:FF:FF:FF");
structureRep.set_type("type");
structureRep.set_revision("rev");
auto node = structureRep.add_nodes();
node->add_capabilities("cap");
node->set_uuid("uuid");
gatewayReport.set_mac(deviceProperties->GetMac());
gatewayReport.set_allocated_structure(&structureRep);
gatewayReport.SerializeToString(&parsedMsg);
google::protobuf::ShutdownProtobufLibrary();
return parsedMsg;
}
It is worth mentioning I have a place in my project where protoc object had created and not dystroyed and all works. So this is also prove that some is not correct in destructor in generated code.
To generate protoc code I must use tool protoc-3.15.1-linux-x86_64
. Version is important because library google-protoc for idf which I have needs this version to correct works.
You are using set_allocated_structure(&structureRep)
which takes ownership of the pointed-to object, but the object is a local variable that is freed when the function exits, not a heap-allocated object. Instead, try declaring and passing a pointer to a new heap-allocated StructureReport
:
std::string ProtobufParser::parseGatewayReportMsg()
{
std::string parsedMsg;
StructureReport *structureRep = new StructureReport;
GatewayReport gatewayReport;
structureRep->set_mac("FF:FF:FF:FF:FF:FF");
structureRep->set_type("type");
structureRep->set_revision("rev");
auto node = structureRep->add_nodes();
node->add_capabilities("cap");
node->set_uuid("uuid");
gatewayReport.set_mac(deviceProperties->GetMac());
gatewayReport.set_allocated_structure(structureRep);
gatewayReport.SerializeToString(&parsedMsg);
return parsedMsg;
}
Also you should probably not call google::protobuf::ShutdownProtobufLibrary();
until your main program exits. I've removed that call from the above.