Skip to content

Instantly share code, notes, and snippets.

@joshkel
Last active April 23, 2017 03:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshkel/9af642f2d932e72a3038862db75f43dc to your computer and use it in GitHub Desktop.
Save joshkel/9af642f2d932e72a3038862db75f43dc to your computer and use it in GitHub Desktop.
Google Protocol Buffers UBSan workarounds

A hack / workaround for google/protobuf#1450, to get a stock version of Protocol Buffers 2.6.1 to work under UBSan. This is useful for (e.g.) building applications on Ubuntu 14.04 or 16.04, where you want to continue using the distro-provided protobuf library packaging instead of upgrading or patching the source.

There are two steps.

Step 1

Replace every 16 in the generated .pb.cc files with this. For example, if you use GNU Make to generate your .pb.cc files:

%.pb.cc %.pb.h %_pb2.py: %.proto
	protoc --cpp_out=. --python_out=. $<

Then you can add a Perl one-liner to do the search-and-replace:

%.pb.cc %.pb.h %_pb2.py: %.proto
	protoc --cpp_out=. --python_out=. $<
	@# Hack: Work around https://github.com/google/protobuf/issues/1450
	@# The ZR macros described there can work with 'this' and don't need to use
	@# reinterpret_cast<>(0x10).
	perl -pi -e 's/>\(16\)/>(this)/' $@

Step 2

Make sure that the following code is included in each of your generated .pb.cc files:

#include <google/protobuf/generated_message_reflection.h>

#undef GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  _Pragma("GCC diagnostic push") \
  _Pragma("GCC diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(TYPE, FIELD) \
  _Pragma("clang diagnostic pop") \
  _Pragma("GCC diagnostic pop")

#endif

(The best way to do this depends on your particular setup. E.g., you can use search-and-replace, as above, to #include a header with this code. In my case, each of our .pb.cc files is #included in a matching .cpp file, because some of our tools are very picky about file endings, so the .cpp files were a natural place to add this.)

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