Frage

Ich bekomme Segmentierungsfehler in getAddrinfo ().

Dies ist die Stapelspur.

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

Die Quelle der Funktion 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;
    }

Nach dem Laufen in Valgrind bekam ich das folgende Protokoll

    ==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==

Diese Funktion test_addrinfo () wird von einer obersten Ebene in meiner Anwendung aufgerufen. Ich habe dieselbe Funktion in einer anderen Anwendung getestet, die nur einen Main () hat. Es hat in dieser Anwendung funktioniert.

Ich vermute, dass ich nicht die richtige Gnulib -Bibliothek oder falsche Kompilierungsflags verwende. Irgendwelche Hinweise oder Hinweise?

War es hilfreich?

Lösung

Ich fand das Problem. Es gab einen Stapelüberlauf, da die Funktion getaddrinfo () alloca () verwendet - die Speicher dynamisch, jedoch auf dem Stapel (und nicht auf dem Haufen) zuweisen. Dies ist eine sehr gefährliche Funktion.

Ich habe versucht, das GCC-Flag-fstack-protector-gcc zu platzieren, aber es war vergebens.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top