Segmentation fault in getaddrinfo()

3.5k Views Asked by At

I am getting segmentation fault in getaddrinfo().

This is the stack trace.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7ff4b70 (LWP 26872)]
__res_vinit (statp=0xb7ff4df4, preinit=0) at res_init.c:176
176 res_init.c: No such file or directory.
    in res_init.c
(gdb) bt
#0  __res_vinit (statp=0xb7ff4df4, preinit=0) at res_init.c:176
#1  0x0042fe95 in *__GI___res_ninit (statp=0xb7ff4df4) at res_init.c:142
#2  0x00430ea0 in *__GI___res_maybe_init (resp=0xb7ff4df4, preinit=0) at res_libc.c:122
#3  0x003f86f4 in gaih_inet (name=<value optimized out>, service=<value optimized out>, req=0xb7ff3df8, pai=0xb7ff3db4, naddrs=0xb7ff3da4)
    at ../sysdeps/posix/getaddrinfo.c:690
#4  0x003faa65 in *__GI_getaddrinfo (name=0x8203a68 "api.shoutcast.com", service=0x810ae72 "http", hints=0xb7ff3df8, pai=0xb7ff3e24)
    at ../sysdeps/posix/getaddrinfo.c:2160
#5  0x08050a87 in test_addrinfo () at /kkkk/myaddrinfo.c:33

The source of the function test_addrinfo();

    #ifndef   NI_MAXHOST
    #define   NI_MAXHOST 1025
    #endif

    struct  addrinfo hints =
    {
        .ai_flags       = 0,        /* Input flags.                 nothing special */
        .ai_family      = PF_UNSPEC,/* Protocol family for socket.  any  */
        .ai_socktype    = SOCK_STREAM,        /* Socket type.                 take any (SOCK_RAW, SOCK_STREAM,  SOCK_DGRAM) */
        .ai_protocol    = IPPROTO_TCP,        /* Protocol for socket.         take any (IPPROTO_TCP and IPPROTO_UDP) */
        .ai_addrlen     = 0,        /* Length of socket address.    always 0 */
        .ai_addr        = NULL,     /* Socket address for socket.   always NULL */
        .ai_canonname   = NULL,     /* Canonical name for service.  always NULL */
        .ai_next        = NULL,     /* Pointer to next in list.     always NULL */
    };



    int test_addrinfo(void)
    {
        struct addrinfo *result = NULL;
        struct addrinfo *res;
        int error;

        /* resolve the domain name into a list of addresses */
        error = getaddrinfo("api.shoutcast.com", "http", &hints, &result);
        if (error != 0)
        {
            fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
            return EXIT_FAILURE;
        }

        /* loop over all returned results and do inverse lookup */
        for (res = result; res != NULL; res = res->ai_next)
        {
            char hostname[NI_MAXHOST] = "";

            error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0); 
            if (error != 0)
            {
                fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
                continue;
            }
            if (*hostname != '\0')
                printf("hostname: %s\n", hostname);
        }

        freeaddrinfo(result);
        return EXIT_SUCCESS;
    }

After running in valgrind, I got the following log

    ==00:00:00:07.590 7788==
    ==00:00:00:07.590 7788== Process terminating with default action of signal 11 (SIGSEGV)
    ==00:00:00:07.590 7788==  Bad permissions for mapped region at address 0x4033BDC
    ==00:00:00:07.590 7788==    at 0x4348C8A: __res_vinit (res_init.c:176)
    ==00:00:00:07.645 7788==

This function test_addrinfo() is called by a top layer in my application. I tested the same function in another application which has only one main(). It worked in that application.

I am suspecting that I am not using the correct gnulib library or wrong compilation flags. Any clues or hints?

2

There are 2 best solutions below

1
On BEST ANSWER

I found the problem. There was stack overflow as the function getaddrinfo() uses alloca() - which allocates memory dynamically but on the stack(and not on heap). This is a very dangerous function.

I tried putting the -fstack-protector-all gcc flag but it was in vain.

0
On

2022-02-08 16:55:33 , the same problem , I don't know how to solve it .

I knew , the error throw when call getaddrinfo()

My error info

(gdb) run
Starting program: /document/c_cpp_program/cpp_spider/main.out
test print 000
test print 111

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7cfe813 in __GI_getaddrinfo (name=<optimized out>, service=<optimized out>, hints=<optimized out>, pai=<optimized out>)
    at ../sysdeps/posix/getaddrinfo.c:2501
2501    ../sysdeps/posix/getaddrinfo.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7cfe813 in __GI_getaddrinfo (name=<optimized out>, service=<optimized out>, hints=<optimized out>, pai=<optimized out>)
    at ../sysdeps/posix/getaddrinfo.c:2501
#1  0x0000555555555367 in test_socket_api () at main.cpp:29
#2  0x00005555555554c7 in main () at main.cpp:47
(gdb)

My error code is

#include <iostream>
#include <sys/socket.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include "net_opt/net_utils.h"
#include "example/other_test.h"

void test_socket_api() {
    std::string host_name = "www.google.com";
    std::string host_service = "80";
    struct addrinfo host_addr_info_limit ;
    struct addrinfo **host_addr_info_result;  //need fix ①

    std::cout << "test print 000 " << "\n" ;
    memset(&host_addr_info_limit, 0, sizeof(host_addr_info_limit));
    host_addr_info_limit = {
      .ai_flags = 0 ,
      .ai_family = AF_UNSPEC ,
      .ai_socktype = SOCK_STREAM ,
      .ai_protocol = 0 ,
      .ai_addrlen = 0 ,
      .ai_addr = NULL ,
      .ai_canonname = NULL ,
      .ai_next = NULL ,
    };
    std::cout << "test print 111" << "\n" ;

    int result_code = getaddrinfo(host_name.c_str(),
                                  host_service.c_str(),
                                  &host_addr_info_limit,
                                  host_addr_info_result);//need fix ②

    std::cout << "test print 222" << "\n" ;

    std::cout << "result_code = " << result_code << "\n";

    if (0 == result_code) {
        std::cout << "get data success ✅  \n";
    } else {
        std::cout << "get data failed ❌  :" << gai_strerror(result_code) << "\n";
    }
}


int main() {
    test_socket_api();

    return 0;
}


Edit 1 : Now I know how to solve problem , but i don't know why .

My refrence code:

  1. man getaddrinfo
  2. https://gist.github.com/jirihnidek/bf7a2363e480491da72301b228b35d5d
  3. Segmentation fault in getaddrinfo()

base my code , I fix two point :

point one :

//struct addrinfo **host_addr_info_result;     
//fix to ---> 
struct addrinfo *host_addr_info_result;

point two :

//int result_code = getaddrinfo(host_name.c_str(),
//                              host_service.c_str(),
//                              &host_addr_info_limit,
//                              host_addr_info_result);
// fix to --> 
int result_code = getaddrinfo(host_name.c_str(),
                                  host_service.c_str(),
                                  &host_addr_info_limit,
                                  &host_addr_info_result);

now my new question is : I don't know what's the different between the two spellings .

2022-02-09 11:58:00 ; I get other information , but i don't know how to explain the error .

the information is :

  1. struct addrinfo **host_addr_info_result; make host_addr_info_result is NULL , the NULL param lead to getaddrinfo() run error .

  2. struct addrinfo *host_addr_info_result; make host_addr_info_result is NULL , but &host_addr_info_result is not NULL , the unnull value make getaddrinfo() run success .


Edit 2 , I try to search file /sysdeps/posix/getaddrinfo.c and check method's implement that getAddrinfo() .

the code is : https://code.woboq.org/userspace/glibc/sysdeps/posix/getaddrinfo.c.html

//file path : https://code.woboq.org/userspace/glibc/sysdeps/posix/getaddrinfo.c.html 

int
getaddrinfo (const char *name, const char *service,
             const struct addrinfo *hints, struct addrinfo **pai)
{
   .....//other code

   if (p)
    {
      *pai = p;    //this is crash point 
                   //pai is NULL is that creash reason 
      return 0;
    }

   .....//other code
}

Now , my question is : my error msg content /sysdeps/posix/getaddrinfo.c: No such file or directory. ; How can i find these codes on my computer?