If two threads have one freshly initialized string buffer each and call strbuf_reset on them at roughly the same time, both threads will be writing a '\0' to strbuf_slopbuf. That is not a problem in practice since it doesn't matter in which order the writes happen. But ThreadSanitizer will consider this a race. When compiling with GIT_THREAD_SANITIZER, avoid writing to strbuf_slopbuf. Let's instead assert on the first byte of strbuf_slopbuf being '\0', since it ensures the promised invariant of "buf[len] == '\0'". (Writing to strbuf_slopbuf is normally bad, but could become even more bad if we stop covering it up in strbuf_reset.) Signed-off-by: Martin Ågren <martin.agren@xxxxxxxxx> --- strbuf.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/strbuf.h b/strbuf.h index e705b94db..295654d39 100644 --- a/strbuf.h +++ b/strbuf.h @@ -153,7 +153,19 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len) /** * Empty the buffer by setting the size of it to zero. */ +#ifdef GIT_THREAD_SANITIZER +#define strbuf_reset(sb) \ + do { \ + struct strbuf *_sb = sb; \ + _sb->len = 0; \ + if (_sb->buf == strbuf_slopbuf) \ + assert(!strbuf_slopbuf[0]); \ + else \ + _sb->buf[0] = '\0'; \ + } while (0) +#else #define strbuf_reset(sb) strbuf_setlen(sb, 0) +#endif /** -- 2.14.1.151.gdfeca7a7e