(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Забытые проблемы разработки 64-битных программ

Источник: Realcoding
Андрей Карпов

Введение

История развития 64-битных программных систем не нова и составляет уже более десятилетия [1]. В 1991 году был выпушен первый 64-битный микропроцессор MIPS R4000 [2, 3]. С тех пор в форумах и статьях возникали дискуссии посвященные переносу программ на 64-битные системы. Началось обсуждения проблем связанных с разработкой 64-битных программ на языке Си. Обсуждались вопросы, какая модель данных лучше, что такое long long и многое другое. Вот, например, интересная подборка сообщений [4] из новостной группы comp.lang.c, посвященная использованию типа long long в языке Си, что в свою очередь было связано с появлением 64-битных систем.

Одним из наиболее распространенных и чувствительных к изменению размерности типов данных является язык Си. Из-за его низкоуровневых свойств, следует постоянно контролировать корректность программы на этом языке, переносимой на новую платформу. Естественно, что при появлении 64-битных систем разработчики по всему миру вновь столкнулись с задачами обеспечения совместимости старого исходного кода с новыми системами. Одним из косвенных свидетельств сложности проблем миграции является большое количество моделей данных, которые постоянно следует учитывать. Модель данных - это соотношение размеров базовых типов в языке программирования. На рисунке 1 показаны размерность типов в различных моделях данных, на которые мы в дальнейшем будем ссылаться.


Рисунок 1. Модели данных.

Существующие публикации и инструменты в сфере верификации 64-битных приложений

Конечно, это был не первый этап смены разрядности. Достаточно вспомнить переход с 16-битных систем на 32-битные. Естественно накопленный опыт оказал свое положительное воздействие на этапе перехода на 64-битные системы.

Но переход на 64-битные системы, имел свои нюансы, в результате чего появилась серий исследований и публикаций по данным вопросам, например [5, 6, 7].

В основном авторами того времени, выделялись ошибки, следующих типов:

  1. Упаковка указателей в типы меньшей размерности. Например, помещение указателя в тип int на системе с моделью данных LP64 приведет к обрезанию значения указателя и невозможности его использовать в дальнейшем.
  2. Использование магических констант. Опасность заключается в использовании таких чисел как 4, 32, 0x80000000 и ряда других вместо специализированных констант или использования оператора sizeof().
  3. Некорректные операции сдвига, не учитывающих увеличение размерности ряда типов.
  4. Использование некорректных объединений или структур без учета выравнивания на системах с различной разрядностью.
  5. Ошибки работы с битовыми полями.
  6. Некорректные арифметические выражения. Пример:
int x = 100000, y = 100000, z = 100000;
long long s = x * y * x;

Рассматривались и некоторые другие более редкие ошибки, но основные перечислены в списке.

На основе проведенных исследований вопроса верификации 64-битного кода были предложены решения, обеспечивающих диагностику опасных конструкций. Например, такую проверку реализовали в статических анализаторах Gimpel Software PC-Lint (http://www.gimpel.com) и Parasoft C++test (http://www.parasoft.com).

Возникает вопрос, если 64-битные системы существуют так давно, существуют статьи, посвященные данной тематике и даже программные инструменты обеспечивающий контроль опасных конструкций в коде, так стоит ли возвращаться к этому вопросу?

К сожалению да - стоит. Причиной служит прогресс, произошедший за эти годы в области информационных технологий. А актуальность данного вопроса связана с быстрым распространением 64-битных версий операционной системы Windows.

Существующая информационная поддержка и инструменты в области разработки 64-битных технологий устарели и нуждаются в существенной переработке. Но Вы возразите, что в Интернете можно найти множество современных статей (2005-2007г), посвященных вопросам разработки 64-битных приложений на языке Си/Си++. К сожалению, на практике они являются не более чем пересказом старых статей, применительно к новой 64-битной версии Windows, без учета ее специфики и произошедших изменений технологий.

Неосвещенные проблемы разработки 64-битных программ

Но начнем по порядку. Авторы новых статей не учитывают, огромный объем памяти, который стал доступен современным приложениям. Конечно, указатели были 64-битными еще в стародавние времена, но вот использовать таким программам массивы размером в несколько гигабайт не доводилось. В результате, как в старых, так и в новых статьях выпал целый пласт ошибок, связанный с ошибками индексации больших массивов. Практически невозможно найти в статьях описание ошибки, подобной следующей:

for (int x = 0; x != width; ++x)
  for (int y = 0; y != height; ++y)
    for (int z = 0; z != depth; ++z)
      BigArray[z * width * height + y * width + x] = InitValue;

В этом примере, выражение "z * width * height + y * width + x" используемое для адресации имеет тип int, а, следовательно, данный код будет некорректен на массивах, содержащих более 2 GB элементов. На 64-битных системах для безопасной индексации к большим массивам следует использовать типы ptrdiff_t, size_t или производные от них. Отсутствие описания такого вида ошибки в статьях объясняется очень просто. Во времена их написания, машины с объемом памяти, позволяющей хранить такие массивы, были практически не доступны. Сейчас же это становится рядовой задачей в программировании и с большим удивлением можно наблюдать, как код верой и правдой служивший многие годы, вдруг перестает корректно работать при работе с большими массивами данных на 64-битных системах.

Другой пласт практически неосвященных проблем, представлен ошибками, связанными с возможностями и особенностями языка Си++. Почему так произошло, тоже достаточно объяснимо. Во время внедрения первых 64-битных систем, язык Си++ для них не существовал или он был не распространен. По этому практически все статьи посвящены проблемам в области языка Си. Современные авторы заменили название Си на Си/Си++, но нового ничего не добавили.

Но отсутствие в статьях описания ошибок специфичных для Си++ не означает, что их нет. Существуют ошибки, проявляющие себя при переносе программ на 64-битные системы. Они связанны с виртуальными функциями, исключениями, перегруженными функциями и так далее. Более подробно с такими ошибками можно ознакомиться в статье [8]. Приведем простой пример, связанный с использованием виртуальных функций.

сlass CWinApp {
  ...
  virtual void WinHelp(DWORD_PTR dwData, UINT nCmd);
};
class CSampleApp : public CWinApp {
  ...
  virtual void WinHelp(DWORD dwData, UINT nCmd);
};

Проследим жизненный цикл разработки некоторого приложения. Пусть первоначально оно разрабатывалось под Microsoft Visual C++ 6.0. когда, функция WinHelp в классе CWinApp имела следующий прототип:

virtual void WinHelp(DWORD dwData, UINT nCmd = HELP_CONTEXT);

Совершенно верно было осуществить перекрытие виртуальной функции в классе CSampleApp, как показано в примере. Затем проект был перенесен в Microsoft Visual C++ 2005, где прототип функции в классе CWinApp претерпел изменения, заключающиеся в смене типа DWORD на тип DWORD_PTR. На 32-битной системе программа продолжит совершенно корректно работать, так как здесь типы DWORD и DWORD_PTR совпадают. Неприятности проявят себя при компиляции данного кода под 64-битную платформу. Получатся две функции с одинаковыми именами, но с различными параметрами, в результате чего перестанет вызываться пользовательский код.

Помимо особенностей разработки 64-битных программ с точки зрения языка Си++, существуют и другие тонкие моменты. Например, особенности связанные с архитектурой 64-битной версии Windows. Хочется заранее предупредить разработчиков о потенциальных проблемах и порекомендовать уделить большее внимание тестированию 64-битного программного обеспечения [9].

Теперь вернемся к методам верификации исходного кода программы с использованием статических анализаторов. Я думаю, вы уже угадали, что здесь тоже не все так хорошо как кажется. Не смотря на заявленную поддержку диагностирования особенностей 64-битного кода, эта поддержка на данный момент не удовлетворяет необходимым требованием. Причина заключена в том, что диагностические правила были созданы по все тем же статьям, не учитывающим специфику языка Си++ или обработку больших массивов данных, превышающих 2 GB.

Для Windows разработчиков дело обстоит еще несколько хуже. Основные статические анализаторы рассчитаны на диагностику 64-битных ошибок для модели данных LP64, в то время, как в Windows используется модель данных LLP64 [10]. Обусловлено это тем, что 64-битные версии Windows молоды, а ранее 64-битные системы были представлены Unix подобными системами с моделью данных LP64.

В качестве примера, рассмотрим диагностическое сообщение 3264bit_IntToLongPointerCast (port-10), генерируемое анализатором Parasoft C++test.

int *intPointer;	
long *longPointer;
longPointer = (long *)intPointer; //-ERR port-10

C++test предполагает, что с точки зрения модели LP64, данная конструкция будет некорректна. Но в рамках модели данных принятых в Windows данная конструкция будет безопасна.

Рекомендации по верификации 64-битных программ

Хорошо, скажите Вы, проблемы разработки 64-битных версий программ действительно актуальны. Но как найти все эти ошибки?

Исчерпывающий ответ дать невозможно, но можно привести ряд рекомендаций, которые в сумме позволят обеспечить безопасную миграцию на 64-битные системы и обеспечить необходимый уровень надежности.

  • Ознакомьте Ваших коллег, связанных с разработкой 64-битых приложений со следующими статьями: [7, 8, 9, 10, 11, 12, 13, 14, 15].
  • Ознакомьте Ваших коллег с методологией статического анализа кода: [16, 17, 18]. Статическая верификация кода один из лучших способов поиска такого рода ошибок. Она позволяет убедиться в работоспособности даже тех частей кода, работу которых на больших объемах данных сложно смоделировать в реальности, например при использовании методологии юнит-тестов.
  • Разработчикам будет полезно познакомиться со статическими анализаторами, такими как Parasoft C++test (www.parasoft.com), Gimpel Software PC-lint (www.gimpel.com), Abraxas Software CodeCheck (www.abxsoft.com).
  • Для разработчиков Windows приложений особенно будет полезно познакомиться со специализированным статическим анализатором Viva64 (www.Viva64.com), рассчитанным на модель данных LLP64 [19].
  • Усовершенствуйте систему юнит-тестирования, включив в набор тестов обработку больших массивов данных. Более подробно с необходимостью тестирования на большом объеме данных, можно познакомиться в [9], а также узнать, как лучше организовать такое тестирование.
  • Провести тщательно ручное тестирование перенесенного кода на реальных больших задачах, использующих возможности 64-битных систем. Смена архитектуры слишком существенное изменение, чтобы полностью положиться на автоматизированные системы тестирования.

Ресурсы

  1. John R. Mashey, The Long Road to 64 Bits.
    http://www.acmqueue.org/modules.php?name=Content&pa=showpage&pid=421&page=7
  2. Wikipedia: MIPS architecture.
    http://en.wikipedia.org/wiki/MIPS_architecture
  3. John R. Mashey, 64 bit processors: history and rationale.
    http://yarchive.net/comp/64bit.html
  4. John R. Mashey, The 64-bit integer type "long long": arguments and history.
    http://yarchive.net/comp/longlong.html
  5. 64-bit and Data Size Neutrality.
    http://www.unix.org/whitepapers/64bit.html
  6. 64-Bit Programming Models: Why LP64?
    http://www.unix.org/version2/whatsnew/lp64_wp.html
  7. Transitioning C and C++ programs to the 64-bit data model.
    http://devresource.hp.com/drc/STK/docs/refs/64datamodel.jsp
  8. Andrey Karpov, Evgeniy Ryzhkov. 20 issues of porting C++ code on the 64-bit platform.
    http://www.viva64.com/articles/20_issues_of_porting_C++_code_on_the_64-bit_platform.html
  9. Andrey Karpov. Evgeniy Ryzhkov. Problems of testing 64-bit applications.
    http://www.viva64.com/articles/Problems_of_testing_64-bit_applications.html
  10. The Old New Thing: Why did the Win64 team choose the LLP64 model?
    http://blogs.msdn.com/oldnewthing/archive/2005/01/31/363790.aspx
  11. Brad Martin, Anita Rettinger, and Jasmit Singh. Multiplatform Porting to 64 Bits.
    http://www.ddj.com/hpc-high-performance-computing/184406427
  12. Migrating 32-bit Managed Code to 64-bit.
    http://msdn2.microsoft.com/en-us/library/ms973190.aspx
  13. Matt Pietrek. Everything You Need To Know To Start Programming 64-Bit Windows Systems.
    http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx
  14. Microsoft Game Technology Group. 64-bit programming for Game Developers.
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/sixty_four_bit_programming_for_Game_Developers.asp
  15. John Paul Mueller. 24 Considerations for Moving Your Application to a 64-bit Platform.
    http://developer.amd.com/articlex.jsp?id=38
  16. Wikipedia: Static code analysis.
    http://en.wikipedia.org/wiki/Static_code_analysis
  17. Sergei Sokolov. Bulletproofing C++ Code.
    http://www.ddj.com/dept/debug/196802351
  18. Walter W. Schilling, Jr. and Mansoor Alam. Integrate Static Analysis Into a Software Development Process.
    http://www.ddj.com/dept/debug/193500967?cid=RSSfeed_DDJ_debugging
  19. Evgeniy Ryzhkov. Viva64: what is it and for whom is it meant?
    http://www.viva64.com/articles/Viva64_-_what_is_and_for.html


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 14.10.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
TeeChart Pro VCL/FMX with source code single license
ABBYY Lingvo x6 Европейская Домашняя версия, электронный ключ
Quest Software. TOAD for SQL Server Xpert Edition
Stimulsoft Reports.Ultimate Single License Includes one year subscription, source code
Allround Automation PL/SQL Developer - Unlimited license
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Программирование на Microsoft Access
CASE-технологии
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
СУБД Oracle "с нуля"
Новые материалы
3D и виртуальная реальность. Все о Macromedia Flash MX.
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100