Thread: strdup against array? segfaults

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    6

    strdup against array? segfaults

    Does anyone see a problem with my code? attempting to do a strdup is failing with a segmentation fault within libc

    plugintools.h
    Code:
    /* Provide function for adding files to be copied/linked
       into report
    */
    typedef struct file_list {
      int count;
      char **filepath;
    } file_list;
    
    // max path length for any file/dir listing
    #define MAXPATHLEN 1024
    file_list *
    add_copy_spec(const char *path);
    plugintools.c
    Code:
    /* add file specification (dir, file, shell glob)
     */
    file_list *
    add_copy_spec(const char *path)
    {
        int err, i;
        char *abspath[MAXPATHLEN];
        glob_t globbuf;
    
        struct file_list *fl = malloc(sizeof(file_list));
        
        err = glob(path, GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
        if (err) {
            fl->count = 0;
            fl->filepath = NULL;
            return fl;
        }
        
        fl->count = globbuf.gl_pathc;
        fl->filepath = malloc(sizeof(char *) * fl->count);
        // loop through our file list, append to struct array
        printf("\nfilepath loop\n");
        for (i = 0; i < globbuf.gl_pathc; i++) {
            printf("%s\n", globbuf.gl_pathv[i]);
            fl->filepath[i] = strdup(globbuf.gl_pathv[i]);
    
    /*
            if((realpath(globbuf.gl_pathv[i], abspath)) != NULL) {
                //fl->filepath[i] = strdup(abspath);
              } else {
                continue;
            }
    */
        }
        globfree(&globbuf);
        return fl;
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't see why abspath should be a string. Did you mean
    Code:
    char abspath[MAXPATHLEN]
    instead?

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    6
    Quote Originally Posted by tabstop View Post
    I don't see why abspath should be a string. Did you mean
    Code:
    char abspath[MAXPATHLEN]
    instead?
    Code:
    fl->filepath[i] = strdup(globbuf.gl_pathv[i]);
    Using the updated code, however produces:

    Code:
    file_list *
    add_copy_spec(const char *path)
    {
        int err, i;
        char abspath[MAXPATHLEN];
        glob_t globbuf;
    
        struct file_list *fl = malloc(sizeof(file_list));
        
        err = glob(path, GLOB_DOOFFS | GLOB_APPEND, NULL, &globbuf);
        if (err) {
            fl->count = 0;
            fl->filepath = NULL;
            return fl;
        }
        
        fl->count = globbuf.gl_pathc;
        fl->filepath = malloc(sizeof(char *) * fl->count);
        // loop through our file list, append to struct array
        printf("\nfilepath loop\n");
        for (i = 0; i < globbuf.gl_pathc; i++) {
            if((realpath(globbuf.gl_pathv[i], abspath)) != NULL) {
                fl->filepath[i] = strdup(abspath);
              } else {
                continue;
            }
        }
        globfree(&globbuf);
        return fl;
    }
    Code:
    make  check-TESTS
    make[2]: Entering directory `/home/uzr/Code/jibbajabba/c/sos/tests'
    Running suite(s): SOS
    __Creating hardlink blank_file_for_tests -> /tmp/sos_tests/blank_file_for_tests
    __Creating symlink /home/uzr/Code/jibbajabba/c/sos/tests/blank_file_for_tests -> /tmp/sos_tests/blank_file_for_tests
    *** glibc detected *** /home/uzr/Code/jibbajabba/c/sos/tests/.libs/lt-check_sos: realloc(): invalid pointer: 0x00007f2f2a284508 ***
    ======= Backtrace: =========
    /lib64/libc.so.6[0x30fce74a76]
    /lib64/libc.so.6(realloc+0x2e2)[0x30fce7a472]
    /lib64/libc.so.6[0x30fcea77cf]
    /lib64/libc.so.6(glob64+0xecc)[0x30fcea8a0c]
    /home/uzr/Code/jibbajabba/c/sos/libsos/.libs/libsos.so.0(add_copy_spec+0x4f)[0x7f2f2a284b8f]
    /home/uzr/Code/jibbajabba/c/sos/tests/.libs/lt-check_sos[0x400ed2]
    /usr/lib64/libcheck.so.0(srunner_run_all+0x6e8)[0x7f2f2a06dbb8]
    /home/uzr/Code/jibbajabba/c/sos/tests/.libs/lt-check_sos[0x400e7b]
    /lib64/libc.so.6(__libc_start_main+0xfd)[0x30fce1eb1d]
    /home/uzr/Code/jibbajabba/c/sos/tests/.libs/lt-check_sos[0x400cd9]
    ======= Memory map: ========
    00400000-00402000 r-xp 00000000 fd:00 1704636                            /home/uzr/Code/jibbajabba/c/sos/tests/.libs/lt-check_sos
    00601000-00602000 rw-p 00001000 fd:00 1704636                            /home/uzr/Code/jibbajabba/c/sos/tests/.libs/lt-check_sos
    01d8a000-01dab000 rw-p 00000000 00:00 0                                  [heap]
    30fc800000-30fc81e000 r-xp 00000000 fd:00 205589                         /lib64/ld-2.11.1.so
    30fca1d000-30fca1e000 r--p 0001d000 fd:00 205589                         /lib64/ld-2.11.1.so
    30fca1e000-30fca1f000 rw-p 0001e000 fd:00 205589                         /lib64/ld-2.11.1.so
    30fca1f000-30fca20000 rw-p 00000000 00:00 0 
    30fce00000-30fcf6f000 r-xp 00000000 fd:00 205590                         /lib64/libc-2.11.1.so
    30fcf6f000-30fd16f000 ---p 0016f000 fd:00 205590                         /lib64/libc-2.11.1.so
    30fd16f000-30fd173000 r--p 0016f000 fd:00 205590                         /lib64/libc-2.11.1.so
    30fd173000-30fd174000 rw-p 00173000 fd:00 205590                         /lib64/libc-2.11.1.so
    30fd174000-30fd179000 rw-p 00000000 00:00 0 
    30fd600000-30fd617000 r-xp 00000000 fd:00 205596                         /lib64/libpthread-2.11.1.so
    30fd617000-30fd816000 ---p 00017000 fd:00 205596                         /lib64/libpthread-2.11.1.so
    30fd816000-30fd817000 r--p 00016000 fd:00 205596                         /lib64/libpthread-2.11.1.so
    30fd817000-30fd818000 rw-p 00017000 fd:00 205596                         /lib64/libpthread-2.11.1.so
    30fd818000-30fd81c000 rw-p 00000000 00:00 0 
    3109e00000-3109e16000 r-xp 00000000 fd:00 205627                         /lib64/libgcc_s-4.4.3-20100127.so.1
    3109e16000-310a015000 ---p 00016000 fd:00 205627                         /lib64/libgcc_s-4.4.3-20100127.so.1
    310a015000-310a016000 rw-p 00015000 fd:00 205627                         /lib64/libgcc_s-4.4.3-20100127.so.1
    7f2f2a066000-7f2f2a069000 rw-p 00000000 00:00 0 
    7f2f2a069000-7f2f2a070000 r-xp 00000000 fd:00 271395                     /usr/lib64/libcheck.so.0.0.0
    7f2f2a070000-7f2f2a26f000 ---p 00007000 fd:00 271395                     /usr/lib64/libcheck.so.0.0.0
    7f2f2a26f000-7f2f2a270000 rw-p 00006000 fd:00 271395                     /usr/lib64/libcheck.so.0.0.0
    7f2f2a270000-7f2f2a271000 rw-p 00000000 00:00 0 
    7f2f2a282000-7f2f2a284000 rw-p 00000000 00:00 0 
    7f2f2a284000-7f2f2a286000 r-xp 00000000 fd:00 1704627                    /home/uzr/Code/jibbajabba/c/sos/libsos/.libs/libsos.so.0.1.5
    7f2f2a286000-7f2f2a485000 ---p 00002000 fd:00 1704627                    /home/uzr/Code/jibbajabba/c/sos/libsos/.libs/libsos.so.0.1.5
    7f2f2a485000-7f2f2a486000 rw-p 00001000 fd:00 1704627                    /home/uzr/Code/jibbajabba/c/sos/libsos/.libs/libsos.so.0.1.5
    7f2f2a486000-7f2f2a487000 rw-p 00000000 00:00 0 
    7fffc3ca3000-7fffc3cb8000 rw-p 00000000 00:00 0                          [stack]
    7fffc3dff000-7fffc3e00000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    66%: Checks: 3, Failures: 0, Errors: 1
    check_sos.c:78:E:Core:test_copy_spec:0: (after this point) Received signal 6 (Aborted)
    FAIL: check_sos

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    6
    Interestingly enough this works:

    Code:
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    void
    print_struct_files()
    {
        char *data = malloc(sizeof(char) * 100);
        char **files = malloc(100);
        int i;
        for(i = 0; i < 5; i++) {
            files[i] = strdup("Testing");
            printf("%s\n", files[i]);
        }
    }
    
    void
    main()
    {
        printf("WORKING\n");
        print_struct_files();
    }
    i was under the impression that strdup would handle malloc'ing

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by schurt
    i was under the impression that strdup would handle malloc'ing
    It should.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    6
    attempting to access memory at

    Code:
    fl->filepath = malloc(sizeof(char *) * fl->count);
    fl->filepath[2] return invalid address.

    if fl->count returns 39 why isn't my array being created correctly?

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Code:
    fl->filepath = malloc(sizeof(char *) * fl->count);
    You are asking for fl-> count char pointers. Is this really correct? This is why the recommendation to use sizeof on an expression, and not a type, is made.

    fl->filepath = malloc(sizeof(*(fl->filepath)) * fl->count);

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    6
    Quote Originally Posted by whiteflags View Post
    Code:
    fl->filepath = malloc(sizeof(char *) * fl->count);
    You are asking for fl-> count char pointers. Is this really correct? This is why the recommendation to use sizeof on an expression, and not a type, is made.

    fl->filepath = malloc(sizeof(*(fl->filepath)) * fl->count);
    You are correct and I am going to alter my code to reflect the expression and not the type

    I fixed the code with this result:
    Code:
    /* add file specification (dir, file, shell glob)
     */
    file_list *
    add_copy_spec(const char *path)
    {
        int err, i;
        char abspath[MAXPATHLEN];
        glob_t globbuf;
    
        struct file_list *fl = malloc(sizeof(file_list));
        
        memset(&globbuf, 0, sizeof(globbuf));
        err = glob(path, 0, NULL, &globbuf);
        if (err) {
            fl->count = 0;
            fl->filepath = NULL;
            return fl;
        }
        
        fl->count = globbuf.gl_pathc;
        fl->filepath = malloc(sizeof(*(fl->filepath)) * fl->count);
        // loop through our file list, append to struct array
        printf("\nfilepath loop\n");
        for (i = 0; i < globbuf.gl_pathc; i++) {
            if((realpath(globbuf.gl_pathv[i], abspath)) != NULL) {
                fl->filepath[i] = strdup(abspath);
                printf("fpath: %s\n", fl->filepath[i]);
              } else {
                continue;
            }
        }
        globfree(&globbuf);
        return fl;
    }

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How many other malloc calls are there in the program, that you haven't shown us?

    This is cause and effect. You're posting the effect, or where you think the problem is.
    Except it isn't in all likelyhood a problem at all.

    Put add_copy_spec() in a separate file, and a MINIMAL main() to call it - does it crash?
    My guess is that it doesn't. But if it does, you have a really good example to post.

    Now, back to the cause.
    The grim reality of C memory management (there isn't any) is that ANY screwup you make can have any one of these outcomes
    - instant death
    - death in an unrelated part of the program
    - absolutely nothing happens

    What to do:
    Run the program in the debugger (compile with -g), and linked against electric fence
    If it's an overrun, it will trap and drop you in the debugger at the line of code which stepped off memory it didn't allocate.

    Run the program under valgrind - see the manual for more details.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Mar 2010
    Posts
    6
    Quote Originally Posted by Salem View Post
    How many other malloc calls are there in the program, that you haven't shown us?

    This is cause and effect. You're posting the effect, or where you think the problem is.
    Except it isn't in all likelyhood a problem at all.


    Put add_copy_spec() in a separate file, and a MINIMAL main() to call it - does it crash?
    My guess is that it doesn't. But if it does, you have a really good example to post.

    Now, back to the cause.
    The grim reality of C memory management (there isn't any) is that ANY screwup you make can have any one of these outcomes
    - instant death
    - death in an unrelated part of the program
    - absolutely nothing happens

    What to do:
    Run the program in the debugger (compile with -g), and linked against electric fence
    If it's an overrun, it will trap and drop you in the debugger at the line of code which stepped off memory it didn't allocate.

    Run the program under valgrind - see the manual for more details.
    Those 2 mallocs are the only calls in the entire library, ill look into electric fence thanks for the tip

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  3. [question]Analyzing data in a two-dimensional array
    By burbose in forum C Programming
    Replies: 2
    Last Post: 06-13-2005, 07:31 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM