3

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?

glglgl
  • 89,107
  • 13
  • 149
  • 217
vaibhav3002
  • 255
  • 4
  • 15
  • 2
    Yes. Checked with valgrind memcheck but nothing strange observed. – vaibhav3002 Oct 19 '11 at 08:10
  • maybe zero out 'hints' before assigning things in it? – AndersK Oct 19 '11 at 08:12
  • if segmentation fault occur in your code then valgrind will give you the reason for that and the line no of your code which has created segmetation fault...if valgrind doesnt give any error then there might me no segmantation fault – Jeegar Patel Oct 19 '11 at 08:12
  • @cnicutar - My question is how come passing the same parameters to the same library function yield different result. – vaibhav3002 Oct 19 '11 at 08:14
  • @crissangel Invariably the answer is you're doing it wrong (i.e. you're not passing them in the same way - you just think you do). – cnicutar Oct 19 '11 at 08:15
  • @Mr.32 Just added valgrind log – vaibhav3002 Oct 19 '11 at 08:17
  • @cnicutar The reason I am not posting the original code is because it is super complicated and huge. The reason I posted over here is that I am trying to get some insight on res_init.c crash. – vaibhav3002 Oct 19 '11 at 08:21
  • res_init.c:176 is creating seg fault so work arround that – Jeegar Patel Oct 19 '11 at 08:25
  • I took your advice and I reduced the code. Now its up for everyone to verify. – vaibhav3002 Oct 19 '11 at 11:05
  • I suspect you corrupted memory before calling `getaddrinfo`, but if you're *really* using gnulib (that's not glibc or glib, but gnulib) then crashes should be expected since just about everything it does invoked undefined behavior... :-) – R.. GitHub STOP HELPING ICE Oct 19 '11 at 15:18

2 Answers2

3

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.

vaibhav3002
  • 255
  • 4
  • 15
1

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?

Tom
  • 333
  • 2
  • 8