Проблема переноса приложений на 64-битные платформы Процесс миграции кода неизбежен. Миграция C/C++ приложений.

Презентация:



Advertisements
Похожие презентации
ООО «СиПроВер» («Системы программной верификации»)
Advertisements

ПРОГРАММИРОВАНИЕ/ ЯЗЫКИ ПРОГРАММИРОВАНИЯ Лекция 4 Работа с бинарными файлами (весенний семестр 2012 г.) Доцент Кафедры вычислительных систем, к.т.н. Поляков.
Лекция 14 Динамические данные. Виды памяти Существует три вида памяти: статическая, стековая и динамическая. Статическая память выделяется еще до начала.
Инструкции C++ Условная инструкция Формат: if (условие) оператор; else оператор; Пример: if (i!=0) { if (j) j++; if(k) k++; else if(p) k--; } else i--;
1. a=? b=? c=? {int a, b, c; a=(b=2+3)/2 - 4+(c=5%2); printf("%d %d %d \n", a, b, c); }
Информационные технологии Классы памяти auto static extern register Автоматические переменные создаются при входе в функцию и уничтожаются при.
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
УКАЗАТЕЛИ. Переменная - это именованная область памяти с заданным типом. [=значение]; int a; //Переменная типа integer с именем a int b=2;// Переменная.
Сложные структуры данных Связные списки. Структуры, ссылающиеся на себя struct node { int x; struct node *next; };
Основы информатики Лекция. Массивы. Указатели. Заикин Олег Сергеевич
Древовидная модель оказывается довольно эффективной для представления динамических данных с целью быстрого поиска информации. Деревья являются одними из.
Получение контроля над объектом атаки Местонахождение атакующего В разных сегментах с объектом атаки Используемые уязвимости Цель Ошибки реализации Степень.
Получение контроля над объектом атаки Местонахождение атакующего В разных сегментах с объектом атаки Используемые уязвимости Цель Ошибки реализации Степень.
Получение контроля над объектом атаки Местонахождение атакующего В разных сегментах с объектом атаки Используемые уязвимости Цель Ошибки реализации Степень.
1. a=? b=? c=? {int a, b, c; a=(b=2+3)/2 - 4+(c=5%2); printf("%d %d %d \n", a, b, c); }
Лекция 22. Шаблоны (часть 2) Красс Александр СПбГУ ИТМО, 2008.
Лекция 14 Динамические данные. Виды памяти Существует три вида памяти: статическая, стековая и динамическая. Статическая память выделяется еще до начала.
Лабораторная работа 7. Работа с динамической памятью, строками и файлами.
Проблемы обеспечения безопасности приложений Тема 20.
Лекция 4. Введение в С++ Наследование, множественное наследование. Конструкторы, деструкторы. Виртуальные функции.
Транксрипт:

Проблема переноса приложений на 64-битные платформы Процесс миграции кода неизбежен. Миграция C/C++ приложений наиболее затруднена из-за особенностей языка. При миграции возможно появление в программах ошибок, которые не удается диагностировать существующими методиками тестирования. Сложно убедится в корректности современных программ после переноса их на 64-битные системы (в MS-DOS 1.0 было строк кода, а в Windows Vista уже ). Поэтому и нельзя обратиться к опыту прошлых переходов.

По данным Kang Su Gatlin, Visual C++ Program Manager, Microsoft Corporation, 2004

Базовый класс: class CWinApp { virtual void WinHelp(DWORD_PTR, UINT); }; Код пользователя: class CMyApp : public CWinApp { virtual void WinHelp(DWORD, UINT); }; 32-битная система:64-битная система:

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, в результате чего указатель окажется далеко за пределами массива.

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) крайне осложнено необходимостью запуска на больших объеме данных. При обработке малого объема данных ошибка выявлена не будет

ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum) { ptrdiff_t mask = 1

#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-битную платформу

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" происходит переполнение и результатом будет выход за границы массива.

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. В результате при больших объемах читаемых данных функция может вернуть не то количество байт, которое на самом деле будет прочитано.

Были исследованы паттерны 64-битных ошибок в коде по более чем 100 различным статьям в печатных и электронных изданиях. Учтен собственный опыт миграции кода пакетов численного моделирования и визуализации на C++. В ходе исследований создана база из нескольких десятков различных паттернов ошибок, связанных с переносом кода на 64-битные системы. В базу попали как известные (опубликованные) ошибки, так и неизвестные ранее. На основе выявленных паттернов ошибок сформулированы правила их диагностики. И паттерны ошибок, и правила диагностики опубликованы в наших статьях и доступны для ознакомления всем желающим.