[Megoldva] glibc/getaddrinfo() furcsaságok

Fórumok

Sziasztok!
Igazából arra lennék kíváncsi, hogy én rontok-e el valamit, vagy hiba van a libc-ben?

Van a következő forráskód: (a formaság kedvéért: src/tes2.c)
(egy nagyobb projekt része, azért van ennyi #include benne, ez egy kiragadott részlet, de egészben is ugyanezt produkálja)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> 
#include <sys/types.h>
#include <sys/ipc.h>  
#include <sys/stat.h> 
#include <fcntl.h>  
#include <linux/limits.h>  
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define test_c 

int main(int argc, char *argv[]){
    char *buff1=NULL, *buff2=NULL, *buff3=NULL;    
    struct addrinfo hints;
    struct addrinfo *res;
    int err;

    memset(&hints, 0, sizeof(hints));   
    hints.ai_family = AF_UNSPEC;        
    hints.ai_socktype = SOCK_STREAM;    
  
    if((err = getaddrinfo("localhost", "http", &hints, &res)) != 0){
        printf( "getaddrinfo hiba: %s\n", gai_strerror(err));
        return -1;
    } 
    printf("1: %p, 2: %p, 3: %p", buff1, buff1, buff3);
    buff1 = malloc(100); /*<-- ezen sor hiányában is hibára fut */
    free(buff1);    /*<-- Ha ezt a free-t kikommentezem, akkor tökéletesen fut */

    printf("\n");
    return 0;
}

ezekkel a kapcsolókkal fordítom:

(természetesen itt is, a crypto libre szükség van a projektben, szóval nem hanyagságból van ott)

gcc -Wall -c -ggdb -Wpedantic -Wmissing-prototypes -o build/test2.o src/test2.c
gcc  build/test2.o -o bin/test2 -lefence -lcrypto

 

Ám a futtatáskor már ezt a hibaüzenetet kapom:
 

tux@pc:~$ ./bin/server
  Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
server: resolv_conf.c:423: __resolv_conf_allocate: Assertion `conf == ptr' failed.
Félbeszakítva (core készült)


tux@pc:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 

 

Ahogy írtam a kódban, a megjelölt sorban, ha kommentbe teszem a free(buff1);-et, akkor minden tökéletesen működik.

Szóval mi lehet a nyűgje a getaddrinfo() -nak?


UPDATE:

Hogy másoknak kevesebb bosszúságot okozzon:

EF_ALIGNMENT=8 ./bin/test2

(és akkor pontos lesz az illesztés)

Hozzászólások

$ make test2 && ./test2
cc -g -Wall -W  -g  test2.c  -lcrypto -lefence -o test2
test2.c: In function ‘main’:
test2.c:17:24: warning: unused variable ‘buff2’ [-Wunused-variable]
     char *buff1=NULL, *buff2=NULL, *buff3=NULL;
                        ^
test2.c:16:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
 int main(int argc, char *argv[]){
              ^
test2.c:16:26: warning: unused parameter ‘argv’ [-Wunused-parameter]
 int main(int argc, char *argv[]){
                          ^

  Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
1: (nil), 2: (nil), 3: (nil)

Nem tudtam reprodukálni a hibát.

 

Most kipróbáltam egy "szűz" Ubuntu 18.04-en (gondolván, hátha valami globális gcc/make beállítás piszkít bele a régebbi gépen)

(Ha valakinek nem találná, a libeket, akkor előtte: apt-get install electric-fence libssl-dev)

de sajnos itt is ugyanez, gdb backtrace:

https://pastebin.com/4vZV6GE1

Akár egyben:

gcc -g -Wall -W -ggdb test2.c -lcrypto -lefence -o test2

Akár két lépésben fordítom:
 

gcc -Wall -g -c -ggdb -W -o test2.o test2.c
gcc  test2.o -o test2 -lefence -lcrypto

(Ugyanis úgy rémlik, mintha korábban lett volna különbség a két mód között, de, ezen a "szűz" ubuntu-n nem látok.)

Látszólag a /etc/resolv.conf tartalma is számít. Meg kellene nézni a valgrind ./test2 kimenetét is.

Működik. Mármint a bináris, amit adtál, működik. Ha lebuildelem, akkor is.

  Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens 
1: (nil), 2: (nil), 3: (nil)

Egyszóval a probléma nem a te kódodban, vagy a GCC-ben van, hanem a környezetben.

Én közben ezt találtam: https://answers.launchpad.net/ubuntu/+question/674132

The reason for this failure is probably because the Electric Fence (-lefence / libefence.so) library is returning non-aligned pointers from its malloc() function.

Ubuntu 18.04, úgyhogy simán passzolhat.

Érdekes felvetés... Annyira, hogy meg is nézem a source-t.
 


if ( EF_ALIGNMENT == -1 ) {
    if ( (string = getenv("EF_ALIGNMENT")) != 0 )
        EF_ALIGNMENT = (size_t)atoi(string);
    else
        EF_ALIGNMENT = sizeof(int);
}

Ravasz... Talán el tudok képzelni olyan esetet, hogy valamilyen kód épít arra, hogy a malloc nyolcbájtra illeszt... Mondjuk ilyesmi:

char *p= malloc (N);
p += ...;
p= (char *)((uintptr_t)p+7)&(~7)); /* align to next 8-byte */

Ha így állunk, akkor oké,

ámbár pillanatnyilag ötletem sincs, merre indítsam a konfigok túrását. lehet,  ez valami systemd feature ???

 

(Csak azért kérdezem, mert korábban, emlékeim szerint Ubuntu 18.04.3->08.04.4 váltásnál egyszercsak meghalt a komplett névfeloldás, és akkor valami veszekedés volt a systemd és a dnsmasq között, amit (szerencsére) orvosolni lehetett  rövid ubunut-fórum olvasgatás után, azóta látszólag minden rendben. Ámbár, ahol a mellékelt bin fordult, az egy "vadi új" ubuntu, most telepítettem 2 hete, tehát ott nem volt verzióugrás)

valgrind-ot nézted? (valgrind ./test2)
Szerk: Bocs, látom benne van a tar.gz-ben.

Erre rá kellene nézni:


==7352== HEAP SUMMARY:
==7352==     in use at exit: 64 bytes in 1 blocks
==7352==  total heap usage: 67 allocs, 66 frees, 31,124 bytes allocated
Szerkesztve: 2021. 07. 19., h – 08:53

Na most előjött nekem is, WSL és efence kell a probléma bemutatásához. Ez segített:

export EF_ALIGNMENT=8

Ebben a történetben az Electric Fence a hibás; hogy aztán az egyes esetekben okoz-e manifeszt hibát, az esetleges. Alapvetően a malloc(3) olyan címet kellene visszaadjon, ami illesztés szempontjából minden elemi típusnak megfelel (mondjuk 64 bit, ha amd64 vagy ppc64 architektúra). Namostan a CPU esetleg nem-illesztett címmel is elboldogul (persze lassabban), de erre nem kellene építeni.