The program runs into impossible execution routine, where if( len >= sizeof(buff) )
should never be true in reality, however it happens. As is shown by the printf
output len:-1__1024
: len
, whose value is -1, is larger than sizeof(buff)
, which is 1024. It's amazing.
select return value -1 ,4
select: Interrupted system call
-1_0x66a1e0
len:-1__1024
*** glibc detected *** /home/fang/Desktop/work/fw: free(): invalid pointer: 0x000000000066a1e0 ***
The following is the execution code.
while (1) {
if( len >= sizeof(buff) ) { //here len==-1, sizeof(buff)==1024
printf("len:%d__%d %s\n", len, sizeof(buff), tmp1); //oops
free(tmp1);
tmp1 = buff;
}
len = get_next_event(&tmp1, sizeof(buff));
printf("%d_%p\n",len, tmp1);
if( len > 0 ){
tmp = strtok_r(tmp1, "\n\r", &saveptr);
// ignore following codes ......
I think the bug is resulted from the stack pollution, but it's hard to find out the secret. To mention more, I list the code of function get_next_event
. Wish for your help ^_^
int get_next_event(char **buf, int len)
{
struct timeval tv;
int tmp;
socklen_t sin_size;
struct sockaddr_in client_addr;
sin_size = sizeof(client_addr);
FD_ZERO(&fdsr);
FD_SET(sock_fd, &fdsr);
tv.tv_sec = 1;
tv.tv_usec = 0;
if (new_fd != 0) {
FD_SET(new_fd, &fdsr);
}
tmp = select(maxsock + 1, &fdsr, NULL, NULL, &tv);
if (tmp < 0) {
printf("select return value %d ,%d\n", tmp, errno);
perror("select");
return -1;
} else if (tmp == 0) {
return 0;
}
-1, is larger than sizeof(buff). It's amazing.
It is.
len >= sizeof(buff)
is the same as -1 >= sizeof(buff)
same as (size_t)-1 >= sizeof(buff)
--> SIZE_MAX >= sizeof(buff)
--> which is certainly true.
When an int
like len
is compared to the unsigned type size_t
, the result of sizeof
, one of the types is converted to the other based on which have a wider range.
In this case, it is usually the int
converts to the unsigned size_t
. (size_t)-1
is the greatest value of size_t
and is certainly larger than sizeof(buff)
.
It is unclear why len == -1
without seeing more code.
Yet in this case, I'd recommend to use size_t len = 0
to mend code.
When printing, use the a matching print specifier like "%zu"
printf("size:%zu\n", sizeof buff);
OP's code, lacking a warning, with printf("%d\n", sizeof(buff));
implies warnings are not fully enabled. Save time. Enable all warnings.