You don't check the iterator returned from connect
: Live Segfault. Adding sanitizers (-fsanitize=address,undefined
) shows:
/usr/include/c++/10/bits/shared_ptr_base.h:1011:16: runtime error: reference binding to null pointer of type 'struct element_type'
/home/sehe/custom/boost_1_76_0/boost/asio/ip/basic_resolver_iterator.hpp:179:22: runtime error: member call on null pointer of type 'struct element_type'
/usr/include/c++/10/bits/stl_vector.h:1046:25: runtime error: member access within null pointer of type 'struct vector'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==25930==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x559d1ad6064f bp 0x7ffc84f479e0 sp 0x7ffc84f479c0 T0)
==25930==The signal is caused by a READ memory access.
==25930==Hint: address points to the zero page.
#0 0x559d1ad6064f in std::vector<boost::asio::ip::basic_resolver_entry<boost::asio::ip::tcp>, std::allocator<boost::asio::ip::basic_resolver_entry<boost::asio::ip::tcp> > >::operator[](unsigned long) /usr/include/c++/10/bits/stl_vector.h:1046
#1 0x559d1ad58b37 in boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp>::dereference() const /home/sehe/custom/boost_1_76_0/boost/asio/ip/basic_resolver_iterator.hpp:179
#2 0x559d1ad4e06e in boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp>::operator*() const /home/sehe/custom/boost_1_76_0/boost/asio/ip/basic_resolver_iterator.hpp:119
#3 0x559d1ad046cf in foo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned short) /home/sehe/Projects/stackoverflow/test.cpp:21
#4 0x559d1ad04dd5 in main /home/sehe/Projects/stackoverflow/test.cpp:29
#5 0x7fcf47a76bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
#6 0x559d1ad03f29 in _start (/home/sehe/Projects/stackoverflow/sotest+0xd3f29)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/include/c++/10/bits/stl_vector.h:1046 in std::vector<boost::asio::ip::basic_resolver_entry<boost::asio::ip::tcp>, std::allocator<boost::asio::ip::basic_resolver_entry<boost::asio::ip::tcp> > >::operator[](unsigned long)
==25930==ABORTING
Simply add the check:
if (it != endpoints.end()) {
m_endpoint = *it;
}
Other Simplifications
All of the above can be - safely - summarized as
tcp::socket _socket(io);
tcp::endpoint m_endpoint = boost::asio::connect(
_socket, tcp::resolver{io}.resolve(ip_address, std::to_string(port)),
ec);
Live again: Live On Coliru
#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::tcp;
void foo(std::string const& ip_address, uint16_t port)
{
boost::asio::io_context io;
boost::system::error_code ec;
tcp::socket _socket(io);
tcp::endpoint m_endpoint = boost::asio::connect(
_socket, tcp::resolver{io}.resolve(ip_address, std::to_string(port)),
ec);
std::cout << ec.message() << " Connected to " << m_endpoint << "\n";
}
int main() {
foo("127.0.0.1", 7979);
}
Prints
Success Connected to 127.0.0.1:7979