Stack smashing before `main()` caused by adding `import` to quick start's greeter proto file
#12.732 geöffnet am 9. Mai 2023
Repository-Metriken
- Stars
- (71.223 Stars)
- PR-Merge-Metriken
- (Durchschn. Merge 2T 11h) (185 gemergte PRs in 30 T)
Beschreibung
Note that I originally thought this is a bug in the gRPC generator, so I filed an issue here. However, I have since realized that this is an issue in protobuf: I can reproduce the issue without grpc.
What version of protobuf and what language are you using? Version: v21.12 Version: v20.2 Version: v19.5 Version: v18.3 Version: v16.2 Version: v3.10.1 Version: v3.6.1.3
Language: C++
What operating system (Linux, Windows, ...) and version? Ubuntu 20.04 LTS
What runtime / compiler are you using (e.g., python version or gcc version)
gcc --version ->
gcc (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
What did you do?
- Use the
Greeterservice quickstart example fromgrpc.iofound here.- Copy-pasted the first proto file text found in the quick start website into
./src/proto/greeter.proto - I did not copy the .proto file from the grpc repository
- Copy-pasted the first proto file text found in the quick start website into
- Add
import "google/api/field_behavior.proto";to import a.protofile fromgoogleapisrepository here. - Compile the .proto files to generate C++ header and source files into a static library
- Instantiate
HelloRequestandHelloReplyin an executable which links against the static library - Run the built executable
This is verified in a repository I created with a demonstration here.
You can run ./build.sh. It will:
- :warning: Prune Docker then remove existing
protobuf-toolchainandprotobuf-stacksmashimages to keep Docker from using tons of resources while iterating changes to the source tree - :information_source: Find or create a few toolchain images
- Find, or create and tag,
ubuntu-2004-toolchainimage which includes only the Ubuntu packages required to compile- this takes a couple minutes
gcc-11is installed from ubuntu-toolchain PPA
- Find, or create and tag,
cmake-toolchainimage which builds and installs cmake from source - Find, or create and tag,
protobuf-toolchainimage which builds and installsprotobuffrom source- NOTE: this image enables Address Sanitizer via environment variables to enforce ASAN throughout the demonstration.
- Here is
protobufversion. Note that I use versionv21.12due to a separate issue found while constructing this demonstration. - Here is
grpcversion
- Find, or create and tag,
- :information_source: Create and tag a new
protobuf-stacksmashimage which compiles a demonstration - :exclamation: Runs the newly-created
protobuf-stacksmashimage to demonstrate whether the resulting executable is viable
What did you expect to see
:heavy_check_mark: Per initial commit here:
./build.sh ->
Successfully built 55df7a9eb834
Successfully tagged grpc-stacksmash:latest
greeter service created -- no stacksmash
What did you see instead?
:exclamation: :stop_sign: ./build.sh ->
Successfully tagged protobuf-stacksmash:latest
*** stack smashing detected ***: terminated
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7f5ca1291941 bp 0x7ffcad720d20 sp 0x7ffcad720ac0 T0)
==1==The signal is caused by a READ memory access.
==1==Hint: this fault was caused by a dereference of a high value address (see register values below). Dissassemble the provided pc to learn which register was used.
#0 0x7f5ca1291941 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x22941)
#1 0x7f5ca12fc26d (/lib/x86_64-linux-gnu/libc.so.6+0x8d26d)
#2 0x7f5ca139eab9 in __fortify_fail (/lib/x86_64-linux-gnu/libc.so.6+0x12fab9)
#3 0x7f5ca139ea85 in __stack_chk_fail (/lib/x86_64-linux-gnu/libc.so.6+0x12fa85)
#4 0x7f5ca1958f90 in google::protobuf::EncodedDescriptorDatabase::Add(void const*, int) google/protobuf/descriptor_database.cc:322
#5 0x7f5ca1925663 in google::protobuf::DescriptorPool::InternalAddGeneratedFile(void const*, int) google/protobuf/descriptor.cc:1358
#6 0x7f5ca191c49d in protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptorsImpl() google/protobuf/any.pb.cc:97
#7 0x7f5ca17f84de in __pthread_once_slow (/lib/x86_64-linux-gnu/libpthread.so.0+0x114de)
#8 0x7f5ca191c65e in __gthread_once /usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:700
#9 0x7f5ca191c65e in void std::call_once<void (&)()>(std::once_flag&, void (&)()) /usr/include/c++/11/mutex:783
#10 0x7f5ca191c65e in void google::protobuf::internal::call_once<std::once_flag&, void (&)()>(std::once_flag&, void (&)()) google/protobuf/stubs/once.h:91
#11 0x7f5ca191c65e in protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptors() google/protobuf/any.pb.cc:105
#12 0x7f5ca24b3b99 (/lib64/ld-linux-x86-64.so.2+0x11b99)
#13 0x7f5ca24b3ca0 (/lib64/ld-linux-x86-64.so.2+0x11ca0)
#14 0x7f5ca24a3139 (/lib64/ld-linux-x86-64.so.2+0x1139)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0x22941) in abort
==1==ABORTING
Anything else we should know about your project / environment
./build.sh is the driver for the demo.
./docker contains Dockerfiles and scripts to set up the build toolchain.
./docker/ubuntu-2004-toolchain.Dockerfile installs GCC
./docker/cmake-toolchain.Dockerfile inherits FROM ubuntu-2004-toolchain and builds & installs cmake
./docker/protobuf-toolchain.Dockerfile inherits FROM cmake-toolchain and builds & installs protobufs (especially protoc). The version of protobuf can be configured as an argument.
./Dockerfile inherits FROM protobuf-toolchain and builds the project with cmake.
./src contains the stack smashing demo
./src/proto/external contains a static library whose only purpose is to compile external proto files -- eg proto files that were nominally downloaded from elsewhere (eg, here.
./src/proto contains a static library whose only purpose is to compile proto files into a static library. It contains the greeter service proto. It then links to and imports the external protos.
./src/greeter-service contains an executable. Its only purpose is to link against the static proto library and instantiate the objects that were generated.
The ./Dockerfile then sets greeter-service as its entrypoint so that docker run will run the demo.
This problem is a Minimal Compilable Reproducible Example that has been trimmed down from a larger codebase. The larger codebase includes several golang projects which are currently using the .proto files being imported. This issue blocks me from building a C++ project to communicate with several golang projects that are already importing this file.