corrupted double-linked list

Discussion in 'C Programming' started by oskar, Oct 10, 2006.

  1. oskar

    oskar Guest

    Hello everyone. I have a problem with my program... and i kinda dunno what to do.. everything seems to work ok, but i'm getting
    corrupted double-linked list error =\.


    *** glibc detected *** corrupted double-linked list: 0x080aff40 ***

    Program received signal SIGABRT, Aborted.
    0xaf7037b2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
    (gdb) bt
    #0 0xaf7037b2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
    #1 0xaf5b4f41 in raise () from /lib/tls/libc.so.6
    #2 0xaf5b66e7 in abort () from /lib/tls/libc.so.6
    #3 0xaf5e857e in __fsetlocking () from /lib/tls/libc.so.6
    #4 0xaf5f2297 in mallopt () from /lib/tls/libc.so.6
    #5 0xaf5f110d in mallopt () from /lib/tls/libc.so.6
    #6 0xaf5efcbb in free () from /lib/tls/libc.so.6
    #7 0x0804a191 in parse (buff=0x805d3f8 "$MyINFO $ALL [AA:027]Burry <++ V:0.688,M:A,H:1/0/0,S:10>$ $0.005\001$$47605417905$|", fd=8, conn=0xa) at main.c:803
    #8 0x0804b970 in main () at main.c:948


    (gdb) x/s 0x805d3f8
    0x805d3f8: "$MyINFO $ALL [AA:027]Burry <++ V:0.688,M:A,H:1/0/0,S:10>$ $0.005\001$$47605417905$|"

    int
    parse(char *buff, int fd, PGconn *conn)
    {

    char **xp2,
    *temp,
    *tag,
    *temp2,
    *co,
    *nick,
    *ip,
    *query;
    PGresult *res;
    int x,
    i,
    total,
    total2;
    float share;
    FILE *fp;

    nick = (char *) malloc(150);
    ip = (char *) malloc(150);
    tag = (char *) malloc(150);
    query = (char *) malloc(150);

    temp = (char *) malloc(2048);
    temp2 = (char *) malloc(2048);
    co = (char *) malloc(2048);

    if (strstr(buff, "MyINFO") != NULL && strlen(buff) > 30) {
    strncpy(nick, buff + 12,
    strlen(buff + 12) -
    strlen(strstr(buff + 15, " ")));
    // fprintf(stderr, "Nick:%s\n", nick);
    xp2 = explode(buff, "$", &total2);
    if (total2 >= 6) {
    if (strstr(xp2[2], "M:") != NULL)
    strncpy(tag, strstr(xp2[2], "M:") + 2, 1);
    share = atof(xp2[6]);
    if (strlen(strstr(nick, " ") + 1) > 49)
    return 1;
    strcpy(nick, strstr(nick, " ") + 1);
    fprintf(stderr,
    "Nick %s jest w trybie %s i udostepnia %.f (%s) bajtow.\n",
    nick, tag, share, xp2[6]);
    checkshare(nick, tag, share, fd);
    }

    checkip(nick, fd);

    memset(tag, 0, 30);
    memset(nick, 0, 30);
    } else if (strstr(buff, "Bad nickname") != NULL) {
    fprintf(stderr, "[%d]%s\n", total, buff);
    exit(0);
    } else
    fprintf(stderr, "[%d]%s\n", total, buff);


    mfree(temp);
    //printf("po2\n");fflush(0);
    mfree(tag);
    //printf("po3\n");fflush(0);
    mfree(temp2);
    //printf("po4\n");fflush(0);
    mfree(co);
    //printf("po5\n");fflush(0);
    mfree(nick);
    //printf("po6\n");fflush(0);
    mfree(ip);
    //printf("po7\n");fflush(0);
    mfree(query);

    return 0;
    }


    I think the problem is with explode function, but i used it in other programs and had no problems.


    char *
    substr(char *src, const int start, const int count)
    {
    char *tmp;
    tmp = (char *) malloc(count + 1);
    if (tmp == NULL) {
    // libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);

    return NULL;
    }

    strncpy(tmp, src + start, count);
    tmp[count] = '\0';

    return tmp;
    }

    char **explode(char *src, const char *token, int *total)
    {
    char **str;
    register int i, j, count, item, start;
    int len;

    if (!src || !token) {
    *total = 0;

    return NULL;
    }

    count = item = start = 0;
    j = 1;
    len = strlen(src);

    // Scans the string to verify how many pieces we heave
    for (i = 0; i < len; i++) {
    if (src == *token)
    count++;
    }

    // We don't have any piece to explode. Returning...
    if (count == 0) {
    *total = 0;

    return NULL;
    }

    // Allocate memory for the structure ( count lines )
    str = (char **)malloc(count * sizeof(char *));
    if (str == NULL)
    return NULL;
    //libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);

    // Now we'll going to get each piece and store it in the structure
    for (i = 0; i < len; i++) {
    if (src != *token)
    j++;
    else {
    // Found one. Now we need to allocate memory to store data
    str[item] = (char *)malloc(j-start);
    if (str[item] == NULL) {
    // libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);

    return NULL;
    }

    *(str+item) = substr(src, start, j-1);

    str[item][j-start-1] = '\0';
    item++;
    start = j++;
    }
    }

    // The last one
    *(str+count) = (char *)malloc(j);
    if (str[count] == NULL)
    return NULL;
    //libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);

    str[count] = substr(src, start, j);
    str[count][j-start] = '\0';
    *total = ++count;

    return str;
    }

    It is part of libcgi library which is free.


    Basiclly i'm stuck =\
    I'm trying to write a nice DC++ bot and this is used to parse messages from server.
    Thing is that program crashes very often so it's kinda useless =\

    I would really apricciate any help!

    And sorry for my poor english =\

    --
    Best regards,
    Oskar.
     
    oskar, Oct 10, 2006
    #1
    1. Advertising

  2. oskar

    Guest

    oskar wrote:

    > Hello everyone. I have a problem with my program... and i kinda dunno what to do.. everything seems to work ok, but i'm getting
    > corrupted double-linked list error =\.


    In which case, it doesn't "work ok" - does it?

    I've not analysed your code in detail, but I've quickly found one
    buffer overrun, and I wouldn't like to swear that you don't have
    more...

    > char **explode(char *src, const char *token, int *total)
    > {

    [snip]
    >
    > // Allocate memory for the structure ( count lines )
    > str = (char **)malloc(count * sizeof(char *));


    So you've allocated room for "count" pointers... str to (str + count
    -1) or str[0] to str[count -1] - right?

    > // The last one
    > *(str+count) = (char *)malloc(j);
    > if (str[count] == NULL)
    > return NULL;


    What's wrong with this picture?
     
    , Oct 10, 2006
    #2
    1. Advertising

  3. You have a lot of risky string manipulation you're doing there!

    All those strncpy's and strcpys need protection so you don't overrun
    the size of the buffers.

    In most of the strncpy's, you're not using the length parameter to
    avoid buffer overflow, you're using it to copy a certain, usually
    unchecked substring.
     
    Ancient_Hacker, Oct 10, 2006
    #3
  4. oskar

    Flash Gordon Guest

    wrote:
    > oskar wrote:


    <snip>

    >> // Allocate memory for the structure ( count lines )
    >> str = (char **)malloc(count * sizeof(char *));

    >
    > So you've allocated room for "count" pointers... str to (str + count
    > -1) or str[0] to str[count -1] - right?


    <snip>

    In addition the cast is not required. If the compiler complains without
    it then that just means you have done something else wrong such as not
    including stdlib.h or using a C++ compiler instead of a C compiler. A
    far better (less error prone) form for the malloc is
    str = malloc(count * sizeof *str);

    Also, to the OP, please don't use tabs when posting to Usenet. Sometimes
    they get stripped from posts loosing all of the formatting.
    --
    Flash Gordon
     
    Flash Gordon, Oct 10, 2006
    #4
  5. Flash Gordon <> wrote:

    > Also, to the OP, please don't use tabs when posting to Usenet. Sometimes
    > they get stripped from posts loosing all of the formatting.


    Indeed the format, which may also manifest in other newsreaders as
    absurdly over-indented code, is verily "loosed" upon all they that hath
    not the same newsreader as OP, at which there be rarely much
    rejoicing.

    --
    C. Benson Manica | I *should* know what I'm talking about - if I
    cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Oct 10, 2006
    #5
  6. oskar

    Flash Gordon Guest

    Christopher Benson-Manica wrote:
    > Flash Gordon <> wrote:
    >
    >> Also, to the OP, please don't use tabs when posting to Usenet. Sometimes
    >> they get stripped from posts loosing all of the formatting.

    >
    > Indeed the format, which may also manifest in other newsreaders as
    > absurdly over-indented code, is verily "loosed" upon all they that hath
    > not the same newsreader as OP, at which there be rarely much
    > rejoicing.


    I've just loosed my mind, but don't worry, it's 'armless. :)

    Getting back to the topic, its loosed because the link to the rest of me
    has been corrupted. Fortunately using a debugger I can see what has gone
    wrong so I'll just patch the pointer for now and correct the off-by-one
    error later.
    --
    Flash Gordon
    Dyslexic software developer,
    At least the compiler ensures I spell variable names consistently wrong.
     
    Flash Gordon, Oct 10, 2006
    #6
  7. On Tue, 10 Oct 2006 14:04:51 +0000 (UTC), oskar <>
    wrote:

    >Hello everyone. I have a problem with my program... and i kinda dunno what to do.. everything seems to work ok, but i'm getting
    >corrupted double-linked list error =\.
    >
    >


    snip system specific debug info

    >int
    >parse(char *buff, int fd, PGconn *conn)
    >{
    >
    > char **xp2,
    > *temp,
    > *tag,
    > *temp2,
    > *co,
    > *nick,
    > *ip,
    > *query;
    > PGresult *res;
    > int x,
    > i,
    > total,
    > total2;
    > float share;
    > FILE *fp;
    >
    > nick = (char *) malloc(150);
    > ip = (char *) malloc(150);
    > tag = (char *) malloc(150);
    > query = (char *) malloc(150);
    >
    > temp = (char *) malloc(2048);
    > temp2 = (char *) malloc(2048);
    > co = (char *) malloc(2048);


    It would be prudent to get rid of the casts and check that these
    succeeded.

    >
    > if (strstr(buff, "MyINFO") != NULL && strlen(buff) > 30) {
    > strncpy(nick, buff + 12,
    > strlen(buff + 12) -
    > strlen(strstr(buff + 15, " ")));


    What happens if there is no space at or after buff+15?

    > // fprintf(stderr, "Nick:%s\n", nick);
    > xp2 = explode(buff, "$", &total2);


    There is no prototype in scope for explode.

    > if (total2 >= 6) {


    There are paths through explode which don't set total2.

    > if (strstr(xp2[2], "M:") != NULL)
    > strncpy(tag, strstr(xp2[2], "M:") + 2, 1);
    > share = atof(xp2[6]);
    > if (strlen(strstr(nick, " ") + 1) > 49)
    > return 1;
    > strcpy(nick, strstr(nick, " ") + 1);
    > fprintf(stderr,
    > "Nick %s jest w trybie %s i udostepnia %.f (%s) bajtow.\n",
    > nick, tag, share, xp2[6]);
    > checkshare(nick, tag, share, fd);
    > }
    >
    > checkip(nick, fd);
    >
    > memset(tag, 0, 30);
    > memset(nick, 0, 30);
    > } else if (strstr(buff, "Bad nickname") != NULL) {
    > fprintf(stderr, "[%d]%s\n", total, buff);
    > exit(0);
    > } else
    > fprintf(stderr, "[%d]%s\n", total, buff);
    >
    >
    > mfree(temp);
    > //printf("po2\n");fflush(0);
    > mfree(tag);
    > //printf("po3\n");fflush(0);
    > mfree(temp2);
    > //printf("po4\n");fflush(0);
    > mfree(co);
    > //printf("po5\n");fflush(0);
    > mfree(nick);
    > //printf("po6\n");fflush(0);
    > mfree(ip);
    > //printf("po7\n");fflush(0);
    > mfree(query);
    >
    > return 0;
    >}
    >
    >
    >I think the problem is with explode function, but i used it in other programs and had no problems.


    Unfortunately, one of the more obnoxious forms of undefined behavior
    is to appear to work as expected.

    >
    >
    >char *
    >substr(char *src, const int start, const int count)
    >{
    > char *tmp;
    > tmp = (char *) malloc(count + 1);
    > if (tmp == NULL) {
    > // libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
    >
    > return NULL;
    > }
    >
    > strncpy(tmp, src + start, count);
    > tmp[count] = '\0';
    >
    > return tmp;
    >}
    >
    >char **explode(char *src, const char *token, int *total)
    >{
    > char **str;
    > register int i, j, count, item, start;
    > int len;
    >
    > if (!src || !token) {
    > *total = 0;
    >
    > return NULL;
    > }
    >
    > count = item = start = 0;
    > j = 1;
    > len = strlen(src);
    >
    > // Scans the string to verify how many pieces we heave
    > for (i = 0; i < len; i++) {
    > if (src == *token)
    > count++;
    > }
    >
    > // We don't have any piece to explode. Returning...
    > if (count == 0) {
    > *total = 0;
    >
    > return NULL;
    > }
    >
    > // Allocate memory for the structure ( count lines )
    > str = (char **)malloc(count * sizeof(char *));
    > if (str == NULL)
    > return NULL;
    > //libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
    >
    > // Now we'll going to get each piece and store it in the structure
    > for (i = 0; i < len; i++) {
    > if (src != *token)
    > j++;
    > else {
    > // Found one. Now we need to allocate memory to store data
    > str[item] = (char *)malloc(j-start);
    > if (str[item] == NULL) {
    > // libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
    >
    > return NULL;
    > }
    >
    > *(str+item) = substr(src, start, j-1);


    This causes a memory leak. *(str+item) is identical to str[item]. You
    just allocated space and stored the address returned by malloc in
    str[item]. Here you replace that address with the one returned by
    substr.

    >
    > str[item][j-start-1] = '\0';
    > item++;
    > start = j++;
    > }
    > }
    >
    > // The last one


    Unfortunately, you are past the last element of str.

    > *(str+count) = (char *)malloc(j);


    This invokes undefined behavior. str points to an area capable of
    holding count char*. The indices of these pointers range from 0 to
    count-1. str[count] does not exist and attempting to store a value in
    it is illegal.

    > if (str[count] == NULL)
    > return NULL;
    > //libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
    >
    > str[count] = substr(src, start, j);
    > str[count][j-start] = '\0';
    > *total = ++count;
    >
    > return str;
    >}
    >
    >It is part of libcgi library which is free.
    >
    >
    >Basiclly i'm stuck =\
    >I'm trying to write a nice DC++ bot and this is used to parse messages from server.
    >Thing is that program crashes very often so it's kinda useless =\
    >
    >I would really apricciate any help!
    >
    >And sorry for my poor english =\



    Remove del for email
     
    Barry Schwarz, Oct 11, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sydex
    Replies:
    12
    Views:
    6,508
    Victor Bazarov
    Feb 17, 2005
  2. Replies:
    1
    Views:
    1,471
    Artie Gold
    Feb 28, 2006
  3. Gabriel Genellina
    Replies:
    1
    Views:
    575
    Gabriel Genellina
    Feb 25, 2009
  4. Duncan Grisby
    Replies:
    0
    Views:
    1,463
    Duncan Grisby
    Feb 25, 2009
  5. eduard
    Replies:
    2
    Views:
    186
    eduard
    Jan 28, 2006
Loading...

Share This Page