1

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;
    }
river
  • 694
  • 6
  • 22
  • 1
    Does your compiler print some "signed/unsigned mismatch" warnings or similar when you compile? – Gerhardh Jul 24 '18 at 07:39
  • Yes, I ignored these warning – river Jul 24 '18 at 10:05
  • 1
    @river Note that posting the warning received helps 1) diagnosing the problem 2) makes the post more valuable as others may find this based on a search of the warning. – chux - Reinstate Monica Jul 24 '18 at 12:31
  • 2
    You get a warning. You ignore it. You find strange behaviour in the same line. And you still don't think, handling the warning or telling us about it might be a good idea? – Gerhardh Jul 24 '18 at 20:18
  • Thanks for your suggestion, I should take serious care about these warnings. In fact, gcc doesn't give me the warning of the comparison statement. @Gerhardh – river Jul 25 '18 at 03:38
  • Can you give me a better title to describe my post? GCC doesn't give me any warning about `int i = -1 ; if( i > sizeof(i) ) { printf("%d\n", i); }` @chux – river Jul 25 '18 at 03:46
  • What about "How can (-1 >= sizeof(buffer)) ever be true?" – Gerhardh Jul 25 '18 at 07:28
  • @river [I ignored these warning](https://stackoverflow.com/questions/51489839/how-can-1-sizeofbuffer-ever-be-true-program-fail-to-get-right-results-o?noredirect=1#comment89959653_51489839) and [GCC doesn't give me any warning about...](https://stackoverflow.com/questions/51489839/how-can-1-sizeofbuffer-ever-be-true-program-fail-to-get-right-results-o?noredirect=1#comment89989730_51489839) imply compilation generated some warnings for something. Posting those warnings adds value to the post. – chux - Reinstate Monica Jul 25 '18 at 11:09

1 Answers1

3

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

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256