corrupted double-linked list

O

oskar

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 =\
 
M

mark_bluemel

oskar said:
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?
 
A

Ancient_Hacker

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.
 
F

Flash Gordon

oskar wrote:
// 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.
 
C

Christopher Benson-Manica

Flash Gordon said:
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.
 
F

Flash Gordon

Christopher said:
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.
 
B

Barry Schwarz

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Fibonacci 0
Adding adressing of IPv6 to program 1
linked list 19
My linked list 38
Double linked list 9
Double Linked List test 5
C language. work with text 3
"corrupted double-linked list error 1

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top