Let ArenaStringPtr debug-fail if it ever attempts to clear a default string.

As an optimization, we maintain a default instance of a string in memory, and
messages with uninitialized fields will be constructed with a pointer to this
default string object. The destructor should clear the field only when it is
"set" to a nondefault object.

If `ClearNonDefaultToEmpty()` is ever called on a default string...
- It will result in undefined behaviour. Most likely, it results in overwriting
  an object in memory (which is already full of zeros) with another bunch of
  zeros.
- It's quite bad for a number of reasons:
  1. It can confuse TSAN.
  2. It blocks us from moving the default instance of the string into the
     `.data` section. Having the default instance of the string live in
     read-only memory would be beneficial for memory safety. It would play well
     with hugepages. It would also eliminate some runtime cost of instantiating
     the default instance of the string.

This change adds a debug-fail so that users don't call this function "unsafely".

PiperOrigin-RevId: 684569674
pull/18762/head
Tony Liao 2 months ago committed by Copybara-Service
parent 0d7fd35086
commit 6c9c12c8a1
  1. 1
      src/google/protobuf/arenastring.h

@ -523,6 +523,7 @@ inline PROTOBUF_NDEBUG_INLINE void ArenaStringPtr::InternalSwap(
inline void ArenaStringPtr::ClearNonDefaultToEmpty() {
// Unconditionally mask away the tag.
ABSL_DCHECK(!tagged_ptr_.IsDefault());
tagged_ptr_.Get()->clear();
}

Loading…
Cancel
Save