Libboost :: resolver получил SIGABRT - PullRequest
0 голосов
/ 13 июня 2018

Я нашел следующий код для получения локальных IP-адресов с помощью libboost.Я использую libboost-1.65.

#include <iostream>
#include <boost/asio.hpp>

std::string getHostIP ()
{
    using boost::asio::ip::tcp;    

    boost::asio::io_service io_service;
    tcp::resolver resolver(io_service);
    std::cout << boost::asio::ip::host_name() << std::endl;
    tcp::resolver::query query(boost::asio::ip::host_name(), "");
    tcp::resolver::iterator iter = resolver.resolve(query);
    tcp::resolver::iterator end; // End marker.
    while (iter != end)
    {
         tcp::endpoint ep = *iter++;
         std::cout << ep << std::endl;
    }
}

int main() {
    getHostIP();
}

В настоящее время я получаю вывод

daniel-XVirtualBox
127.0.1.1:0
free(): invalid size
Aborted (core dumped)

Правильно указано имя хоста и IP-адрес локального хоста.Я знаю, что на компьютере имеется несколько интерфейсов, и этот запрос может возвращать любое их количество, но я не вижу двух других интерфейсов, подключенных к компьютеру.Я также добавлю вывод ifconfig .

Однако мой вопрос касается бита "free (): недопустимый размер".GDB дополнительно говорит об этом:

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.

***Backtrace***
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff705a801 in __GI_abort () at abort.c:79
#2  0x00007ffff70a3897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff71d0b9a "%s\n")
    at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff70aa90a in malloc_printerr (str=str@entry=0x7ffff71ceda0 "free(): invalid size") at malloc.c:5350
#4  0x00007ffff70b1e2c in _int_free (have_lock=0, p=0x7ffff7de5990 <_dl_init+864>, av=0x7ffff7405c40 <main_arena>)
    at malloc.c:4161
#5  __GI___libc_free (mem=0x7ffff7de59a0 <_dl_fini>) at malloc.c:3124
#6  0x0000555555559111 in main () at boost_gethostname.cpp:22

Существует ли процедура очистки для boost :: asio :: io_service, которую мне не хватает?Должен ли распознаватель быть остановлен?А также, почему я не вижу все интерфейсы на компьютере?

Спасибо!

ifconfig: 
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::ecd6:f288:3b03:d8cf  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:37:63:98  txqueuelen 1000  (Ethernet)
        RX packets 114124  bytes 111705475 (111.7 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42644  bytes 3732986 (3.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.11.221  netmask 255.255.255.0  broadcast 10.10.11.255
        inet6 fe80::3aa2:ecbd:5702:2ab4  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:a6:44:ce  txqueuelen 1000  (Ethernet)
        RX packets 194194  bytes 24826176 (24.8 MB)
        RX errors 0  dropped 7354  overruns 0  frame 0
        TX packets 1189  bytes 127853 (127.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 912  bytes 76283 (76.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 912  bytes 76283 (76.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

В дополнение к ответу @andreee, всегда компилирует ваш код с помощью -Wall -Wextra -Werror для обнаружения таких неприятных ошибок во время компиляции.Нет оправдания тому, что эти флаги не используются.

В моих make-файлах я обычно использую расширение bash -W{all,extra,error}.

0 голосов
/ 13 июня 2018

Вы вызвали неприятный случай неопределенного поведения (UD), которое в конечном итоге приводит к SIGABRT в вашей программе.В 9.6.3 [stmt.return] :

Выход из конца конструктора, деструктора или функции с типом возвращаемого значения cv void эквивалентен возвратубез операнда.В противном случае выпадение из конца функции, отличной от main, приводит к неопределенному поведению.

Технически, почти все, что может произойти с вашим кодом после возврата из вашей функции.В большинстве случаев ничего не происходит, все будут счастливы, и поэтому люди в основном игнорируют предупреждения типа no return statement in function returning non-void.

Теперь здесь вы понимаете, почему это может быть очень плохой вещью.Если вы установите тип возвращаемого значения void вместо std::string или если вы do вернете некоторую строку, программа больше не будет аварийно завершать работу.

Хотя сгенерированный gcc код кажется segfault или abort (в зависимости от версии), сгенерированный clang код выдаст недопустимую инструкцию .Оба компилятора в порядке, если вы измените тип возвращаемого значения.Для еще большей путаницы возьмите gcc 4.9.x;здесь ваш код просто отлично работает , несмотря на UB.

Этот фрагмент кода представляет собой настоящий сладкий пирог с поведением undefined , которое действительно может испортить ваше приложение.

...