Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 12 лет назад пользователемfiles.viva64.com
2 Проблема переноса приложений на 64-битные платформы Процесс миграции кода неизбежен. Миграция C/C++ приложений наиболее затруднена из-за особенностей языка. При миграции возможно появление в программах ошибок, которые не удается диагностировать существующими методиками тестирования. Сложно убедится в корректности современных программ после переноса их на 64-битные системы (в MS-DOS 1.0 было строк кода, а в Windows Vista уже ). Поэтому и нельзя обратиться к опыту прошлых переходов.
3 По данным Kang Su Gatlin, Visual C++ Program Manager, Microsoft Corporation, 2004
4 Базовый класс: class CWinApp { virtual void WinHelp(DWORD_PTR, UINT); }; Код пользователя: class CMyApp : public CWinApp { virtual void WinHelp(DWORD, UINT); }; 32-битная система:64-битная система:
5 int A = -2; unsigned B = 1; int array[5] = { 1, 2, 3, 4, 5 }; int *ptr = array + 3; ptr = ptr + (A + B); printf("%i\n", *ptr); Переменная A типа int приводится к типу unsigned; Происходит сложение A и B. В результате мы получаем значение 0xFFFFFFFF типа unsigned; Вычисляется выражение "ptr + 0xFFFFFFFFu". Результат зависит от размерности указателя на данной платформе. В 32-битной программе, выражение будет эквивалентно "ptr - 1" и мы успешно распечатаем число 3. В 64-битной программе к указателю прибавится значение 0xFFFFFFFFu, в результате чего указатель окажется далеко за пределами массива.
6 bool IsPresent(char *array, size_t arraySize, char key) { for (unsigned i = 0; i != arraySize; ++i) if (array[i] == key) return true; return false; } Данный код приведет к возникновению бесконечного цикла, если arraySize превысит значение UINT_MAX. Выявление подобных ошибок с использованием unit-тестов или динамических анализаторов (BoundsChecker) крайне осложнено необходимостью запуска на больших объеме данных. При обработке малого объема данных ошибка выявлена не будет
7 ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum) { ptrdiff_t mask = 1
8 #define N_COUNT 100 int **pArray = (int**) malloc(N_COUNT * 4); hFileMapping = CreateFileMapping ( (HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, (DWORD) 0, (DWORD) (szBufIm), (LPCTSTR) &FileShareNameMap[0]); size_t n, newexp; n = n >> (32 - newexp); Наиболее распространенные магические значения, опасные при переносе приложений с 32-битной на 64-битную платформу
9 ptrdiff_t UnsafeCalcIndex(int x, int y, int width) { return x + y * width; }... int domainWidth = 50000; int domainHeght = 50000; for (int x = 0; x != domainWidth; ++x) for (int y = 0; y != domainHeght; ++y) array[UnsafeCalcIndex(x, y, domainWidth)] = 1; Данный код не может корректно заполнить массив, состоящий из 50000*50000 элементов. При вычислении выражения "x + y * width" происходит переполнение и результатом будет выход за границы массива.
10 size_t __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp); size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) { int ret; FLOCKFILE(fp); ret = __fread(buf, size, count, fp); FUNLOCKFILE(fp); return (ret); } Функция __fread возвращает тип size_t, но для хранения количества прочитанных байт используется тип int. В результате при больших объемах читаемых данных функция может вернуть не то количество байт, которое на самом деле будет прочитано.
11 Были исследованы паттерны 64-битных ошибок в коде по более чем 100 различным статьям в печатных и электронных изданиях. Учтен собственный опыт миграции кода пакетов численного моделирования и визуализации на C++. В ходе исследований создана база из нескольких десятков различных паттернов ошибок, связанных с переносом кода на 64-битные системы. В базу попали как известные (опубликованные) ошибки, так и неизвестные ранее. На основе выявленных паттернов ошибок сформулированы правила их диагностики. И паттерны ошибок, и правила диагностики опубликованы в наших статьях и доступны для ознакомления всем желающим.
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.