getpwnam()



  • hi,
    ich versuche anhand eines Benutzernames die UID herauszufinden. Das funktioniert auch wunderbar allerdings bekomme ich memoryleaks. Kann mir jemand sagen wie ich diese Funktion richtig aufrufen / behandeln muss?

    #include <stdlib.h>
    #include <stdio.h>
    #include <pwd.h>
    #include <mcheck.h>
    
    int main( void ) {
        struct passwd *pwd = NULL;
    
        mtrace();
    
        if( ( pwd = getpwnam( "root" ) ) == NULL ) {
            printf( "Fehler\n" );
    
            return 1;
        }
    
        printf( "pw_name: %s\n", pwd->pw_name );
        printf( "pw_dir: %s\n", pwd->pw_dir );
        printf( "pw_shell: %s\n", pwd->pw_shell );
        printf( "pw_uid: %u\n", pwd->pw_uid );
    
        return 0;
    }
    

    mtrace gibt folgendes aus:

    Memory not freed:
    -----------------
       Address     Size     Caller
    0x0804a8d0     0x10  at 0xb7f3c39c
    0x0804b2b0     0x24  at 0xb7f4f3e3
    0x0804b2d8      0x8  at 0xb7f4efbc
    0x0804ba48     0x10  at 0xb7f3c39c
    0x0804ba60      0x8  at 0xb7f4efbc
    0x0804ba70     0x10  at 0xb7f3c39c
    0x0804ba88      0x8  at 0xb7f4efbc
    0x0804ba98     0x10  at 0xb7f3c39c
    0x0804bab0      0x8  at 0xb7f4efbc
    0x0804bac0     0x10  at 0xb7f3c39c
    0x0804bad8      0x8  at 0xb7f4efbc
    

    danke,
    blan



  • das geht mit getpwnam gar nicht. man könnte auf die idee kommen, den zurückgegebenen pointer mit free zu deallokieren, sollte aber davon abstand nehmen, das nicht garantiert ist, dass jede implementierung den speicherbereich für die passwd struktur dynamisch allokiert. ein speicherleck im eigentlichen sinne ist es nicht, da der verwendete speicher immer wieder verwendet wird. du verlierst also nicht bei jedem aufruf neuen speicher.
    eine lösung wär man: getpwnam_r(3).

    #include <stdlib.h>
    #include <stdio.h>
    #include <pwd.h>
    #include <mcheck.h>
    
    #define BUFFER_SIZE 1024
    
    int main( void ) {
      struct passwd pwd;
      struct passwd* result;
      char buffer[BUFFER_SIZE];
      int error;
    
      if((error = getpwnam_r("root", &pwd, buffer, BUFFER_SIZE, &result))) {
        fprintf(stderr, "Fehler: %s\n", strerror_r(error, buffer, BUFFER_SIZE));
        return 1;
      }
    
      printf( "pw_name: %s\n", pwd.pw_name );
      printf( "pw_dir: %s\n", pwd.pw_dir );
      printf( "pw_shell: %s\n", pwd.pw_shell );
      printf( "pw_uid: %u\n", pwd.pw_uid );
      return 0;
    }
    


  • hi,
    die methode habe ich auch schon probiert. allerdings tritt dort das gleiche problem auf. warum wird der speicher nicht freigegen - das kann doch nicht normal sein oder?

    blan



  • ich denke, es ist generell nicht schön, wenn eine Bibliothek, die man verwendet, keinen Speicher freigibt. Bei getpwnam ist es aber so, dass bei jedem Aufruf nicht nochmal Speicher reserviert wird, also hält sich der "Schaden" in Grenzen.

    Wenn aber kein Speicher mit getpwnam_r freigegeben wird, dann denke ich, ist ein Bug Report an die glibc Entwickler schon der richtige Weg.

    BTW: bist du wirklich 100% sicher, dass es am getpwnam und nicht an einer anderen Funktion liegt?



  • supertux schrieb:

    ich denke, es ist generell nicht schön, wenn eine Bibliothek, die man verwendet, keinen Speicher freigibt. Bei getpwnam ist es aber so, dass bei jedem Aufruf nicht nochmal Speicher reserviert wird, also hält sich der "Schaden" in Grenzen.

    Wenn aber kein Speicher mit getpwnam_r freigegeben wird, dann denke ich, ist ein Bug Report an die glibc Entwickler schon der richtige Weg.

    BTW: bist du wirklich 100% sicher, dass es am getpwnam und nicht an einer anderen Funktion liegt?

    ich bin mir ziehmlich sicher weils in dem code ja keine andere funktion gibt. gibts ne möglichkeit den code stück für stück im gdb durchlaufen zu lassen? ambesten mit allen malloc() aufrufen.

    blan



  • die glibc hat schon mehrere solche bugs. teste mal ein einfaches hello world programm mit valgrind. der dynamische linker hat schon genug probleme. das ist normal bei der glibc. die entwickler haben für solche lapalien echt keine zeit. nur bugs, die wirklich gravierend sind z.b. bezüglich sicherheit oder allgemeiner verwendbarkeit der glibc, werden gefixt.



  • hi,
    das hört man natürlich nicht gerne - schlechte vorbilder 🙄
    ich habe mal den folgenden code durch valgrid laufen lassen

    #include <stdlib.h>
    #include <stdio.h>
    #include <pwd.h>
    #include <mcheck.h>
    
    int main( void ) {
        printf( "hello world\n" );
        getpwnam( "root" );
    
        return 0;
    }
    

    valgrid sagt:

    ==7411== Memcheck, a memory error detector.
    ==7411== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
    ==7411== Using LibVEX rev 1804, a library for dynamic binary translation.
    ==7411== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
    ==7411== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework.
    ==7411== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
    ==7411== For more details, rerun with: -v
    ==7411== 
    hello world
    ==7411== 
    ==7411== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from 1)
    ==7411== malloc/free: in use at exit: 156 bytes in 11 blocks.
    ==7411== malloc/free: 66 allocs, 55 frees, 6,342 bytes allocated.
    ==7411== For counts of detected errors, rerun with: -v
    ==7411== searching for pointers to 11 not-freed blocks.
    ==7411== checked 56,168 bytes.
    ==7411== 
    ==7411== 156 (36 direct, 120 indirect) bytes in 1 blocks are definitely lost in loss record 1 of 3
    ==7411==    at 0x4022AB8: malloc (vg_replace_malloc.c:207)
    ==7411==    by 0x40FBC41: nss_parse_service_list (nsswitch.c:530)
    ==7411==    by 0x40FC334: __nss_database_lookup (nsswitch.c:134)
    ==7411==    by 0x4563E7B: ???
    ==7411==    by 0x4565044: ???
    ==7411==    by 0x40B6D25: getpwnam_r@@GLIBC_2.1.2 (getXXbyYY_r.c:226)
    ==7411==    by 0x40B6700: getpwnam (getXXbyYY.c:116)
    ==7411==    by 0x80483CC: main (test.c:8)
    ==7411== 
    ==7411== LEAK SUMMARY:
    ==7411==    definitely lost: 36 bytes in 1 blocks.
    ==7411==    indirectly lost: 120 bytes in 10 blocks.
    ==7411==      possibly lost: 0 bytes in 0 blocks.
    ==7411==    still reachable: 0 bytes in 0 blocks.
    ==7411==         suppressed: 0 bytes in 0 blocks.
    

    also scheinbar liegt das schon an dieser funktion oder was meint ihr?

    P.S: Ohne die Funktion gibt es keine leaks.

    blan



  • mach dir über solche sachen keine sorgen. zum einen sind es nciht deine fehler zum anderen sind 156 bytes vollkommen bedeutungslos für ein einmaliges speicherloch. außerdem ist das bei getpwnam ja by design so. speicherlecks sind schlecht, wenn sie immer wieder auftreten.



  • Wenn ein Speicherleck nicht immer wieder auftritt ist es doch kein Speicher_leck _ ?!
    Es gibt doch jede Menge Funktionen die einmalig Speicher behalten. Das sind keine Speicherlecks.


Anmelden zum Antworten