From: Martin Ågren Date: Tue, 15 Aug 2017 12:53:04 GMT Subject: [PATCH 4/5] strbuf_reset: don't write to slopbuf with ThreadSanitizer Message-ID: <931ffb00319f40e3c9e099f17eeae6a0c1de41ea.1502780344.git.martin.agren@gmail.com> In-Reply-To: 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 --- 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