用于 IDF 的 C++ Google Protobuf。调用析构函数时出现错误 CORRUPT HEAP

问题描述 投票:0回答:1

我有一个通过

protoc
proto
文件生成的代码。创建 protobuf 对象并序列化到
string
后,当函数结束时,在创建的
proto
对象中调用析构函数,此时我收到错误,导致内部 desctructo 形式不可编辑生成的代码。

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

原型文件是。

    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;
    }

简单的代码:

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;
}

值得一提的是,我的项目中有一个地方,protoc 对象已经创建,并且没有被破坏,并且所有工作都有效。所以这也证明了生成代码中析构函数中有些不正确。 要生成协议代码,我必须使用工具

protoc-3.15.1-linux-x86_64
。版本很重要,因为我拥有的 idf 库 google-protoc 需要这个版本才能正确工作。

c++ esp32 protoc
1个回答
0
投票

您正在使用

set_allocated_structure(&structureRep)
,它获取指向对象的所有权,但该对象是一个局部变量,当函数退出时会被释放。相反,尝试声明并传递指针:

std::string ProtobufParser::parseGatewayReportMsg()
{
    std::string parsedMsg;
    StructureReport *structureRep = new StructureReport;
    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;
}
© www.soinside.com 2019 - 2024. All rights reserved.