<br><br><div class="gmail_quote">On Mon, Mar 19, 2012 at 3:15 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com">eli.friedman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Mon, Mar 19, 2012 at 2:52 PM, Kostya Serebryany <<a href="mailto:kcc@google.com">kcc@google.com</a>> wrote:<br>
> Hello,<br>
><br>
> While instrumenting LLVM IR in ThreadSanitizer (race detector), I need<br>
> to distinguish between a store to vtable pointer (vptr) and any other<br>
> regular store.<br>
> This special treatment should be limited to class DTORs, so I should also<br>
> know when a function is a DTOR.<br>
> Rationale: need to distinguish benign and harmful races on vptr<br>
> (<a href="http://code.google.com/p/data-race-test/wiki/PopularDataRaces#Data_race_on_vptr" target="_blank">http://code.google.com/p/data-race-test/wiki/PopularDataRaces#Data_race_on_vptr</a>).<br>
><br>
> Currently, I can figure out when a function is a DTOR and when a store<br>
> touches vptr by analyzing mangled names.<br>
> _ZN1BD1Ev=="B::~B()"<br>
> _ZTV1B=="vtable for B"<br>
><br>
> define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) unnamed_addr nounwind<br>
> uwtable align 2 {<br>
> entry:<br>
>   ....<br>
>   store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*]*<br>
> @_ZTV1B, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 8<br>
><br>
> However, this does not sound right.<br>
> What would be the right way to pass this information from clang to LLVM?<br>
> Will using metadata for this purpose be a right solution?<br>
> (insn-level metadata for vptr store and module-level metadata for DTORs)<br>
<br>
</div></div>It's worth pointing out the according to the abstract LLVM IR model,<br>
your "benign" races are in fact undefined behavior.  </blockquote><div><br></div><div>Oh yes. According to C++11 too, I believe.</div><div>But C++98 did not define threads, so we are in the grey area here.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The only reason<br>
it appears to work is that in practice non-atomic loads and stores<br>
usually result in the same generated code as "relaxed" atomic loads<br>
and stores.  If we are in fact supposed to guarantee some sort of<br>
behavior here, we should generate an atomic store.  If we aren't, I'm<br>
not sure why AddressSanitizer</blockquote><div><br></div><div>s/AddressSanitizer/ThreadSanitizer/</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> needs to distinguish between "usually<br>

appears to work" and "almost always appears to work".<br></blockquote><div><br></div><div>This is more like "almost always works in practice" and "certainly broken". </div><div>We run ThreadSanitizer (the old valgrind-based one) on millions lines of legacy code (not always our own code) and we see a lot of those "benign" vptr races. </div>
<div>Ignoring those (while still detecting really harmful ones) has been #1 feature request from our users until we implemented it in valgrind-based ThreadSanitizer. </div><div><br></div><div>--kcc </div><div><br></div><div>
 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
-Eli<br>
</font></span></blockquote></div><br>