Closed lijh8 closed 1 year ago
I turn on address sanitizer on debug and it reports heap-use-after-free on boost::asio::buffer() on server side.
boost::asio::buffer()
But I do not see increasing memory usage in server side in top command when I turn off address sanitizer. Do not know if it is false report.
boost::asio::async_write(socket, boost::asio::buffer(msg + (std::to_string(cnt++) + "\n").c_str()), [this, self](boost::system::error_code ec, std::size_t /*length*/) { if (!ec) { handle_write(ec); } else { std::cout << ec.message() << "\n"; } });
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 595 Debian-+ 20 0 15.1m 8.8m 7.3m S 0.0 0.2 0:00.11 /lib/systemd/systemd --user 1021 ljh 20 0 15.1m 8.9m 7.4m S 0.0 0.2 0:00.17 /lib/systemd/systemd --user 1417 ljh 20 0 5.7m 1.5m 1.4m R 48.5 0.0 6:32.56 ./build/server 9995 1449 ljh 20 0 5.7m 1.5m 1.4m S 14.5 0.0 2:20.46 ./build/client 192.168.1.4 9995 bbb 1419 ljh 20 0 5.7m 1.5m 1.4m S 17.5 0.0 3:28.82 ./build/client 192.168.1.4 9995 aaa 1050 ljh 20 0 15.8m 5.1m 3.4m S 0.0 0.1 0:00.08 -bash 1257 ljh 20 0 15.8m 5.2m 3.5m S 0.0 0.1 0:00.03 -bash
// server.cpp // ./boost_1_81_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp #include <cstdlib> #include <iostream> #include <memory> #include <utility> #include <boost/asio.hpp> #include <sanitizer/lsan_interface.h> using boost::asio::ip::tcp; void handlerCont(int signum){ if (signum == SIGCONT) { printf("Got SIGCONT\n"); } #ifndef NDEBUG __lsan_do_recoverable_leak_check(); #endif } struct session : public std::enable_shared_from_this<session> { session(tcp::socket socket) : socket(std::move(socket)) { } void start() { start_read(); start_write(); } void start_read() { auto self(shared_from_this()); memset(data, 0, sizeof(data)); socket.async_read_some(boost::asio::buffer(data, max_length), [this, self](boost::system::error_code ec, std::size_t length) { if (!ec) { handle_read(ec, length); } else { std::cout << ec.message() << "\n"; } }); } void handle_read(const boost::system::error_code& error, std::size_t n) { if (!error) { std::cout << data; start_read(); } else { std::cout << error.message() << "\n"; } } void start_write() { auto self(shared_from_this()); boost::asio::async_write(socket, boost::asio::buffer(msg + (std::to_string(cnt++) + "\n").c_str()), [this, self](boost::system::error_code ec, std::size_t /*length*/) { if (!ec) { handle_write(ec); } else { std::cout << ec.message() << "\n"; } }); } void handle_write(const boost::system::error_code& error) { if (!error) { // sleep(1); //test start_write(); } else { std::cout << error.message() << "\n"; } } tcp::socket socket; enum { max_length = 1024 }; char data[max_length]; std::string msg = "hello client "; size_t cnt = 0; }; struct server { server(boost::asio::io_context& io_context, short port) : acceptor(io_context, tcp::endpoint(tcp::v4(), port)) { std::cout << "listen on port: " << port << " \n"; do_accept(); } void do_accept() { acceptor.async_accept( [this](boost::system::error_code ec, tcp::socket socket) { if (!ec) { std::cout << "accept connection: " << socket.remote_endpoint() << "\n"; std::make_shared<session>(std::move(socket))->start(); } else { std::cout << ec.message() << ", " << socket.remote_endpoint() << "\n"; } do_accept(); }); } tcp::acceptor acceptor; }; int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: server <port>\n"; return 1; } signal(SIGCONT, handlerCont); // $ man 7 signal boost::asio::io_context io_context; server s(io_context, std::atoi(argv[1])); io_context.run(); return 0; }
//client.cpp // ./boost_1_81_0/doc/html/boost_asio/example/cpp11/timeouts/async_tcp_client.cpp #include <boost/asio/buffer.hpp> #include <boost/asio/io_context.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/read_until.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/asio/write.hpp> #include <functional> #include <iostream> #include <string> #include <sanitizer/lsan_interface.h> using boost::asio::steady_timer; using boost::asio::ip::tcp; using std::placeholders::_1; using std::placeholders::_2; void handlerCont(int signum){ if (signum == SIGCONT) { printf("Got SIGCONT\n"); } #ifndef NDEBUG __lsan_do_recoverable_leak_check(); #endif } struct client { client(boost::asio::io_context& io_context) : socket(io_context) { } void start(tcp::resolver::results_type endpoints, const std::string& msg) { endpoints_ = endpoints; msg_ = msg; start_connect(endpoints_.begin()); } void start_connect(tcp::resolver::results_type::iterator endpoint_iter) { if (endpoint_iter != endpoints_.end()) { socket.async_connect(endpoint_iter->endpoint(), std::bind(&client::handle_connect, this, _1, endpoint_iter)); } } void handle_connect(const boost::system::error_code& error, tcp::resolver::results_type::iterator endpoint_iter) { if (!socket.is_open()) { std::cout << "Connect timed out\n"; start_connect(++endpoint_iter); } else if (error) { std::cout << "Connect error: " << error.message() << "\n"; socket.close(); start_connect(++endpoint_iter); } else { std::cout << "Connected to " << endpoint_iter->endpoint() << "\n"; //do not have to write before read start_write(); start_read(); } } void start_write() { boost::asio::async_write(socket, boost::asio::buffer("hello server " + msg_ + " " + std::to_string(cnt++) + "\n"), std::bind(&client::handle_write, this, _1)); } void handle_write(const boost::system::error_code& error) { if (!error) { // sleep(1); //test start_write(); } else { std::cout << error.message() << "\n"; } } void start_read() { boost::asio::async_read_until(socket, boost::asio::dynamic_buffer(input_buffer), '\n', std::bind(&client::handle_read, this, _1, _2)); } void handle_read(const boost::system::error_code& error, std::size_t n) { if (!error) { std::string line(input_buffer.substr(0, n - 1)); input_buffer.erase(0, n); if (!line.empty()) { std::cout << line << "\n"; } start_read(); } else { std::cout << error.message() << "\n"; } } tcp::resolver::results_type endpoints_; tcp::socket socket; std::string input_buffer; std::string msg_; size_t cnt = 0; }; int main(int argc, char* argv[]) { if (argc != 4) { std::cerr << "Usage: client <host> <port> <msg>\n"; return 1; } signal(SIGCONT, handlerCont); // $ man 7 signal boost::asio::io_context io_context; tcp::resolver r(io_context); client c(io_context); c.start(r.resolve(argv[1], argv[2]), argv[3]); io_context.run(); return 0; }
================================================================= ==1271==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000fa3a80 at pc 0x7eff5cc8a1ff bp 0x7fffe5826d70 sp 0x7fffe5826520 READ of size 20 at 0x603000fa3a80 thread T0 #0 0x7eff5cc8a1fe in __interceptor_send ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6439 #1 0x55a4f9e1024f in boost::asio::detail::socket_ops::send1(int, void const*, unsigned long, int, boost::system::error_code&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/socket_ops.ipp:1426 #2 0x55a4f9e1037a in boost::asio::detail::socket_ops::non_blocking_send1(int, void const*, unsigned long, int, boost::system::error_code&, unsigned long&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/socket_ops.ipp:1569 #3 0x55a4f9e382f8 in boost::asio::detail::reactive_socket_send_op_base<boost::asio::const_buffers_1>::do_perform(boost::asio::detail::reactor_op*) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/reactive_socket_send_op.hpp:63 #4 0x55a4f9e05709 in boost::asio::detail::reactor_op::perform() /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/reactor_op.hpp:47 #5 0x55a4f9e0b52a in boost::asio::detail::epoll_reactor::descriptor_state::perform_io(unsigned int) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/epoll_reactor.ipp:773 #6 0x55a4f9e0b756 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/epoll_reactor.ipp:804 #7 0x55a4f9e030ea in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/scheduler_operation.hpp:40 #8 0x55a4f9e0de08 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/scheduler.ipp:492 #9 0x55a4f9e0d0d4 in boost::asio::detail::scheduler::run(boost::system::error_code&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/scheduler.ipp:210 #10 0x55a4f9e0e800 in boost::asio::io_context::run() /home/ljh/Downloads/boost_1_81_0/boost/asio/impl/io_context.ipp:63 #11 0x55a4f9dfac21 in main /home/ljh/Documents/hello_asio/src/server.cpp:120 #12 0x7eff5c87bd09 in __libc_start_main ../csu/libc-start.c:308 #13 0x55a4f9dfa9d9 in _start (/home/ljh/Documents/hello_asio/src/build/server+0xa9d9) 0x603000fa3a80 is located 0 bytes inside of 31-byte region [0x603000fa3a80,0x603000fa3a9f) freed by thread T0 here: #0 0x7eff5cce2017 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:160 #1 0x55a4f9e1738a in session::start_write() /home/ljh/Documents/hello_asio/src/server.cpp:58 #2 0x55a4f9e17680 in session::handle_write(boost::system::error_code const&) /home/ljh/Documents/hello_asio/src/server.cpp:72 #3 0x55a4f9e16e6a in session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}::operator()(boost::system::error_code, unsigned long) const /home/ljh/Documents/hello_asio/src/server.cpp:62 #4 0x55a4f9e27058 in boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>::operator()(boost::system::error_code, unsigned long, int) /home/ljh/Downloads/boost_1_81_0/boost/asio/impl/write.hpp:362 #5 0x55a4f9e3a417 in boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>::operator()() /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/bind_handler.hpp:289 #6 0x55a4f9e39eaf in void boost::asio::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>&, ...) /home/ljh/Downloads/boost_1_81_0/boost/asio/handler_invoke_hook.hpp:88 #7 0x55a4f9e399e1 in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>, {lambda(boost::system::error_code, unsigned long)#1}>(boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>&, {lambda(boost::system::error_code, unsigned long)#1}&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/handler_invoke_helpers.hpp:54 #8 0x55a4f9e397ea in void boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, {lambda(boost::system::error_code, unsigned long)#1}>(boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>&, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, {lambda(boost::system::error_code, unsigned long)#1}>*) /home/ljh/Downloads/boost_1_81_0/boost/asio/impl/write.hpp:430 #9 0x55a4f9e39053 in void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>(boost::asio::detail::binder2<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::system::error_code, unsigned long>&, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/handler_invoke_helpers.hpp:54 #10 0x55a4f9e380b3 in void boost::asio::detail::handler_work<boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::asio::any_io_executor, void>::complete<boost::asio::detail::binder2<session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}, boost::system::error_code, unsigned long>&, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/handler_work.hpp:520 #11 0x55a4f9e36209 in boost::asio::detail::reactive_socket_send_op<boost::asio::const_buffers_1, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, boost::asio::const_buffers_1, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, session::start_write()::{lambda(boost::system::error_code, unsigned long)#1}>, boost::asio::any_io_executor>::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/reactive_socket_send_op.hpp:150 #12 0x55a4f9e030ea in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/scheduler_operation.hpp:40 #13 0x55a4f9e0de08 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/scheduler.ipp:492 #14 0x55a4f9e0d0d4 in boost::asio::detail::scheduler::run(boost::system::error_code&) /home/ljh/Downloads/boost_1_81_0/boost/asio/detail/impl/scheduler.ipp:210 #15 0x55a4f9e0e800 in boost::asio::io_context::run() /home/ljh/Downloads/boost_1_81_0/boost/asio/impl/io_context.ipp:63 #16 0x55a4f9dfac21 in main /home/ljh/Documents/hello_asio/src/server.cpp:120 #17 0x7eff5c87bd09 in __libc_start_main ../csu/libc-start.c:308 previously allocated by thread T0 here: #0 0x7eff5cce1647 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99 #1 0x7eff5cb7a859 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x133859) SUMMARY: AddressSanitizer: heap-use-after-free ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6439 in __interceptor_send
sorry, i used the buffer incorrectly
I turn on address sanitizer on debug and it reports heap-use-after-free on
boost::asio::buffer()
on server side.But I do not see increasing memory usage in server side in top command when I turn off address sanitizer. Do not know if it is false report.