<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54977>54977</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
LeakSanitizer does not unwind stack behind std::string's constructor called in placement new
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
yeputons
</td>
</tr>
</table>
<pre>
Consider the following code:
```c++
#include <iostream>
#include <memory>
#include <string>
int main() {
char buf[sizeof(std::string)];
new (&buf) std::string(1000, 'x');
struct Foo { Foo() { new int(1000); } };
char buf2[sizeof(Foo)];
new (&buf2) Foo();
std::cout << buf[0] << buf2[0] << "\n";
}
```
It leaks memory in two objects which are placement-new allocated in `buf` and `buf2` respectively.
When compiled with g++ 10 on Ubuntu 20.04 on my machine (or [trunk versions of gcc/clang on Godbolt](https://godbolt.org/z/ebMn35c57)) like `g++-10 x.cpp -fsanitize=address -fno-omit-frame-pointer -g -o x` it prints:
```
=================================================================
==553==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1001 byte(s) in 1 object(s) allocated from:
#0 0x7f3c9f394f27 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
#1 0x7f3c9f243f7b in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct(unsigned long, char) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x142f7b)
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f3c9f394f27 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
#1 0x55ea7ab7e3bf in Foo /home/yeputons/x.cpp:9
#2 0x55ea7ab7e536 in main /home/yeputons/x.cpp:11
#3 0x7f3c9edc90b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
SUMMARY: AddressSanitizer: 1005 byte(s) leaked in 2 allocation(s).
```
Both leaks are detected correctly. However, for the first one (when `std::string` is constructed by placement new) the stack trace is aborted on `std::string`'s constructor and does not go further to placement new. Adding `-f
I'd expect that the first stack trace ends with `x.cpp:6` and `__libc_start_main`, like the second one.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzdVktv4zYQ_jXyhZAgUa_o4EPWXrcFGhTIYlH0ZFAkZbGRSYOkYnt_fWck2Za9m-25DWQpfH3z-maGtRHn5cpop4S0xLeSNKbrzFHpHeFGyCB9DuJ1EF_eRTw-PKCf8Blnaao073ohSZCulHHeSrYP0s8_Wt7LvbHnDxbhJEi-LQ5vpT3ZM6UD-hTQigTlJJbAH2-ZJXXfBPknp75J08Am5wWqnT5PaLQK8nWQzk5peSQDWoFHAfO7I09JHMcBXcG28gQ_BLkg3HBgd8892RiDWuH3puMgBFS_YiEALKzxd6fNxQY6N2LA-rniFCVdZf5QvckqbnqP7oVnclYMyLMZ-jAVUJhZafxcYUHrew7Mxf3mSSfZmyNjeMFw4o-GmPpvyb0jx1bxljAryaFjXO6l9iHawoBrnHkp8ABAonJFTJgW04ji0Ep3ABj1LrtzNJf6Zys10HR_UB1AHJVvyW4kJkliYjT5Wvfa94TGUZzheH8GJvFWaYluNJaA3RBD_UbepXUK8oCYhuw40HvDOwZJAId-MaI2ncdY0KfW-4NDr9INPLtxKTIW5G6-wU_WLzrNeT4wBuLTqTeJtkx6haDXKeKHAwkbx7TyEO8gXTMhwEgHk9qEZq982Fi2l-HBAIMgMcMdCQ05oTOUJwfgqHcfpeY0TNf_-WdmSJ6n4z-fX1__eAXTye9Aty-TBy1OCOmBJMCDiYIDH-ceWisLG4Z5jDJkZULqs5dYMjBUQMFkYuxl6sbPxpr91eOYXFC4YhKfyiblVZNWWUNLRDAHaZkHZgG9AaWHyrrTcL4zQyUiUQQkeXg5i3zrVO2u9tANg8H02QLWVsgODETqgBpVdadIclWEZmlT1qjINfm3W346Jck4qJlTfHspsyssPVjlbpUCJrbeMoX8GpehGM93TC4x9rZOcM8o62XLIYmGsvi99SsyyqvGGoYWw_v0VGyLLOyU7k_hTveTK7yYekzkTFTANz4lGQXjMLE-jmr2PwppnktWsrqUad2gIkOfoZvW7MHAzVkeeg_ORhdeMO4g6BwiTwuEwD76cwxgyhwkvThECl7FNUWQ7RYMQxYx67cT4r_Fk9_CSDPAeYjil68vL8-vf2EeP4-18C63IVfzu8BiuMeuQS8Rheo9rUY_aVSfDDSJsVVhO7oWDW4s8ggaDPnVHOW7HPKiMdOlSFnnoRcMbeOIXQdgHy8NWJwdufIfQOvzrd-N7KkGOPAcfyOQZlziEVYbi9vNB7Bw_5jhgkrYH4WRjmjjyc6QprcAC6qae3kROhOvcgASNnf9GjAFkSfsq6AS8zMz59pJLdzYWAHiQpFi1qO_48Kg72rse4OtEjRH22S0EMtUVGnFFl75Ti7vSvjNoF7D9VNMatSyHQcPF7QHj3AgwciHOwcsetstH1o2GNPXEdwakJjd--UTHqwZ68RGOddLzIk8q8py0S5lVbKmZCxJKad1wqq4yGUhILcqURVFuehYLTu3hNsEXJmGix9CDLeo9UItaUxpnCVVkmRFmkU0FUVZZXnWVE-xyOogiyW4rotQD7xLLOxyUKnudw4WO-W8uy0yNxQgOYgDfNb71tjlJZcXg-zloPs_k59_oA">