Microsoft Issues Workaround For Zune Freeze 277
UnknowingFool writes "As a followup to the Zune New Year's Eve meltdown, Microsoft has issued a workaround for what some users have correctly guessed was a bug caused by a leap year. To recover from the problem, let the Zune drain the batteries and restart it after noon on January 1, 2009. Many sites are reporting that Microsoft has 'fixed' the issue, but technically all Microsoft has done is to ask users to wait out the conditions that triggered the bug. Unless a software patch comes out, Zunes will suffer the same problem again in four years." Reader ndtechnologies adds, "According to posts in the Toshiba forum at anythingbutipod.com, the same bug that shut down millions of Zune 30's also affects the Toshiba Gigabeat S. The Zune 30 is based off of the Gigabeat S series and was co-developed by Microsoft with Toshiba."
Sorry to gloat but (Score:1, Informative)
My iPod, Macbook, iPhone, Time Capsule, Airport Express, and Apple TV are all working just fine!
The Source Code (Score:5, Informative)
Re:Can anyone explain this bug? (Score:5, Informative)
Here's the actual buggy code [pastie.org].
The error is infinite loop in ConvertDays(), starting at line 249. The first loop does not cope with "IsLeapYear() == true" when "days == 366"
Cause of the Zune crash? Third party drivers (Score:2, Informative)
A quote from the ZuneBoards forum:
http://www.zuneboards.com/forums/zune-news/38143-cause-zune-30-leapyear-problem-isolated.html [zuneboards.com]
Re:Can anyone explain this bug? (Score:5, Informative)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
source code that caused the bug.
Re:The Source Code (Score:1, Informative)
10 points for looking correct, but minus several million for not being correct.
Earlier in 2008, the bug did not exist. In the newest firmware, it does. that means the bug was introduced in 2008.
The copyright on that code ended in 2007, so the code hasn't been edited since then.
Clearly, this is not the code you are looking for.
Re:Can anyone explain this bug? (Score:5, Informative)
In case you can't see how this fails: On December 31st in a leap year, days is counted down to 366 like it's supposed to, and then the IsLeapYear() test is true, but days>366 is not, so the loop body does nothing and the while becomes an infinite loop.
This code can not possibly have been accepted in any kind of code review. Someone would have pointed out that there are O(1) formulas for calendar calculations.
Re:It probably won't last another 4 years (Score:5, Informative)
In UK law at least this is a significant difference... you can never tell in the US though.
Re:It probably won't last another 4 years (Score:3, Informative)
If the microwave was only 5 years old and it broke down, you are covered in England and Wales by consumer protection laws if it less than six years old and it break down. Just as long as you can prove it was not accidental damage, your covered for a free repair. :)
Just something for the UK readers here. Covers anything electronic.
Re:Zune 80 (Score:3, Informative)
Re:Can anyone explain this bug? (Score:2, Informative)
Re:It probably won't last another 4 years (Score:5, Informative)
My microwave has a firmware bug. After I heat something, if the next button on the keypad I press is anything other than "Reset", it locks up. It's incredibly irritating (since I'm usually putting something else in and trying to enter a new cooking time). That said, the microwave cost under $50...
Re:Out of curiosity... (Score:2, Informative)
Why does a music player need to know the date or time at all?
For the DRM to work.
Non-DRM using pirates win again, arrrr!
Re:Zune 80 (Score:4, Informative)
Q: Why is this issue isolated to the Zune 30 device?
It is a bug in a driver for a part that is only used in the Zune 30 device.
Re:Can anyone explain this bug? (Score:5, Informative)
The function iteratively converts days into years. If there are more days left in the days variable than there are days in a year (365), then the days in that year are subtracted from the days variable and added as 1 year to the year variable.
It starts with year=1980, because the RTC counts days since 1/1/1980 (inclusive). For normal years, it subtracts 365 days and adds a year. After the first iteration, year is 1981 and days is the number of days since 1/1/1981 (inclusive). If the loop is currently looking at a leap year, then 366 days are subtracted from the days variable and 1 year is added to the year variable. So far the code looks like this:
while (days>365){
if (IsLeapYear(year)){
days-=366;
year+=1;
}else{
days-=365;
year+=1;
}
}
The crazy thing is that someone must have looked at the edge case in that code: The last day of a leap year. On that day, the above code fails by incrementing year once too often, because at the beginning of the last iteration, the loop test indicates that there are more days in the days variable than there are in a year, but there are not, because a leap year has 366 days. That edge case is caught by the second if:
while (days>365){
if (IsLeapYear(year)){
if (days>366){
days-=366;
year+=1;
}
}else{
days-=365;
year+=1;
}
}
The loop goes into the last iteration because of the loop condition which is on day short, then the IsLeapYear test selects the first branch, and instead of blindly incrementing the year and subtracting 366 days, there is an extra check if there are really more days left to make a full year...and then it fails to handle the only case where the code fails without that extra check. It should simply break the loop:
while (days>365){ // days==366 && IsLeapYear(year): end of calculation
if (IsLeapYear(year)){
if (days>366){
days-=366;
}else{
break;
}
}else{
days-=365;
}
year+=1;
}
(Matt's code always reduces the day count by 366. 1980 was a leap year.)
Re:It probably won't last another 4 years (Score:2, Informative)
They start from 1980. You can see it on line 58. ;-)
And looking at line 59 you can see that there is planned obsolescence(!) for the year 2080. Zune owners should demand a refund
Re:It probably won't last another 4 years (Score:5, Informative)
It ought to simply be
while (days > daysInYear(year))
{
days -= daysInYear(year);
year += 1;
}
Hey, c'mon now; programmers are almost universally judged by their bosses by the number of lines of code they produce. The (buggy) MS code used 16 lines to do what you did in 5 lines. Therefore, the original (buggy) code is considered more than 3 times better than yours. No programmer interested in a good professional career would write code so simply and obviously correct.
This isn't really a joke. One a project a few years ago, I fixed several bugs by doing rewrites like yours, resulting in fewer lines of code. My record actually had a note indicating that I had negative productivity during that period, and my superiors had a real problem giving me a good review because of it.
Yes, I did find another job soon thereafter. But that wasn't the last time something like that happened.
(And I would probably save the first call of daysInYear(year) in a local variable, which would make the code a bit faster. But I could declare the local on a separate line, incrementing the line count, so it would look good to the line counters. ;-)
Re:It probably won't last another 4 years (Score:4, Informative)
Nah; most code-size measurements exclude comments, on the grounds that comments aren't executed by the computer, and thus aren't code. This puts subtle pressure on the programmers to not write comments, since this just takes time that leads to being behind schedule.
It's hard to imagine any rating system that's more screwed up than the system used in most companies to rate the output of their programmers. If they were consciously trying to sabotage the software, they probably wouldn't come up with any schemes nearly as effective as judging programmers by lines of code produced.
Re:Out of curiosity... (Score:2, Informative)
So it knows when to expire the DRM-encumbered tracks that might have been loaded on it. Hell, I'm surprised it doesn't have GPS so it can enforce region restrictions on "content" too.
Re:Can anyone explain this bug? (Score:1, Informative)
The while (true) loop is bad, bad practice.
I have been coding for twenty-two years. Trust me on this, my friend.
Re:Out of curiosity... (Score:3, Informative)
Anything from month-to-month media rental (for example, the Zune Pass) to simply displaying the time like a watch (how many people do you know who pull out their cell phones to check the time? I know at least 4, and it amuses me to no end, but in any case a "current time" display was one of the most-requested features for the Zune 3.0 firmware).