RE: serious libwww timers bug

Here is a small program which prints out times when libwww timers will not work
Duration of a timer 'outage' equals to timer's timeout (for repetitive relative timers)

Here are the dates and times when it's going to happen (in EST or GMT-05:00)
We were able to reproduce the problem consistently in our test lab for given times.

Next event: Sun Apr 18 19:32:39 2004

Next event: Mon Jun  7 12:35:26 2004

Next event: Tue Jul 27 05:38:14 2004

Next event: Tue Sep 14 22:41:01 2004

Next event: Wed Nov  3 14:43:48 2004

Next event: Thu Dec 23 07:46:36 2004

Next event: Fri Feb 11 00:49:23 2005

Next event: Fri Apr  1 17:52:10 2005

Next event: Sat May 21 11:54:57 2005

Next event: Sun Jul 10 04:57:45 2005

Next event: Sun Aug 28 22:00:32 2005

Next event: Mon Oct 17 15:03:19 2005

Next event: Tue Dec  6 07:06:07 2005

Next event: Wed Jan 25 00:08:54 2006

Next event: Wed Mar 15 17:11:41 2006

Next event: Thu May  4 11:14:29 2006

Next event: Fri Jun 23 04:17:16 2006

Next event: Fri Aug 11 21:20:03 2006

Next event: Sat Sep 30 14:22:50 2006

Next event: Sun Nov 19 06:25:38 2006

Next event: Sun Jan  7 23:28:25 2007

Next event: Mon Feb 26 16:31:12 2007

Next event: Tue Apr 17 10:34:00 2007

Next event: Wed Jun  6 03:36:47 2007

Next event: Wed Jul 25 20:39:34 2007

Next event: Thu Sep 13 13:42:21 2007

Next event: Fri Nov  2 05:45:09 2007

Next event: Fri Dec 21 22:47:56 2007

Next event: Sat Feb  9 15:50:43 2008

Next event: Sun Mar 30 08:53:31 2008

Next event: Mon May 19 02:56:18 2008

Next event: Mon Jul  7 19:59:05 2008

Next event: Tue Aug 26 13:01:53 2008

.....


#include <sys/time.h>

main()
{

int status;
struct timeval tp;
unsigned long a;

status = gettimeofday( &tp, NULL);
for (tp.tv_sec; tp.tv_sec != 0; tp.tv_sec++)
{
   a=tp.tv_sec*1000;  /* milliseconds */
/* 4294367296 = 2**32 - 600000 */
   if ( a > 4294367296UL ) {
        printf("Next event: %s\n" , ctime(&tp.tv_sec));
        tp.tv_sec += 600000;  /* timeout value */
   }
}
}


Somebody with CVS access please fix it in Library/src/wwwsys.h

typedef unsigned long long  ms_t;


Thanks a lot,
--MG


-----Original Message-----
From: www-lib-request@w3.org [mailto:www-lib-request@w3.org]On Behalf Of
Grushinskiy, Mikhail, ALABS
Sent: Monday, March 01, 2004 6:19 PM
To: www-lib@w3.org
Subject: serious libwww timers bug




I think there is a serious bug in implementation of internal timers in libwww.

I see cases when HTTimer_new() with valid parameter values causes endless 
recursion and stack overfloating.

Here is what I think is a root cause:


HTTimer_new() makes use of HTGetTimeInMillis function which supposed to return 
number of milliseconds since EPoch (00:00 January  1, 1970, UTC)


in Library/src/HTInet.c

PUBLIC ms_t HTGetTimeInMillis (void)
{
#ifdef WWW_MSWINDOWS
    return GetTickCount();
#else /* WWW_MSWINDOWS */
#ifdef HAVE_GETTIMEOFDAY
    struct timeval tp;
    gettimeofday(&tp, NULL);
    return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
#else
    return((ms_t) 0);
#endif
#endif /* !WWW_MSWINDOWS */
}

ms_t is declared as 

typedef unsigned long ms_t;

in Library/src/wwwsys.h


On my system unsigned long is 4 bytes or 32 bits.

Currently number of millisecods since epoch 
will be something like: 1 078 179 223 000 

which simply doesn't fit into ms_t (unsigned long) - 4 bytes
max 4 294 967 296


This causes major problems with timers (which end-up 
in endless recursion sometimes) due to arithmetics in 

HTTimer.c
 
    ms_t now = HTGetTimeInMillis();
    ms_t expires;
    HTTimer * pres;

    CHECKME(timer);
    expires = millis;
    if (relative)
        expires += now;
    else
        millis = expires-now;


I think correct declaration for ms_t in Library/src/wwwsys.h
should have been

typedef unsigned long long  ms_t;



See stack trace below for described problems


#0  0xc00a6d20 in ltostr ()
#1  0xc00a6e28 in ltostr ()
#2  0xc00a7584 in malloc ()
#3  0xc00824c0 in calloc ()
#4  0xc0b6c37c in HTMemory_calloc (nobj=1, size=8) at HTMemory.c:88
#5  0xc0b6b364 in HTList_addList (me=0x40041088, newObject=0x40041098 "") at HTList.c:88
#6  0xc0bd010c in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
    repetitive=1 '\001') at HTTimer.c:251
#7  0xc0bcf75c in Timer_dispatch (cur=0x400410b8, last=0x40041088) at HTTimer.c:112
#8  0xc0bd0190 in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
    repetitive=1 '\001') at HTTimer.c:259
#9  0xc0bcf75c in Timer_dispatch (cur=0x400410b8, last=0x40041088) at HTTimer.c:112
#10 0xc0bd0190 in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
    repetitive=1 '\001') at HTTimer.c:259
#11 0xc0bcf75c in Timer_dispatch (cur=0x400410b8, last=0x40041088) at HTTimer.c:112
#12 0xc0bd0190 in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
    repetitive=1 '\001') at HTTimer.c:259
#13 0xc0bcf75c in Timer_dispatch (cur=0x400410b8, last=0x40041088) at HTTimer.c:112
#14 0xc0bd0190 in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
    repetitive=1 '\001') at HTTimer.c:259
#15 0xc0bcf75c in Timer_dispatch (cur=0x400410b8, last=0x40041088) at HTTimer.c:112
#16 0xc0bd0190 in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
    repetitive=1 '\001') at HTTimer.c:259
#17 0xc0bcf75c in Timer_dispatch (cur=0x400410b8, last=0x40041088) at HTTimer.c:112
#18 0xc0bd0190 in HTTimer_new (timer=0x40041098, cbf=0x4000ea42, param=0x0, millis=600000, relative=1 '\001',
...
this goes on

I hope this will get fixed in CVS.

--MG

Received on Wednesday, 3 March 2004 13:11:42 UTC