drogonframework / drogonframework/drogon
drogon_ctl press: possible double free in multithreaded mode if destination unreachable
- Dominant language
- C++
- Stars
- 14.3k
- Forks
- 1.4k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 15
Description
**To Reproduce**
```bash
drogon_ctl press -n 10000 -c 100 -t 4 -q "http://${unreachable_domain_or_IP}"
```
Output with backtrace
```txt
Too many errors
Too many errors
Too many errors
Too many errors
=================================================================
==77435==ERROR: AddressSanitizer: attempting double-free on 0x619000001980 in thread T3 (EventLoopThread):
#0 0x7f996cde6f19 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x7f996c317552 in __run_exit_handlers (/usr/lib/libc.so.6+0x3f552)
#2 0x7f996c31764d in exit (/usr/lib/libc.so.6+0x3f64d)
#3 0x55a4e878ea5c in outputErrorAndExit(std::basic_string_view > const&) /usr/src/my_project/drogon/drogon_ctl/press.cc:43
#4 0x55a4e87909b1 in operator() /usr/src/my_project/drogon/drogon_ctl/press.cc:255
#5 0x55a4e8792815 in __invoke_impl&, drogon::ReqResult, const std::shared_ptr&> /usr/include/c++/11.1.0/bits/invoke.h:61
#6 0x55a4e8792497 in __invoke_r&, drogon::ReqResult, const std::shared_ptr&> /usr/include/c++/11.1.0/bits/invoke.h:111
#7 0x55a4e8791fe0 in _M_invoke /usr/include/c++/11.1.0/bits/std_function.h:291
#8 0x55a4e885b428 in std::function const&)>::operator()(drogon::ReqResult, std::shared_ptr const&) const (/home/user/.local/bin/drogon_ctl+0x22d428)
#9 0x55a4e8849aad in operator() /usr/src/my_project/drogon/lib/src/HttpClientImpl.cc:348
#10 0x55a4e8854bbd in __invoke_impl&, drogon::ReqResult, const std::shared_ptr&> /usr/include/c++/11.1.0/bits/invoke.h:61
#11 0x55a4e8853e07 in __invoke_r&, drogon::ReqResult, const std::shared_ptr&> /usr/include/c++/11.1.0/bits/invoke.h:111
#12 0x55a4e885222a in _M_invoke /usr/include/c++/11.1.0/bits/std_function.h:291
#13 0x55a4e885b428 in std::function const&)>::operator()(drogon::ReqResult, std::shared_ptr const&) const (/home/user/.local/bin/drogon_ctl+0x22d428)
#14 0x55a4e884e4ed in drogon::HttpClientImpl::onError(drogon::ReqResult) /usr/src/my_project/drogon/lib/src/HttpClientImpl.cc:618
#15 0x55a4e884440a in operator() /usr/src/my_project/drogon/lib/src/HttpClientImpl.cc:99
#16 0x55a4e8852eeb in __invoke_impl&> /usr/include/c++/11.1.0/bits/invoke.h:61
#17 0x55a4e885105f in __invoke_r&> /usr/include/c++/11.1.0/bits/invoke.h:111
#18 0x55a4e884fdb8 in _M_invoke /usr/include/c++/11.1.0/bits/std_function.h:291
#19 0x55a4e88bcd05 in std::function::operator()() const /usr/include/c++/11.1.0/bits/std_function.h:560
#20 0x55a4e8a4d549 in operator() /usr/src/my_project/drogon/trantor/trantor/net/TcpClient.cc:71
#21 0x55a4e8a5203f in __invoke_impl&> /usr/include/c++/11.1.0/bits/invoke.h:61
#22 0x55a4e8a51736 in __invoke_r&> /usr/include/c++/11.1.0/bits/invoke.h:154
#23 0x55a4e8a510c1 in _M_invoke /usr/include/c++/11.1.0/bits/std_function.h:291
#24 0x55a4e88bcd05 in std::function::operator()() const /usr/include/c++/11.1.0/bits/std_function.h:560
#25 0x55a4e8a76613 in trantor::Connector::handleError() /usr/src/my_project/drogon/trantor/trantor/net/inner/Connector.cc:232
#26 0x55a4e8a79f0f in void std::__invoke_impl&>(std::__invoke_memfun_deref, void (trantor::Connector::*&)(), std::shared_ptr&) /usr/include/c++/11.1.0/bits/invoke.h:74
#27 0x55a4e8a79dba in std::__invoke_result&>::type std::__invoke&>(void (trantor::Connector::*&)(), std::shared_ptr&) /usr/include/c++/11.1.0/bits/invoke.h:96
#28 0x55a4e8a79cf1 in void std::_Bind))()>::__call(std::tuple<>&&, std::_Index_tuple<0ul>) /usr/include/c++/11.1.0/functional:420
#29 0x55a4e8a79bb0 in void std::_Bind))()>::operator()<, void>() (/home/user/.local/bin/drogon_ctl+0x44bbb0)
#30 0x55a4e8a797f9 in void std::__invoke_impl))()>&>(std::__invoke_other, std::_Bind))()>&) /usr/include/c++/11.1.0/bits/invoke.h:61
#31 0x55a4e8a795a4 in std::enable_if, std::__is_invocable))()>&> >::value, void>::type std::__invoke_r))()>&>(std::_Bind))()>&) /usr/include/c++/11.1.0/bits/invoke.h:154
#32 0x55a4e8a7900c in std::_Function_handler))()> >::_M_invoke(std::_Any_data const&) (/home/user/.local/bin/drogon_ctl+0x44b00c)
#33 0x55a4e88bcd05 in std::function::operator()() const /usr/include/c++/11.1.0/bits/std_function.h:560
#34 0x55a4e8a715af in trantor::Channel::handleEventSafely() /usr/src/my_project/drogon/trantor/trantor/net/Channel.cc:80
#35 0x55a4e8a71490 in trantor::Channel::handleEvent() /usr/src/my_project/drogon/trantor/trantor/net/Channel.cc:66
#36 0x55a4e8a3e41a in trantor::EventLoop::loop() /usr/src/my_project/drogon/trantor/trantor/net/EventLoop.cc:190
#37 0x55a4e8a451d6 in trantor::EventLoopThread::loopFuncs() /usr/src/my_project/drogon/trantor/trantor/net/EventLoopThread.cc:60
#38 0x55a4e8a449b5 in operator() /usr/src/my_project/drogon/trantor/trantor/net/EventLoopThread.cc:25
#39 0x55a4e8a4652f in __invoke_impl > /usr/include/c++/11.1.0/bits/invoke.h:61
#40 0x55a4e8a464e4 in __invoke > /usr/include/c++/11.1.0/bits/invoke.h:96
#41 0x55a4e8a46491 in _M_invoke<0> /usr/include/c++/11.1.0/bits/std_thread.h:253
#42 0x55a4e8a46465 in operator() /usr/include/c++/11.1.0/bits/std_thread.h:260
#43 0x55a4e8a46449 in _M_run /usr/include/c++/11.1.0/bits/std_thread.h:211
#44 0x7f996c6e33c3 in execute_native_thread_routine /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82
#45 0x7f996c979258 in start_thread (/usr/lib/libpthread.so.0+0x9258)
#46 0x7f996c3d65e2 in __GI___clone (/usr/lib/libc.so.6+0xfe5e2)
0x619000001980 is located 0 bytes inside of 1040-byte region [0x619000001980,0x619000001d90)
freed by thread T2 (EventLoopThread) here:
#0 0x7f996cde6f19 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x7f996c317552 in __run_exit_handlers (/usr/lib/libc.so.6+0x3f552)
previously allocated by thread T0 here:
#0 0x7f996cde7459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x7f996c317831 in __new_exitfn (/usr/lib/libc.so.6+0x3f831)
Thread T3 (EventLoopThread) created by T0 here:
#0 0x7f996cd88fa7 in __interceptor_pthread_create /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:216
#1 0x7f996c6e36aa in std::thread::_M_start_thread(std::unique_ptr >, void (*)()) /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
#2 0x55a4e8a44b4f in trantor::EventLoopThread::EventLoopThread(std::__cxx11::basic_string, std::allocator > const&) /usr/src/my_project/drogon/trantor/trantor/net/EventLoopThread.cc:25
#3 0x55a4e8a4b23a in void __gnu_cxx::new_allocator::construct, std::allocator > const&>(trantor::EventLoopThread*, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/ext/new_allocator.h:156
#4 0x55a4e8a4afb0 in void std::allocator_traits >::construct, std::allocator > const&>(std::allocator&, trantor::EventLoopThread*, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/alloc_traits.h:512
#5 0x55a4e8a4aa5d in std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace, std::allocator > const&>(std::allocator, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr_base.h:519
#6 0x55a4e8a4a238 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count, std::__cxx11::basic_string, std::allocator > const&>(trantor::EventLoopThread*&, std::_Sp_alloc_shared_tag >, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr_base.h:650
#7 0x55a4e8a49ce5 in std::__shared_ptr::__shared_ptr, std::__cxx11::basic_string, std::allocator > const&>(std::_Sp_alloc_shared_tag >, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr_base.h:1337
#8 0x55a4e8a49a48 in std::shared_ptr::shared_ptr, std::__cxx11::basic_string, std::allocator > const&>(std::_Sp_alloc_shared_tag >, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr.h:409
#9 0x55a4e8a490b5 in std::shared_ptr std::allocate_shared, std::__cxx11::basic_string, std::allocator > const&>(std::allocator const&, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr.h:861
#10 0x55a4e8a48b41 in std::shared_ptr std::make_shared, std::allocator > const&>(std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr.h:877
#11 0x55a4e8a48435 in trantor::EventLoopThreadPool::EventLoopThreadPool(unsigned long, std::__cxx11::basic_string, std::allocator > const&) /usr/src/my_project/drogon/trantor/trantor/net/EventLoopThreadPool.cc:23
#12 0x55a4e8794f75 in std::_MakeUniq::__single_object std::make_unique(unsigned long&) (/home/user/.local/bin/drogon_ctl+0x166f75)
#13 0x55a4e8790268 in drogon_ctl::press::createRequestAndClients() /usr/src/my_project/drogon/drogon_ctl/press.cc:213
#14 0x55a4e878feda in drogon_ctl::press::doTesting() /usr/src/my_project/drogon/drogon_ctl/press.cc:198
#15 0x55a4e878f94c in drogon_ctl::press::handleCommand(std::vector, std::allocator >, std::allocator, std::allocator > > >&) /usr/src/my_project/drogon/drogon_ctl/press.cc:193
#16 0x55a4e86e5287 in exeCommand(std::vector, std::allocator >, std::allocator, std::allocator > > >&) /usr/src/my_project/drogon/drogon_ctl/cmd.cc:43
#17 0x55a4e878d62e in main /usr/src/my_project/drogon/drogon_ctl/main.cc:46
#18 0x7f996c2ffb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
Thread T2 (EventLoopThread) created by T0 here:
#0 0x7f996cd88fa7 in __interceptor_pthread_create /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:216
#1 0x7f996c6e36aa in std::thread::_M_start_thread(std::unique_ptr >, void (*)()) /build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
#2 0x55a4e8a44b4f in trantor::EventLoopThread::EventLoopThread(std::__cxx11::basic_string, std::allocator > const&) /usr/src/my_project/drogon/trantor/trantor/net/EventLoopThread.cc:25
#3 0x55a4e8a4b23a in void __gnu_cxx::new_allocator::construct, std::allocator > const&>(trantor::EventLoopThread*, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/ext/new_allocator.h:156
#4 0x55a4e8a4afb0 in void std::allocator_traits >::construct, std::allocator > const&>(std::allocator&, trantor::EventLoopThread*, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/alloc_traits.h:512
#5 0x55a4e8a4aa5d in std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace, std::allocator > const&>(std::allocator, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr_base.h:519
#6 0x55a4e8a4a238 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count, std::__cxx11::basic_string, std::allocator > const&>(trantor::EventLoopThread*&, std::_Sp_alloc_shared_tag >, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr_base.h:650
#7 0x55a4e8a49ce5 in std::__shared_ptr::__shared_ptr, std::__cxx11::basic_string, std::allocator > const&>(std::_Sp_alloc_shared_tag >, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr_base.h:1337
#8 0x55a4e8a49a48 in std::shared_ptr::shared_ptr, std::__cxx11::basic_string, std::allocator > const&>(std::_Sp_alloc_shared_tag >, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr.h:409
#9 0x55a4e8a490b5 in std::shared_ptr std::allocate_shared, std::__cxx11::basic_string, std::allocator > const&>(std::allocator const&, std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr.h:861
#10 0x55a4e8a48b41 in std::shared_ptr std::make_shared, std::allocator > const&>(std::__cxx11::basic_string, std::allocator > const&) /usr/include/c++/11.1.0/bits/shared_ptr.h:877
#11 0x55a4e8a48435 in trantor::EventLoopThreadPool::EventLoopThreadPool(unsigned long, std::__cxx11::basic_string, std::allocator > const&) /usr/src/my_project/drogon/trantor/trantor/net/EventLoopThreadPool.cc:23
#12 0x55a4e8794f75 in std::_MakeUniq::__single_object std::make_unique(unsigned long&) (/home/user/.local/bin/drogon_ctl+0x166f75)
#13 0x55a4e8790268 in drogon_ctl::press::createRequestAndClients() /usr/src/my_project/drogon/drogon_ctl/press.cc:213
#14 0x55a4e878feda in drogon_ctl::press::doTesting() /usr/src/my_project/drogon/drogon_ctl/press.cc:198
#15 0x55a4e878f94c in drogon_ctl::press::handleCommand(std::vector, std::allocator >, std::allocator, std::allocator > > >&) /usr/src/my_project/drogon/drogon_ctl/press.cc:193
#16 0x55a4e86e5287 in exeCommand(std::vector, std::allocator >, std::allocator, std::allocator > > >&) /usr/src/my_project/drogon/drogon_ctl/cmd.cc:43
#17 0x55a4e878d62e in main /usr/src/my_project/drogon/drogon_ctl/main.cc:46
#18 0x7f996c2ffb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
SUMMARY: AddressSanitizer: double-free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127 in __interceptor_free
==77435==ABORTING
```
**Expected behavior**
Correct program termination with error description.
**Desktop (please complete the following information):**
- OS: ArchLinux
- amd64 quad core laptop
```console
~$ drogon_ctl -v
_
__| |_ __ ___ __ _ ___ _ __
/ _` | '__/ _ \ / _` |/ _ \| '_ \
| (_| | | | (_) | (_| | (_) | | | |
\__,_|_| \___/ \__, |\___/|_| |_|
|___/
A utility for drogon
Version: 1.7.2
Git commit: 3fd9d88dc0e44186f09c08c1e490ddb05ed54eae
Compilation:
Compiler: /usr/bin/c++
Compiler ID: GNU
Compilation flags: -g -fno-omit-frame-pointer -fsanitize=leak -fsanitize=address -std=c++17 -I/usr/include -I/home/user/.local/include
Libraries:
postgresql: no (batch mode: no)
mariadb: no
sqlite3: no
openssl: yes
brotli: yes
boost: no
hiredis: no
c-ares: yes
```
**Additional context**
P.S. ___Too many errors___ - not very speaking error. I got it even with a single request, when server instance was started explicitly on an _IPv6 address_, but the destination for `drogon_ctl` is set to _localhost_. When using curl this request passed.
Contributor guide
Assessment
This issue has not been assessed yet.