Correct a bug in the code that resets shadow memory introduced as part
of a previous change for the Go race detector (D128909). The bug was
that only the most recently added shadow segment was being reset, as
opposed to the entire extent of the segment created so far. This
fixes a bug identified in Google internal testing (b/240733951).
Details
- Reviewers
dvyukov - Commits
- rG24a62bfe9a49: tsan: fix bug in shadow reset introduced in D128909
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | ||
---|---|---|
203–204 | Do we need the ctx->mapped_shadow_begin variable at all? But also what if the mapped region (ctx->mapped_shadow_begin) is far from ShadowBeg? Won't we mmap/memset potentially huge region (terabytes)? Maybe we need to fix how we update ctx->mapped_shadow_begin instead? E.g. instead of: if (ctx->mapped_shadow_begin < shadow_begin) ctx->mapped_shadow_begin = shadow_begin; do something like: if (!ctx->mapped_shadow_begin || ctx->mapped_shadow_begin > shadow_begin) ctx->mapped_shadow_begin = shadow_begin; ? |
compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | ||
---|---|---|
203–204 | You are the expert here, I am arriving late on the scene. Happy to try your second suggestion.
What confuses me here is that for regular C/C++ tsan (e.g. not SANITIZER_GO) it's going to default to clearing ShadowBegin() through ShadowEnd(), which presumably is a very large region. Wouldn't your concern apply there too? |
compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | ||
---|---|---|
203–204 |
It just looks like mapped_shadow_begin is currently maintained incorrectly (does not really point to the beginning of the used shadow region). Otherwise I don't know how to explain that extreme slowdown in the test we observed.
C++ tsan does not work on Windows. And Windows is the reason we added these mapped_shadow_begin/end. On unixes it's fine to mmap terabytes of virtual address space. |
compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | ||
---|---|---|
203–204 | Right, of course. OK, this strategy: if (!ctx->mapped_shadow_begin || ctx->mapped_shadow_begin > shadow_begin) ctx->mapped_shadow_begin = shadow_begin; looks good-- fixes the google test timeout and seems to be clean with race.bat on windows. I will update the patch. |
Switch shadow clear back to [mapped_shadow_begin, mapped_shadow_end]
but revise recipe for updating mapped_shadow_begin.
Do we need the ctx->mapped_shadow_begin variable at all?
It's used in MapShadow, but only to update itself. So it looks we can remove it now.
But also what if the mapped region (ctx->mapped_shadow_begin) is far from ShadowBeg? Won't we mmap/memset potentially huge region (terabytes)? Maybe we need to fix how we update ctx->mapped_shadow_begin instead?
E.g. instead of:
do something like:
?