Sonntag, 4. Januar 2009

 

Schaltjahr-Bug in Zune

Zune - das ist das Microsoft-Pendant zu iTunes - ist zu Silvester abgestürzt, genauer hängen geblieben. Genauere Informationen finden sich auf zum Beispiel auf Heise1 bzw. Heise2. Es gibt in diversen Foren plausible Erklärungen für den Ausfall des Ur-Zune. Für den Fehler ist wahrscheinlich nicht direkt Microsoft verantwortlich sondern der Hersteller der im Player verbauten Hardware.

Ich präsentiere hier den relevanten Ausschnit des gesamten Quelltexts.

Zunächst die gesamte Funktion, in der der Fehler zu finden ist:

//------------------------------------------------------------------------------
//
// Function: ConvertDays
//
// Local helper function that split total days since Jan 1, ORIGINYEAR into
// year, month and day
//
// Parameters:
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
{
int dayofweek, month, year;
UINT8 *month_tab;

//Calculate current day of the week
dayofweek = GetDayOfWeek(days);

year = ORIGINYEAR;

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


// Determine whether it is a leap year
month_tab = (UINT8 *)((IsLeapYear(year))? monthtable_leap : monthtable);

for (month=0; month<12; month++)
{
if (days <= month_tab[month])
break;
days -= month_tab[month];
}

month += 1;

lpTime->wDay = days;
lpTime->wDayOfWeek = dayofweek;
lpTime->wMonth = month;
lpTime->wYear = year;

return TRUE;
}



Hier das relevante Code-Stück noch mal herausgenommen:


year = ORIGINYEAR; // == 1980
while (day > 365)
{
if (IsLeapYear(year))
{
numOfLeap++;
if (day > 366)
{
day -= 366;
year += 1;
}
}
else
{
day -= 365;
year += 1;
}
}


Das Jahr 2008 ist ein Schaltjahr (IsLeapYear(year) liefert true), d.h. der 31.12.2008 ist der 366 Tag. Die Schleife while (day > 365) wird nie beendet, da in der Abfrage if (day > 366) der Tag mit der Nummer 366 nie berücksichtigt wird. Man hat in diesem Fall also eine Endlosschleife (day wird in diesem Fall nie verändert!).

Labels: ,


Kommentare:
war das break schon drin? weil mit dem break sehe ich keinen grund für eine endlosschleife.
 
Das break ist schon eine Reparatur im Oiginal-Code war das nicht drinnen. Wieso das break hier in dieses Post gekommen ist, frage ich mich allerdings auch...
 
Ich habe mir gerade den Original-Code angesehen. Die Schleife kommt an zwei Stellen vor, einmal mit break und einmal ohne break. Hab wohl das falsche Code-Stück geposted. Werde das demnächst korrigieren.
 
Vielen Dank an Herrn Hecher, der mich mit seinem Kommentar auf einen "Fehler im Fehler" aufmerksam gemacht hat. Jetzt werden die fehlerhaften Code-Stücke angezeigt.
 

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]