gethostbyaddr() crasht manchmal



  • Hallo !

    Ich bastel gerade in ein bestehendes Programm einen DNS-Lookup ein welcher dann per Socket weitergegeben werden soll.

    Dazu gehe ich wie folgt (rudimentär) vor:

    ...
    char msg[1024];
    double myupspeed;
    myupspeed = upspeed / float( 1 << 20 );

    struct hostent *host;
    struct in_addr in;

    in.s_addr = v.m_ipa;
    host = gethostbyaddr(&in, sizeof(struct in_addr), AF_INET);

    sprintf(msg," UID: %d UpSpeed: %.2f MB/s (%s) \n", user->uid, myupspeed, host->h_name);

    end(sock, msg, strlen(msg), 0);
    close(sock);
    ...

    Das funktioniert soweit auch, allerdings nur rund 10-15 mal, manchmal auch nur 2 mal oder gar nicht bis das Programm dann komplett mit einem Segfault crasht.

    Kommentiere ich die gethostbyaddr()... aus funktioniert es über Stunden ohne Probleme...

    Hat jemand eine Idee ? Habe ich evtl. etwas übersehen ?

    Danke



  • Hallo,

    bei allen API funktionen ist es wichtig zu überprüfen ob sie korrekt ausgeführt wurden. Das geht bei sockets doch irgendwie mit WSALAtError oder so??
    Dann würde ich mal vermuten, dass es auch läuft wenn Du das sprintf rausmachst.



  • Hi !

    Ja ich könnte gethostbyaddr() auf NULL prüfen, allerdings ist es für die Ausgabe des Programmes relativ uninteressant da es "nicht schlimm für mich" ist wenn eine Adresse mal nicht aufgelöst werden kann, d.h. hab ich keine Prüfung eingefügt.
    Würde NULL geliefert werden, müßte %s beim socket weiter unten eigentlich keine Probleme habe.

    Ich denke das Problem liegt auch nicht am Socket, da dieser auf dem gleichen Host läuft, es muß irgendein Problem mit gethostbyaddr() sein, ich komme nur nicht darauf was es sein könnte...



  • Chris21 schrieb:

    Würde NULL geliefert werden, müßte %s beim socket weiter unten eigentlich keine Probleme habe.

    Du greifst ja auf h_host->h_name zu. Also so:

    ((hostent*)0)->h_name;
    


  • Sorry so fortgeschritten bin ich noch nicht, ich kann Dir nicht wirklich folgen. Was würdest Du am Code ändern daß bei NULL kein Crash mehr folgt ?



  • Was würdest Du am Code ändern daß bei NULL kein Crash mehr folgt ?

    Um Dich selbst zu zitieren: Du könntest gethostbyaddr auf NULL prüfen...



  • Ja aber macht das denn Sinn ? Im Prinzip kann %s doch auch NULL sein d.h. es würde halt anstelle des Hostnamen einfach NULL ausgegeben werden...

    Ich kann natürlich auch

    if (host == NULL)
    {
    host->h_name = "NULL";
    }

    machen.. aber irgendwie bissi blöd, oder ? 😉



  • Genau das kannst Du nicht machen. NULL ist keine gültige Speicherstelle, damit zeigt host auf kein gültiges Objekt. Damit ist host->h_name per se undefiniert. Nicht lesen! Nicht schreiben! Nicht anfassen!

    Du wirst Dir schon die Mühe machen müssen, den Fall NULL explizit abzufangen.



  • Achso !

    Sorry das wußte ich nicht.

    Ein

    if (host == NULL)
    {
    host->h_name = "Fehler";
    }

    Würde also demnach funktionieren damit das sprintf weiter unten kein Problem kriegt ?



  • Da host immernoch NULL ist, ist host->h_name immernoch undefiniert. Du darfst host nicht anfassen!



  • Ok vielen Dank.

    Ich denke (hoffe) so sollte es dann funktionieren:

    host = gethostbyaddr(&in, sizeof(struct in_addr), AF_INET);

    if (host == NULL)
    {
    hostname = "Nicht auflösbar";
    }
    else
    {
    hostname = host->h_name;
    }

    sprintf(msg,"UID: %d UpSpeed: %.2f MB/s (%s) \n", user->uid, myupspeed, hostname);


Anmelden zum Antworten