Not a kernel guy

… in the Windows kernel team

Tuesday, December 19, 2006

Пара интересных багов.

На днях попытался собрать 64-битную версию Notepad2, благо исходники доступны. Надо сказать, что зачастую сборка изначально 32-битного приложения под x64 не доставляет никаких проблем, за исключанием множества предупреждений компилятора. Однако не в этот раз. Среди всех ошибок две показались наиболее интересными.

Первая проблема, в общем-то, не связана напрямую с 64-битностью. Одна из вспомогательных функций была объявлена следующим образом:

void RegDeleteKeyEx(HKEY, LPCSTR, BOOL*);

Её реализация представляла собой обертку вокруг RegDeleteKey, позволяющую удалять ключ реестра вместе со всеми подключами. Это работало, пока не вышла Window XP x64 и Vista. В Window XP x64 и Vista функциональность RegDeleteKey была расширена и новая версия функции получила имя “RegDeleteKeyEx”. Естественно, что две функции с одинаковым именем не смогли ужиться в одной программе (Notepad2 написан на C).

Этот пример хорошо показывает почему плохо называть обертки системных функций в стиле FooBarEx. С выходом новой версии системы в ней самой может появиться функция FooBarEx.

Вторая проблема иллюструриет тезис о вреде преждевременной оптимизации. Приложение падало сразу после запуска при вызове функции FormatString:

int FormatString(LPSTR lpOutput, int nOutput, UINT uIdFormat, ...)
{
    ...
    wvsprintf(lpOutput, p, (LPVOID)(&uIdFormat + 1)); // < -- bug
    ...
}

Само падение происходило где-то в глубинах wvsprintf, однако причина проблемы была в странной арифметике вокруг uIdFormat. Насколько я могу судить, автор пытался сэкономить пару строк кода и одну переменную, отказавшись от использования макроса va_start(). Однако в 64-х битном окружении выражения (&uIdFormat + 1) и va_start(…) дают разный результат: первое сдвигает указатель на 4-е байта, второе – сдвигает и выравнивает указатель на границу 8-ми байт.

Posted at 4:29 pm •

RSS feed | Trackback URI

Comments »

No comments yet.

Your Comment (smaller | larger)

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by WordPress