Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Feb 2007 09:52:44 +0200
From:      Vasil Dimov <vd@FreeBSD.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        Daniel Crandall <dcrandall@simplestar.com>, bug-followup@FreeBSD.org, freebsd-amd64@freebsd.org, rwatson@freebsd.org, wollman@freebsd.org, kensmith@freebsd.org
Subject:   Re: amd64/109584: zdump doesn't work
Message-ID:  <20070228075244.GA36076@qlovarnika.bg.datamax>
In-Reply-To: <20070228064337.GA34966@qlovarnika.bg.datamax>
References:  <200702271920.l1RJK8fo042824@freefall.freebsd.org> <200702271454.14774.jhb@freebsd.org> <20070228064337.GA34966@qlovarnika.bg.datamax>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Feb 28, 2007 at 08:43:37 +0200, Vasil Dimov wrote:
[...]
> it hangs in this loop:
> 
> src/lib/libc/stdtime/localtime.c:
> 1320         y = EPOCH_YEAR;
> 1321 #define LEAPS_THRU_END_OF(y)    ((y) / 4 - (y) / 100 + (y) / 400)
> 1322         while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
> 1323                 long    newy;
> 1324
> 1325                 newy = y + days / DAYSPERNYEAR;
> 1326                 if (days < 0)
> 1327                         --newy;
> 1328                 days -= (newy - y) * DAYSPERNYEAR +
> 1329                         LEAPS_THRU_END_OF(newy - 1) -
> 1330                         LEAPS_THRU_END_OF(y - 1);
> 1331                 y = newy;
> 1332         }
> 
> where days oscillates between -1 and 365, y and newy between
> -292277022654 and -292277022655. E.g. try so see what happens if you
> enter the loop with days=365 and y=-292277022655.

What about this patch:

--- localtime.c_infloop.diff begins here ---
Index: localtime.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdtime/localtime.c,v
retrieving revision 1.41
diff -u -r1.41 localtime.c
--- localtime.c	19 Jan 2007 01:16:35 -0000	1.41
+++ localtime.c	28 Feb 2007 07:40:24 -0000
@@ -1326,8 +1326,8 @@
 		if (days < 0)
 			--newy;
 		days -= (newy - y) * DAYSPERNYEAR +
-			LEAPS_THRU_END_OF(newy - 1) -
-			LEAPS_THRU_END_OF(y - 1);
+			LEAPS_THRU_END_OF(newy - (newy > 0 ? 1 : -1)) -
+			LEAPS_THRU_END_OF(y - (y > 0 ? 1 : -1));
 		y = newy;
 	}
 	tmp->tm_year = y - TM_YEAR_BASE;
--- localtime.c_infloop.diff ends here ---

-- 
Vasil Dimov
gro.DSBeerF@dv
%
Everything should be made as simple as possible, but not simpler.
                -- Albert Einstein



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070228075244.GA36076>