Zunes bug

J

jacob navia

Millions of Zunes players froze on December 31st 2009.
The problem lies in the following code from the time keeping
device driver.

year = ORIGINYEAR; /* = 1980 */

while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
 
T

Tomás Ó hÉilidhe

year = ORIGINYEAR; /* = 1980 */

while (days > 365)
{
   if (IsLeapYear(year))
   {
     if (days > 366)
     {
       days -= 366;
     year += 1;
     }
   }
   else
   {
     days -= 365;
     year += 1;
   }

}


I don't get it... what's it supposed to do? And what does it actually
do?
 
W

Willem

jacob navia wrote:
) Millions of Zunes players froze on December 31st 2009.

ITYM December 31st of any leap year. 2008 for example.

But why post this ? MS bashing ? I agree, it's shitty code.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
J

jacob navia

Malcolm said:
days gives the number of days elapsed since midnight Dec 31 1979. The
code counts down to extract the year.
If days == 365 and it is a leap year, however, the code goes into an
infinite loop.

.... and the infinite loop is perceived by the poor user
of the Zunes music player as "freezes all over when booting"

Happily, the bug lasts only a day. It will repeat itself next
Dec 31st 2012.
 
T

Tom

Willem said:
But why post this ? MS bashing ? I agree, it's shitty code.

Arguably it's useful to show how such a small coding error can cause such big
problems, though I think most people on c.l.c. know this. That sort of stuff
would be more suited to comp.programming, however.
 
C

Charles Richmond

jacob said:
... and the infinite loop is perceived by the poor user
of the Zunes music player as "freezes all over when booting"

Happily, the bug lasts only a day. It will repeat itself next
Dec 31st 2012.

And dealing with Mi$uck, you should be *happy* that they only
robbed you of *one* day out of four years!!!
 
C

CBFalconer

Tom said:
Arguably it's useful to show how such a small coding error can
cause such big problems, though I think most people on c.l.c.
know this. That sort of stuff would be more suited to
comp.programming, however.

No it isn't suited to comp.programming. It would get by, because
that group is not too fussy about subject matter, but it is
primarily devoted to algorithms.

It is C code, so quite suited to c.l.c.
 
M

MisterE

if (days > 366)
{
days -= 366;
year += 1;
}

Goes to show that no one even bothered to put the clocks forward and
actually try end of year turn overs. 100 year testing is standard practice
even with small scale produced devices I make and we sure as hell don't sell
millions of them all over the world! Anyway from what I understand the code
is example code from the RTC chip manufacturer, so microsoft are to lazy to
write their own code, and don't bother testing what code they do end up
using.
 
J

jacob navia

christian.bau said:
Just noticed: The code for this function could _not_ be tested in less
than one second :)

This bug is hard, and nI posted it here because I have done
it many times.

Contrary to the geniuses here I do make mistakes, and this mistake
could have been mine.

With 20/20 hindsight it is easy to see, but when you are programming
it is surely not so easy. And even if I posted it here as a bug, there
was at least one poster that did not see it.
 
R

Radoslav Dorcik

Contrary to the geniuses here I do make mistakes, and this mistake
could have been mine.

With 20/20 hindsight it is easy to see, but when you are programming
it is surely not so easy. And even if I posted it here as a bug, there
was at least one poster that did not see it.

I would consider this bug in "typo" bug group, bu In the case of test
driven
programming it can be hidden in uncovered % which are accepted by
project :)
 
C

Charles Richmond

christian.bau said:
There is code that contains obviously no errors. And there is code
that contains no obvious errors. (Don't remember who wrote this the
first time).

This code falls into the second category (for the right value of
"obvious").

There is the following quote by C.A.R. Hoare:

There are two ways of constructing a software design. One way is to make
it so simple that there are obviously no deficiencies. And the other way
is to make it so complicated that there are no obvious deficiencies.
 
R

Richard Tobin

christian.bau said:
There is code that contains obviously no errors. And there is code
that contains no obvious errors. (Don't remember who wrote this the
first time).

It was Tony Hoare (famed for Quicksort and Communicating Sequential
Processes) who said that there are two ways to construct a
piece of software: one is to make it so simple that there are
obviously no errors; the other is to make it so complicated that there
are no obvious errors.

-- Richard
 
J

John Bode

There is code that contains obviously no errors. And there is code
that contains no obvious errors. (Don't remember who wrote this the
first time).

This code falls into the second category (for the right value of
"obvious").

I hate to admit it, it took me more than a couple of minutes to figure
out the problem, but I was never a genius. The strictly-greater-than
was tickling my ain't-right meter to a small degree, but I didn't see
the real problem until walking through it a few times.
 
G

Guest

It was Tony Hoare (famed for Quicksort and Communicating Sequential
Processes) who said that there are two ways to construct a
piece of software: one is to make it so simple that there are
obviously no errors; the other is to make it so complicated that there
are no obvious errors.

my quote file has that as:
"There are two ways of constructing a software design: One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies. The first method is far more difficult."

and indeed as Tony Hoare
 
S

Spiros Bousbouras

Actually, it is not a "typo" bug at all.

If you are an experienced programmer, you have encountered code that
just does the right thing (and sometimes contains "typos"). But when
you look at this short bit of code, it smacks you right in the face as
being unnecessary complicated and therefore error prone. It uses a
programming style that I would call "asking for trouble". Of course it
is possible to make such code work correctly with enough effort and
enough testing, but a good programming style achieves the same with
much less effort.

Indeed. Here's another example of "asking for trouble" code again from
http://pastie.org/349916

static int IsLeapYear(int Year)
{
int Leap;

Leap = 0;
if ((Year % 4) == 0) {
Leap = 1;
if ((Year % 100) == 0) {
Leap = (Year%400) ? 0 : 1;
}
}

return (Leap);
}

Note the triple (counting the ? operator) nesting and the construct
Leap = (Year%400) ? 0 : 1 which practically invites you to get
the test the wrong way round.

What's wrong with writing

static int IsLeapYear(int Year) {
if ( Year % 4 != 0 ) return 0 ;
if ( Year % 100 != 0 ) return 1 ;
if ( Year % 400 == 0 ) return 1 ;
return 0 ;
}

Or perhaps

static int IsLeapYear(int Year) {
if (Year % 400 == 0 || ( Year%4 == 0 && Year%100 != 0 ))
return 1 ;
else
return 0 ;
}
 
K

Keith Thompson

Spiros Bousbouras said:
What's wrong with writing

static int IsLeapYear(int Year) {
if ( Year % 4 != 0 ) return 0 ;
if ( Year % 100 != 0 ) return 1 ;
if ( Year % 400 == 0 ) return 1 ;
return 0 ;
}

Or perhaps

static int IsLeapYear(int Year) {
if (Year % 400 == 0 || ( Year%4 == 0 && Year%100 != 0 ))
return 1 ;
else
return 0 ;
}

Or:

static int IsLeapYear(int Year) {
return Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0);
}
 
C

CBFalconer

Spiros said:
.... snip ...

Indeed. Here's another example of "asking for trouble" code again
from http://pastie.org/349916

static int IsLeapYear(int Year) {
int Leap;

Leap = 0;
if ((Year % 4) == 0) {
Leap = 1;
if ((Year % 100) == 0) {
Leap = (Year%400) ? 0 : 1;
}
}
return (Leap);
}

Note the triple (counting the ? operator) nesting and the construct
Leap = (Year%400) ? 0 : 1 which practically invites you to get
the test the wrong way round.

I never use the ?: operator, so I look at it suspiciously, and I
would probably find the bug (assuming there is a bug there). My
point with this code is that it should forbid negative Year, and
any Year smaller than roughly 1650. I.e:

Leap = -1; /* failure signal */
if (MIN_LEAP < Year) {
/* code to decide and set Leap */
}
return Leap;
 

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

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top