Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SegFault accessing Any in Map #19567

Open
Chekov2k opened this issue Dec 9, 2024 · 2 comments
Open

SegFault accessing Any in Map #19567

Chekov2k opened this issue Dec 9, 2024 · 2 comments

Comments

@Chekov2k
Copy link

Chekov2k commented Dec 9, 2024

Im using protobuf 29.1 with llvm 19.1.5 on Mac OS X 15.1.1 (24B91) to generate C++ bindings:

brew info protobuf
==> protobuf: stable 29.1 (bottled)
brew info llvm
==> llvm: stable 19.1.5 (bottled), HEAD [keg-only]

What did you do?

Since the switch to 29.X my code segfaults with EXC_BAD_ACCESS.

I have narrowed it down to an access to an Any in a Map that was filled previously. The proto spec is

syntax = "proto3";
package test;

import "google/protobuf/any.proto";

message Message{
    string content = 1;
}

message Map {
    map<string, google.protobuf.Any> any = 1;
}

and the C++ code is generated like this: protoc --cpp_out . test.proto

The C++ minimal reproducer is:

#include <iostream>

#include "test.pb.h"

using namespace test;

int main() {
  Map map;
  Message message;
  message.set_content("test");
  if ((*map.mutable_any())["test"].PackFrom(message))
    std::cout << map.DebugString() << std::endl;
}

compiled using this command clang++ -fclang-abi-compat=17 $(pkg-config --cflags --libs protobuf) test.pb.cc main.cpp -o test

What did you expect to see

The debug string is printed correctly.

What did you see instead?

A segfault occurs:

lldb -- ./test
(lldb) target create "./test"
Current executable set to '/Users/balzer/Downloads/test' (arm64).
(lldb) run
Process 34287 launched: '/Users/balzer/Downloads/test' (arm64)
1
Process 34287 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x000000010044b398 libprotobuf.29.1.0.dylib`google::protobuf::internal::MapFieldPrinterHelper::SortMap(google::protobuf::Message const&, google::protobuf::Reflection const*, google::protobuf::FieldDescriptor const*, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*>>*) + 520
    frame #2: 0x000000010044a7fc libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintField(google::protobuf::Message const&, google::protobuf::Reflection const*, google::protobuf::FieldDescriptor const*, google::protobuf::TextFormat::BaseTextGenerator*) const + 212
    frame #3: 0x000000010044a684 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintMessage(google::protobuf::Message const&, google::protobuf::TextFormat::BaseTextGenerator*) const + 612
    frame #4: 0x0000000100449948 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::Print(google::protobuf::Message const&, google::protobuf::TextFormat::BaseTextGenerator*) const + 292
    frame #5: 0x0000000100449694 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::Print(google::protobuf::Message const&, google::protobuf::io::ZeroCopyOutputStream*, google::protobuf::internal::FieldReporterLevel) const + 72
    frame #6: 0x00000001004467f8 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintToString(google::protobuf::Message const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*) const + 84
    frame #7: 0x00000001004468b0 libprotobuf.29.1.0.dylib`google::protobuf::Message::DebugString() const + 152
    frame #8: 0x00000001000148f4 test`main + 244
    frame #9: 0x0000000183670274 dyld`start + 2840

Anything else we should know about your project / environment

It is not just accessing the debug string, any access to the stored Any results in a segfault. Any idea what is going on?

I also tested different ways of inserting into the Map and they all fail:

#include <iostream>
#include <string>

#include <google/protobuf/any.pb.h>

#include "test.pb.h"

using namespace test;

int main() {
  Map map;
  Message message;
  message.set_content("test");

  google::protobuf::Any any;
  if(any.PackFrom(message)) {
    map.mutable_any()->insert(std::make_pair<std::string, google::protobuf::Any>("test", std::move(any)));
    std::cout << map.DebugString() << std::endl;
  }
}
@Chekov2k Chekov2k added the untriaged auto added to all issues by default when created. label Dec 9, 2024
@zhangskz zhangskz added c++ 29.x and removed untriaged auto added to all issues by default when created. labels Dec 9, 2024
@sbenzaquen
Copy link
Contributor

Is this specific to just Any?
Would it happen with user-defined messages?
What about other built-in messages, like some of the messages from descriptor.proto?
Is this only with string keys? or also with integral keys?

@Chekov2k
Copy link
Author

Is this specific to just Any? Would it happen with user-defined messages? What about other built-in messages, like some of the messages from descriptor.proto? Is this only with string keys? or also with integral keys?

I can confirm the segfaults happens for custom messages as well, i.e:

syntax = "proto3";
package test;

message Message{
    string content = 1;
}

message Map {
    map<string, Message> custom = 1;
  }

and

#include <iostream>
#include <string>

#include "test.pb.h"

using namespace test;

int main() {
  Map map;
  Message message;
  message.set_content("test");
  (*map.mutable_custom())["test"] = message;
  std::cout << map.DebugString() << std::endl;
}

with segfault

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x000000010044b398 libprotobuf.29.1.0.dylib`google::protobuf::internal::MapFieldPrinterHelper::SortMap(google::protobuf::Message const&, google::protobuf::Reflection const*, google::protobuf::FieldDescriptor const*, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*>>*) + 520
    frame #2: 0x000000010044a7fc libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintField(google::protobuf::Message const&, google::protobuf::Reflection const*, google::protobuf::FieldDescriptor const*, google::protobuf::TextFormat::BaseTextGenerator*) const + 212
    frame #3: 0x000000010044a684 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintMessage(google::protobuf::Message const&, google::protobuf::TextFormat::BaseTextGenerator*) const + 612
    frame #4: 0x0000000100449948 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::Print(google::protobuf::Message const&, google::protobuf::TextFormat::BaseTextGenerator*) const + 292
    frame #5: 0x0000000100449694 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::Print(google::protobuf::Message const&, google::protobuf::io::ZeroCopyOutputStream*, google::protobuf::internal::FieldReporterLevel) const + 72
    frame #6: 0x00000001004467f8 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintToString(google::protobuf::Message const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*) const + 84
    frame #7: 0x00000001004468b0 libprotobuf.29.1.0.dylib`google::protobuf::Message::DebugString() const + 152
    frame #8: 0x0000000100014c7c test`main + 192
    frame #9: 0x0000000183670274 dyld`start + 2840

Also using an integral key results in a segfault:

syntax = "proto3";
package test;

message Message{
    string content = 1;
}

message Map {
    map<int32, Message> custom = 1;
  }

code:

#include <iostream>
#include <string>

#include "test.pb.h"

using namespace test;

int main() {
  Map map;
  Message message;
  message.set_content("test");
  (*map.mutable_custom())[1] = message;
  std::cout << map.DebugString() << std::endl;
}

Segfault:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x0000000100443398 libprotobuf.29.1.0.dylib`google::protobuf::internal::MapFieldPrinterHelper::SortMap(google::protobuf::Message const&, google::protobuf::Reflection const*, google::protobuf::FieldDescriptor const*, std::__1::vector<google::protobuf::Message const*, std::__1::allocator<google::protobuf::Message const*>>*) + 520
    frame #2: 0x00000001004427fc libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintField(google::protobuf::Message const&, google::protobuf::Reflection const*, google::protobuf::FieldDescriptor const*, google::protobuf::TextFormat::BaseTextGenerator*) const + 212
    frame #3: 0x0000000100442684 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintMessage(google::protobuf::Message const&, google::protobuf::TextFormat::BaseTextGenerator*) const + 612
    frame #4: 0x0000000100441948 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::Print(google::protobuf::Message const&, google::protobuf::TextFormat::BaseTextGenerator*) const + 292
    frame #5: 0x0000000100441694 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::Print(google::protobuf::Message const&, google::protobuf::io::ZeroCopyOutputStream*, google::protobuf::internal::FieldReporterLevel) const + 72
    frame #6: 0x000000010043e7f8 libprotobuf.29.1.0.dylib`google::protobuf::TextFormat::Printer::PrintToString(google::protobuf::Message const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*) const + 84
    frame #7: 0x000000010043e8b0 libprotobuf.29.1.0.dylib`google::protobuf::Message::DebugString() const + 152
    frame #8: 0x00000001000152a8 test`main + 196
    frame #9: 0x0000000183670274 dyld`start + 2840

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants