<div dir="ltr">Hi, <div><br></div><div style>I have a few questions about libc++'s _LIBCPP_DEBUG. </div><div style><br></div><div style>Is this the right mailing list? </div><div style><br></div><div style>Is the _LIBCPP_DEBUG mode being maintained/developed? </div>
<div style>I see at least two compile-time problems: </div><div style><br></div><div style>1. __LIBCPP_DEBUG is used a few places in include/string instead of _LIBCPP_DEBUG (two '_' instead of one)</div><div style>
<br></div><div style>2.  =================</div><div style>% cat erase.cc </div><div>#include <string></div><div><br></div><div>void foo(std::string &s) {</div><div>  s.erase(10, std::string::npos);</div><div>}</div>
<div>% clang++ ./erase.cc -I/home/kcc/llvm/projects/libcxx/include -D_LIBCPP_DEBUG -c<br></div><div><div>In file included from ./erase.cc:1:</div><div>In file included from /home/kcc/llvm/projects/libcxx/include/string:434:</div>
<div>In file included from /home/kcc/llvm/projects/libcxx/include/algorithm:594:</div><div>In file included from /home/kcc/llvm/projects/libcxx/include/memory:596:</div><div>/home/kcc/llvm/projects/libcxx/include/iterator:1486:30: error: elaborated type refers to a typedef</div>
<div>    friend class _Container::__self;</div><div>                             ^</div><div>./erase.cc:4:11: note: in instantiation of template class 'std::__1::__debug_iter<std::__1::basic_string<char>, const char *>' requested here</div>
<div>  s.erase(10, std::string::npos);</div><div>          ^</div><div>/home/kcc/llvm/projects/libcxx/include/string:1043:58: note: declared here</div><div>    typedef basic_string                                 __self;</div>
<div>                                                         ^</div><div>1 error generated.</div></div><div>=================<br></div><div style><br></div><div style><br></div><div style>Last, and the most interesting question. </div>
<div style>The STL buffer overflow checks are incomplete because there is string::data() which returns the object guts as a raw pointer. </div><div style>Compare these two tests: when using s[3] the checks work, but when using s.data()[3] checks don't work</div>
<div style><br></div><div style><div><div><div>==> string_data_test.cc <==</div><div>#include <string></div><div>int main() {</div><div>  std::string s("012");</div><div>  return s.data()[3];</div><div>
}</div><div><br></div><div>==> string_operator_test.cc <==</div><div>#include <string></div><div>int main() {</div><div>  std::string s("012");</div><div>  return s[3];</div><div>}</div></div></div><div>
<br></div><div style>Same applies to vector.</div><div style>I have a proof-of-concept patch that adds AddressSanitizer annotations to include/string</div><div style>and allows to find buffer overflows even in s.data()[3]. </div>
<div style>Would someone be interested in helping me polish this patch and commit it? </div><div style><br></div><div style><br></div><div style><div>% libc++clang -g  string_data_test.cc -fsanitize=address -O1; ./a.out </div>
<div>=================================================================<br></div><div>==6693== ERROR: AddressSanitizer: use-after-poison on address 0x7fff81527524 at pc 0x41812d bp 0x7fff815274f0 sp 0x7fff815274e8</div><div>
READ of size 1 at 0x7fff81527524 thread T0</div><div>    #0 0x41812c in main /home/kcc/stl_checks/string_data_test.cc:4</div><div>    #1 0x7f0b92c9a76c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)</div><div>    #2 0x417c64 (/home/kcc/stl_checks/a.out+0x417c64)</div>
<div>Address 0x7fff81527524 is located at offset 36 in frame <main> of T0's stack:</div><div>  This frame has 1 object(s):</div><div>    [32, 72) 's'</div><div><br></div></div><div style><br></div><div style>
Thanks,</div><div style><br></div><div style>--kcc </div><div style><br></div><div style><br></div><div style><br></div><div><br></div></div></div>