1

I tried to compile a project but it failed with the following error:

Build Error

Below is the code in my project:

boost::system::error_code ec;

auto endpoints = resolver->resolver().resolve(ip_address, std::to_string(port)), ec);

if (ec)
    return;

// Connect to server
boost::asio::ip::tcp::endpoint m_endpoint;
m_endpoint = *(boost::asio::connect(_socket, endpoints.begin(), endpoints.end(), ec));

The problem occurs in the call to boost::asio::connect function. By the way, I am using Boost C++ Libraries v1.77 and GCC 11.2.0.

How should I rectify this error? Thanks.

Hung Law
  • 11
  • 1

1 Answers1

0

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
sehe
  • 374,641
  • 47
  • 450
  • 633
  • I've since found your screenshot - that might be an issue related to conecpt checking. Yu can probably disable some of these with some define, or you can silence the warning with some compiler #pragma. I expect these to go away soon - with either a new version of the compiler or boost - they're clearly unintended diagnostics. – sehe Oct 14 '21 at 10:45
  • Hi sehe, thanks for your answer. Finally I solved the problem by adding "#pragma GCC system_header" in the header file. – Hung Law Oct 18 '21 at 00:02
  • What header? If the boost header,. why not simply specify the include directory as system? So `-isystem path` instead of `-I path` – sehe Oct 18 '21 at 00:05