Clang15 + Protobuf 3.19.4 weird variadic template function args passing behavior

19 views
Skip to first unread message

Mike Tsai

unread,
Sep 12, 2024, 3:00:55 AM9/12/24
to Protocol Buffers
Greetings, 

We are seeing a weird behavior that when we compile the *pb.cc generated with a v3.19.4 protobuf that the variadic template function gets called, the args seems to be passed incorrectly. We are not sure if it' a compiler issue or protobuf issue. The same *pb.cc can be compiled and run correctly with GCC but it will crash with Clang.

I will share some code snippet on the generated code..

```
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void BaseCVRequest::set_requestid(ArgT0&& arg0, ArgT... args) {
 
 requestid_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{},  static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:cvclient.data.request.BaseCVRequest.requestId)
}
```

Our test program is straightforward and we've confirmed GetArenaForAllocation() does return nullptr for both GCC and Clang compiled test program (which listed below).
```

#include <iostream>
#include "CVServiceRequest.pb.h"

static const std::string CVS_REQUEST_DUMMY_ID = "123";
using namespace cvclient::data::request;

int main(int args, char** argv) {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
   std::cout << "Hello World" << std::endl;

   CVInternalRequest internalRequest;
   internalRequest.mutable_basecvrequest()->set_requestid(CVS_REQUEST_DUMMY_ID);

}
```
We would hit a SEGB in set_requestid() beacuse the arena pointer is bogus.

BaseCVRequest is within CVInternalRequest.

What seems to happen is GetArenaForAllocation() returns nullptr, but when it gets call into arenastring's Set function, it become a bogus pointer. 

```
google::protobuf::internal::ArenaStringPtr::Set (this=0x46be50, value=..., arena=0x460014) at google/protobuf/arenastring.cc:102

Python Exception <class 'ModuleNotFoundError'>: No module named 'gdb.styling'
102 Set(&GetEmptyStringAlreadyInited(), value, arena);
(gdb) list
97 }
98 }
99
100 void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value,
101 ::google::protobuf::Arena* arena) {
102 Set(&GetEmptyStringAlreadyInited(), value, arena);
103 }
104
105 void ArenaStringPtr::Set(EmptyDefault, std::string&& value,
106 ::google::protobuf::Arena* arena) {
(gdb) p value
$1 = (google::protobuf::ConstStringParam) <error reading variable: Cannot access memory at address 0x0>
(gdb)
```

The libprotobuf.so shared lib on our target i s GCC-V11.2 built. Has anyone encountered similar issue. 

Thanks,

Mike


Reply all
Reply to author
Forward
0 new messages