<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, May 12, 2014 at 5:29 PM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">
<div class="">On Mon, May 12, 2014 at 3:45 PM, Stephan Tolksdorf <span dir="ltr"><<a href="mailto:st@quanttec.com" target="_blank">st@quanttec.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>On 12.05.14 13:13, Kostya Serebryany wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Do you have a test that demonstrates that? That would be very helpful.<br>
</blockquote>
<br></div>
In push_back for example, you annotate that the length increases by 1, but then you don't undo that annotation if the copy constructor of the element throws an exception. Afterwards the sanitizer can't properly check accesses to the end of the vector and the next time the vector calls __sanitizer_annotate_<u></u>contiguous_container it will pass a wrong old_mid pointer.<br>

</blockquote><div><br></div></div><div>Trying to build a test case with libc++ and exceptions... (not trivial, will take some time)</div></div></div></div></blockquote><div><br></div><div>Reproduced. (we have very little code with exceptions so this has avoided our testing efforts :)</div>
<div>Any suggestion for the fix? <br></div><div><div><br></div><div>#include <vector></div><div>#include <assert.h></div><div>#include <iostream></div><div>#include <sanitizer/asan_interface.h></div>
<div>using namespace std;</div><div><br></div><div>class X {</div><div> public:</div><div>  X(const X &x) {</div><div>    if (x.a == 42) throw 0;</div><div>    a = x.a;</div><div>  }</div><div>  X(char arg): a(arg){}</div>
<div>  char get() const { return a; }</div><div> private:</div><div>  char a;</div><div>};</div><div><br></div><div>int main() {</div><div>  vector<X> v;</div><div>  v.reserve(2);</div><div>  v.push_back(X(2));</div>
<div>  assert(v.size() == 1);</div><div>  try {</div><div>    v.push_back(X(42));</div><div>    assert(0);</div><div>  } catch (int e) {</div><div>    assert(v.size() == 1);</div><div>  } </div><div>  assert(v.size() == 1);</div>
<div>  assert(v[1].get() != 777); </div><div>  char *p = (char*)v.data();</div><div>  assert(!__asan_address_is_poisoned(p));</div><div>  assert(__asan_address_is_poisoned(p+1));</div><div>} </div></div><div><br></div><div>
<br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">
<div class="gmail_quote"><div class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
And an unrelated issue: the documentation for __sanitizer_annotate_<u></u>contiguous_container states that the complete buffer should be unpoisened before it is deallocated. This doesn't seem to be happening in the destructor or in the deallocate function.</blockquote>

</div><div>Here we rely on the fact that vector is using the default allocator, which immediately calls delete, which itself unpoisons the memory chunk.   </div><div><br></div><div>--kcc </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<span><font color="#888888"><br>
<br>
- Stephan<br>
<br>
</font></span></blockquote></div><br></div></div>
</blockquote></div><br></div></div>