Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

27.05.2017

Google
WWW CITForum.ru
С Новым годом!
2001 г

Средства тестирования от компании Rational

(оригинал напечатан в "Компьютер-пресс" #2'2001 и на сайте www.interface.ru )
Новичков Александр Николаевич
http://www.interface.ru, http://www.compress.ru, http://www.cmcons.com

C развитием аппаратной базы компьютерных систем - увеличением тактовой частоты до запредельных уровней (переваливших за гигагерц), ускорением обработки изображений в реальном масштабе времени при помощи супермощных видеоадаптеров многие разработчики не считают нужным (или возможным) оптимизировать написанные ими программные продукты, перенося весь неоптимизированный код на быструю подсистему, быстрый процессор, "умный" компилятор. Результат подобного злоупотребления мы наблюдаем ежедневно во время запуска программ на собственных компьютерах, отмечая странную тенденцию: чем новее программа, тем больше требует ресурсов, и тем медленнее работает. Но и это еще не все! Многие программы по окончании работы не освобождают все занимаемые ресурсы, что приводит к достаточно неприятным последствиям. Странно, не правда ли? Казалось бы, технологии программирования должны совершенствоваться и идти в ногу с аппаратными новинками, качественно используя все предоставляемые ими возможности, однако на деле все обстоит гораздо хуже. В погоне за новыми цифрами версий на коробках продуктов разработчики не считают нужным (возможным) проводить детальную оптимизацию написанного кода, тщательно отслеживая все вызовы и подсчитывая занимаемую системную память, поскольку занятие это трудоемкое и длительное, а получаемый результат не всегда оправдывает надежды: времени потрачено много, сил - еще больше, а производительность конечного продукта повысилась в лучшем случае на 9%, а то и меньше. Согласитесь, ситуация для нашего времени достаточно типичная, причем типична она для всех софтверных компаний, вне зависимости от ранга, размера, и, что немаловажно, от географического расположения. Лозунг: "время - деньги", применяемый всеми к месту и не к месту, в данной ситуации дает явный сбой! Получается количество версий - в ущерб качеству.

За примером далеко ходить не придется: у всех есть нерасторопные операционные системы и офисные пакеты, которые с каждой новой реализации повышают аппаратные требования, функционально оставаясь при этом, на уровне 95 года.

Неужели все так страшно и бесперспективно? И "да" и "нет". Все крупные компании, связанные с написанием программного обеспечения, пытаются найти способы наиболее эффективного тестирования, не выходя при этом за рамки бюджета конкретной разработки. Но, к сожалению, то ли ищут не там, то ли применяют не то, поскольку оптимизированных продуктов на рынке не так много.

Разработка качественных продуктов в отведенные сроки сроки - вот задача, на решения которой направлены все продукты компании Rational. В частности, для этапа разработки высококачественного кода, компанией рекомендуется использование, посредством RUP. (Rational Unified Process - методологии разработки), инструментов тестирования: Quantify, Purify, PureCoverage.

Разумное применение этих продуктов позволит группам разработчиков найти узкие места в производительности создаваемого программного обеспечения и своевременно устранить их.

  • Quantify - собирает полную статистику о количестве вызовов функций в тестируемой программе, позволяя тем самым узнавать временные характеристики отдельных частей приложения
  • Pure Coverage - позволит быстро найти участки кода, пропущенные при тестировании
  • Purify - отлавливает все ошибки, связанные с утечкой памяти а также некоторые Run-time ошибки

Далее разговор пойдет о наиболее продвинутой программе, из вышеприведенного списка - Rational Purify, которая также поставляется компанией Interface Ltd.. Данный продукт является самым сложным и самым "интеллектуальным", в силу своей специфики, поскольку ей в обязанности вменяется нахождение ошибок, а не простая статистическая выкладка, которую выдают остальные пакеты.

Глава 1
Purify

Исследуем поверхность и интегрируемся с VC++

Начать описание возможностей продукта Rational Purify хочется перефразированием одного очень известного изречения: "с точностью до миллиБАЙТА". И это не случайно, ведь именно на решение всех проблем, связанных с утечкой памяти и предназначен данный продукт.

Ни для кого не секрет, что многие приложения ведут себя "не слишком скромно", замыкая во время работы все системные ресурсы без большой на то необходимости. Данной болезни подвержены в основном крупные программные пакеты, и возникает подобная ситуация по причине нежелания программистов доводить созданный код "до ума", но чаще подобное происходит не из за лени, а из-за невнимательности. Это понятно - современные темпы разработки ПО в условиях жесточайшего прессинга со стороны конкурентов не позволяют уделять слишком много времени оптимизации кода, ведь для этого необходимы и высокая квалификация, и наличие достаточного количества проектного времени. Как правило квалификация есть, а вот времени и денег на детальное тестирование кода на наличие "глюков" и "багов" практически нет. И в большинстве случаев, идя на поводу у клиентов крупные компании выпускают сырой код и тут же принимаются "латать" его различными патчами:

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

Так вот, как мне видится, имея в своем распоряжении надежный инструмент, который бы сам в процессе работы над проектом указывал бы на подобные ошибки, то разработчики начали бы его повсеместное внедрение, повысив надежность создаваемого ПО, поскольку, как известно, что проще ошибку не допустить, чем потом с гордостью исправлять.

В общих чертах работа Rational Purify сводится к детальному выводу статистики об использовании памяти приложением (список ошибок и примеры устранения во второй главке).

Получаемой статистики вполне достаточно для получения общей, а затем - и детальной информации обо всем, что имеет отношение к памяти: утечки, потерянные блоки, фиктивные ссылки.

Purify позволяет анализировать исполняемый модуль, содержащий отладочную информацию, либо работать на уровне исходников, но только в среде Visual Studio (C++, Basic, Java).

Работа программы начинается со сбора информации о загружаемых библиотеках. То есть программа отыскивает ошибки не только внутренние но и внешние, разумеется, нельзя исправить ошибку в системной DLL, но если она там есть, то наверняка, можно написать дополнительный код в своей процедуре, отказавшись от вызова "некачественной" функции из DLL.

Перво-наперво идет детальное инструментирование всех модулей. Инструментирование сводится к тому, что Purify вставляет свою отладочную информацию в тело программы и вызываемых библиотек (технология Object Code Insertion). Для эффективной работы все "пройденные" библиотеки хранятся в кеше, что позволяет сократить необходимое время не перезапуск исправленного приложения.

Давайте рассмотрим возможности Purify в плане совместной работы с Microsoft Visual C++.

Интеграция компонентов от Rational выражается в появлении новых инструментальных панелей на поверхности рабочего стола в Development Studio. Получив полный набор тестирующих и профилирующих средств, разработчик обращается к ним по мере необходимости, не покидая рабочего пространства, что позволяет сэкономить массу времени на различные вызовы сторонних программ.

Рисунок 1 показывает примерный вид инструментальных панелей в Visual Studio, появляющихся после инсталляции Purify, Quantify, PureCoverage. (вставить сюда из файла INTEGRATION.tif)

А учитывая давнюю дружбу Rational и Microsoft, становится понятно, почему поддерживаются в полной мере только среды разработчиков от MS.

Собрав воедино всю перечисленную информацию, давайте попробуем на конкретном примере в Visual C++, создать приложение, внести в него ряд намеренных ошибок после чего, используя Purify попытаться отыскать их.

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

Во-вторых, для чистоты эксперимента мы воспользуемся стандартным "Волшебником" из состава Visual Studio, сгенерировав, на его основе проект, в который внесем некоторый код, который будет неадекватно себя вести с памятью системы:

Итак, у меня получилось 32-разрядное приложение для Windows с именем "PROJECTOID". На рисунке 2 изображен скриншот окна Workspace после создания проекта. Для демонстрации преимуществ Purify не нужно заводить в примере тонны сложных классов, запутывая и себя, и программу, и статью: ограничимся лишь простыми вызовами на распределение памяти.

Для более наглядного способа отлова ошибок допишем пару строк в стандартный обработчик "OnAppAbout":

void All::OnAppAbout()
{
        char *alex;                               //Наша строка №1
        alex=(char *)malloc(20000);  //Наша строка №2
        CAboutDlg aboutDlg;
        aboutDlg.DoModal();
}

Добавление интеллекта к функции OnAppAbout сделано намерено, поскольку во время работы можно воспользоваться данной функцией несколько раз подряд, активируя диалог "ABOUT" после игр с его вызовом. Теперь завершим приложение, посмотрим статистику по памяти и под конец найдем "виновного" в полученной утечке памяти. Из фрагмента видно, что указатель "alex" смотрит в сторону блока длиной в 20Кб, который выделяется функцией MALLOC. Еще можно заметить, что: 1) указатель нигде не используется, 2) Блок памяти не освобождается.

Запускаем программу по F5, предварительно активировав Purify (увеличительные стекла на инструментальной панели Purify. См. рис. 1). В запущенном приложении трижды запускаем диалог ABOUT из верхнего меню и закрываем приложение.

Во время работы подконтрольного приложения Purify собрала достаточно информации о нем и о его проблемах с памятью. Полученная статистика выведется на экран сразу по окончании работы приложения.

Рисунок 3 иллюстрирует вид окна со статистикой по памяти. При внимательном рассмотрении становится видна вся подноготная как нашего модуля, так и шапки, сгенерированной компилятором Microsoft в лице Visual C++. Purify насчитала 43 (!) предупреждения о неправильном (читай: неэффективном) использовании памяти, а из них только одно наше было преднамеренно введено в программу. Хотя, если говорить совсем честно и открыто, то не все ошибки являются ошибками! (см вторую главку)

Вновь обратимся к рисунку со статистикой, где в явном виде находится информация по ошибкам и по модулям, в которых эти ошибки были обнаружены. К приятной неожиданности можно отнести фразу "Memory leak of 60000", указывающую на то, сколько фактических байтов памяти программа не вернула системе, по завершении своей работы. Эта черта разительно отличает подходы к тестированию программы Rational Purify от подобных продуктов конкурирующих компаний, которые высчитывают не фактические утечки (полученные в результате нескольких вызовов при реальной работе приложения, а количество невозвращенных блоков, то есть ограничиваются лишь анализом (на уровне исходных текстов) программы с выявлением вызовов функций аллокирования памяти без последующего освобождения. Из этого и следует полученное число 60000 - фактически не освобожденных блоков (3 по 20000). После добавления функции free(alex) в конец обработчика OnAppAbout и перекомпиляции тестируемого приложения, Purify не обнаруживает никаких ошибок памяти, что и являлось нашей целью.

Рисунок 4 отображает окно c ошибкой, в котором Purify, подсветила конкретный фрагмент текста листинга.

Все вышеописанные возможности дают мощный инструментарий в руки разработчика, желающего знать, где в коде находится вызов на выделение памяти, и сколько физически утеряно блоков в результате работы приложения, и какая часть программы в этом виновата. Продукт поставляется в Россию компанией Interface Ltd.: mail@interface.ru

Глава 2
Purify

Тонкие моменты

Из предыдущей главы нам стало известно, что Rational Purify направлена на поиск ошибок в программах написанных на Visual Studio. Мы также знаем, что продукт способен проанализировать эффективность кода программы, как с использованием исходных кодов, так и без них.

К достоинствам программы можно отнести не только вышесказанное. Purify способна работать (запускаться) на трех уровнях: из среды интеграции (Visual Studio), как отдельная программа и наконец из командной строки (если при инсталляции ей разрешили "прописаться" в путях). Любой разработчик, пишущий визуальные изощрения под "Окна", может отказаться от интерфейса командной строки за ненадобностью. И совершенно напрасно! Как известно корни доброй половины продуктов Rational уходят своими корнями в разные UNIX системы, для которых командная строка - вещь святая, и графическими средствами незаменяемая. Соответственно, все особенности продуктов перекочевали под Windows: где и прижились: в лучшей или худшей степени.

Давайте обратим наше внимание именно на командную строку и попробуем разобраться как и для чего она нужна в повседневной разработке. Из материала прошлой статьи известно, что для своей работы средства тестирования Rational используют патентованную (читай: засекреченную) технологию под названием OCI - Object Code Insertion. Соответственно, суть метода тестирования состоит в том, что в исполняемый код записываются специальные инструкции Purify. Здесь хочется еще раз акцентировать внимание на том, что код вставляется не только в пользовательский модуль, но и во все внешние библиотеки, что дает разработчику уникальную возможность по отладке программ, предоставляя полную статистику по всем модулям. А это позволит вовремя заменить/переписать/переделать некорректную DLL, а не ждать пока она сведет на "нет" все усилия по вылавливанию внутренних ошибок. К вопросу о скорости работы: код вставляется относительно долго, зато создается директория с кешем - DLL со вставленным OCI. Так что, каждый новый запуск проходит быстрее предыдущего.

Процесс записи объектного кода в приложения на языке Purify называется "инструментированием", соответственно подобная операция выполняется каждый раз перед исполнением написанного приложения. Если это касается совместной работы с пакетами из VS, то дело происходит так: сначала приложение компилируется (обычным способом, без вставки OCI), затем, после подачи команды "RUN" - запускается Purify и начинается процесс вставки кода. Только по его завершению, приложение начнет исполняться.

Из самого же Purify дело обстоит еще проще: необходимо просто выбрать нужный EXE'шник. Естественно, и в том и в другом случае приложению (при необходимости) можно передать аргументы командной строки и настроить фильтры сообщений (об этом чуть ниже).

Полное же управление над процессом инструментирования можно получить из командной строки. Здесь есть некоторые возможности, отсутствующие в версиях GUI.

Например:

  • Инструментирование как самого файла приложения, так и его копии (последняя создается автоматически)
  • Только вставка кода без запуска приложения
  • Запись кеша в указанную директорию
  • И многое другое: всего 38 ключей

Тестирование сервисов Windows NT

Конечно же командная строка во многом дублирует функции графической оболочки, что делает не совсем очевидным применения именно данной возможности. Для решения следующего примера нам нужно воспользоваться командной строкой поскольку, тестируемое приложение является сервисом Windows NT, который, разумеется, нельзя исполнить как простое приложение. В этом случае как нельзя кстати приходится функция записи OCI без исполнения файла, что позволит внести в него весь объектный код, а затем прописать данный сервис в реестре. Соответственно, при старте сервиса у вас появится возможность получения информации о работоспособности сервиса.

Рецепт тестирования выглядит следующим образом:

    1) Правильно настроить системные пути таким образом, чтобы из них были видны все директории Purify (особенно кеш: \Program Files\Rational\Purify), иначе процесс не пойдет на исполнение. 2) Откомпилированный сервис нужно запустить Purify из командной строки следующим образом: purify /Run=no /Out=service_pure.exe service.exe. Как видно из параметров, Purify инструментирует файл service.exe, помещая его копию вместе с OCI в service_pure.exe. Все происходит без запуска. 3) В ключе реестра \HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services необходимо поставить ссылку на кешированный файл (service_pure.exe) 4) Во вкладке сервисов активировать пункт Allow Service to Interact with Desktop, выбрать режим запуска "manual"

Далее - как обычно: после перезагрузки загрузить Purify и стартовать сервис. Программа подхватит его и начнет тестировать как это было бы при работе обычного приложения.

Помимо системных сервисов, Rational Purify способна работать совместно с:

  • Компонентами Active X
  • Дочерними процессами
  • Совместно написанными программами (Visual С++ & Visual Basic)
  • COM серверами (in-proc и out-proc)
  • Internet Information Server

Сообщения об ошибках и предупреждениях.
Настройка фильтра.

Rational Purify по своей природе способна выловить не только ошибки, связанные с потерей памяти, но также ряд других не менее важных ошибок. Следует определить, что все сообщения делятся на две категории: ОШИБКИ и ПРЕДУПРЕЖДЕНИЯ. Во время запуска программа будет дотошно собирать все виды сообщений, и только настройка фильтра позволит отказаться от заведомо лишней, ненужной информации. Система фильтров Purify способна настроить не только уровень "придирчивости" к программе, но и количество исследуемых внешних модулей (чтобы разработчик мог концентрироваться только на собственных ошибках и не огорчался по поводу системных ошибок).

По умолчанию Purify выводит все сообщения и предупреждения, что может повергнуть разработчика в шок (даже в абсолютно правильной программе могут быть определенные предупреждения). Это связанно со спецификой поиска неточностей, так как некоторые предупреждения могут счиаться ошибкой, а могут и не быть таковыми - все зависит от конкретного алгоритма! Вот почему Purify и предлагает мощный фильтр

Как видно из рисунка, предполагается ставить фильтры либо по сообщениям (вручную) либо по категориям (при этом соответствующие сообщения выберутся автоматически). Обратите внимание на список сообщений: количество доходит до 41 и растет с каждой новой версией! Перед тем, как мы перейдем к рассмотрению всех сообщений, хочется отметить очень важный нюанс: Purify способен работать совместно с отладчиком (он прописывается отдельно). В этом случае возможна двойная работа по отладке программы с установкой брейкпоинтов:. итд.

Попробуем рассмотреть некоторые сообщения Purify c комментариями и примерами:

ABR: Array Bounds Read Выход за пределы массива при чтении

#include <iostream.h>
#include <windows.h>
int main(int, char **)
{
    int *ptr = new int[2];          //Определить число элементов
    ptr[0] = 0;
    ptr[1] = 1;
    for (int i=0; i <= 2; i++) {    //ОШИБКА
        //ABR when i is 2
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n';
    }
    delete[] ptr;
    return(0);
}

ABW: Array Bounds Write Выход за пределы массива при записи

#include <iostream.h>
#include <windows.h>
int main(int, char **)
{
    int *ptr = new int[2];          //Определить число элементов
    for (int i=0; i <= 2; i++) {    //ОШИБКА
        ptr[i] = i;
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n'; //ABW + ABR when i is 2
    }
    delete[] ptr;
    return(0);
}

ABWL: Late Detect Array Bounds Write Cообщение указывает, что программа записала значение перед началом или после конца распределенного блока памяти

#include <iostream.h>
#include <windows.h>
int main(int, char **)
{
    int *ptr = new int[2];          //Определить число элементов
    for (int i=0; i <= 2; i++) {    //ОШИБКА
        ptr[i] = i;
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n';
    }
    delete[] ptr;  //ABWL: ОШИБКА
    return(0);
}

BSR: Beyond Stack Read сообщение указывает, что функция в программе собирается читать вне текущего указателя вершины стека

#include <windows.h>
#include <iostream.h>
#define A_LOT 256
int * setup_values(void)
{
    int values[A_LOT];    //ОШИБКА: должен быть статичным
    for (int i=0; i < A_LOT; i++) {
        values[i] = i;
    }
    return(values);       //ОШИБКА: неизвестно, что возвращать
}
int main(int, char **)
{
    int *values;
    values = setup_values();
    for (int i=0; i < A_LOT; i++) {
        //BSR: значения из  "setup_values" больше не находятся в стеке

        cerr << "element #" << i << " is " << values[i] << '\n';
    }
    return(0);
}

BSW: Beyond Stack Write сообщение указывает, что функция в программе собирается писать вне текущего указателя вершины стека (пример см. выше)

FFM: Freeing Freed Memory Попытка освобождения свободного блока памяти

#include <iostream.h>
#include <windows.h>
int
main(int, char **)
{
    int *ptr1 = new int;    // int
    int *ptr2 = ptr1;       //ОШИБКА: должен дублировать
                       объект, а не копировать указатель
    *ptr1 = 10;
    *ptr2 = 20;
    cerr << "ptr1" << " is " << *ptr1 << '\n';
    cerr << "ptr2" << " is " << *ptr2 << '\n';
    delete ptr1;
    delete ptr2;            //FFM: ОШИБКА
    return(0);
}

FIM: Freeing Invalid Memory Попытка освобождения некорректного блока памяти

#include <iostream.h>

int main(int, char **)
{
   int i;
   delete[] &i;    //FIM: не было операции new. Освобождать нечего!
   return(0);
}

FMM: Freeing Mismatched Memory Сообщение указывает, что программа пробует освобождать память с неправильным ВЫЗОВОМ API для того типа памяти

#include <windows.h>

int main(int, char **)
{
    HANDLE heap1, heap2;
    heap1 = HeapCreate(0, 1000, 0);
    heap2 = HeapCreate(0, 1000, 0);
    int *pointer = (int *) HeapAlloc(heap1, 0, sizeof(int));
    HeapFree(heap2, 0, pointer);
             //ОШИБКА: неправильное освобождение памяти
    HeapDestroy(heap1);
    HeapDestroy(heap2);
    return(0);
}

FMR: Free Memory Read Попытка чтения уже освобожденного блока памяти

#include <iostream.h>
#include <windows.h>
int main(int, char **)
{
    int *ptr = new int[2];
    ptr[0] = 0;
    ptr[1] = 1;
    delete[] ptr;   //ОШИБКА: (специально сделано удаление)
    for (int i=0; i < 2; i++) {
        //FMR: ОШИБКА ДОСТУПА К ПАМЯТИ
        cerr << "element #" << i << " is " << ptr[i] << '\n';
    }
    return(0);
}

FMW: Free Memory Write Попытка записи уже освобожденного блока памяти

#include <iostream.h>

#include <windows.h>
int  main(int, char **)
{
    int *ptr = new int[2];
    ptr[0] = 0;
    ptr[1] = 1;
    delete[] ptr;   //ОШИБКА: (специально сделано удаление)
    for (int i=0; i < 2; i++) {
      ptr[i] *= i; //FMR + FMW: потому что ptr уже удален
      cerr << "element #" << i << " is " << ptr[i] << '\n';  //FMR
    }
    return(0);
}

HAN: Invalid Handle Операции над неправильным дескриптором

#include <iostream.h>
#include <windows.h>
#include <malloc.h>
int main(int, char **)
{
    (void) LocalUnlock((HLOCAL)3);//HAN: 3 - неправильный указатель
    return(0);
}

HIU: Handle In Use Индикация утечки ресурсов. Неправильная индикация дескриптора

#include <iostream.h>
#include <windows.h>
static long
get_alignment(void)
{
    SYSTEM_INFO sys_info;
    GetSystemInfo(&sys_info);
    return(sys_info.dwAllocationGranularity);
}
int
main(int, char **)
{
    const long  align = get_alignment();
    HANDLE      file_handle = CreateFile("file.txt",
                                GENERIC_READ|GENERIC_WRITE, 0, NULL,
                                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file_handle == INVALID_HANDLE_VALUE) {

        cerr << "ОШИБКА файла\n";
        return(1);
    }
    HANDLE      map_handle = CreateFileMapping(file_handle, NULL,
                                PAGE_READWRITE, 0, align, "mymap");
    if (map_handle == INVALID_HANDLE_VALUE) {
        cerr << "Unable to create actual mapping\n";
        return(1);
    }
    char       *pointer = (char *) MapViewOfFile(map_handle, FILE_MAP_WRITE,
                                        0, 0, align);

    if (pointer == NULL) {
        cerr << "Unable to map into address space\n";
        return(1);
    }
    strcpy(pointer, "hello\n");
    //HIU: map_handle все еще доступный и правильный
    //HIU: file_handle все еще доступный и правильный
    return(0);
}

ILK: COM Interface Leak Утечка COM интерфейса

#include <windows.h>

int main(int, char **)
{
    LPMALLOC        lpIm;
    CoGetMalloc( MEMCTX_TASK, (LPMALLOC*)&lpIm);
    IMalloc_Release(lpIm);  //НЕВЕРНЫЙ ЗАПРОС
    return(0);
}

IPR: Invalid Pointer Read Ошибка обращения к памяти, когда программа пытается произвести чтение из недоступной области

#include <iostream.h>

#include <windows.h>
int main(int, char **)
{
    int *ptr = (int *) 0x80000000;  //ОШИБКА: Указатель на зарезервированную
                                                часть адресного пространства
    for (int i=0; i < 2; i++) {
        //IPR: Попытка обращения к недопустимому указателю
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n';
    }
    return(0);
}

IPW: Invalid Pointer Write Ошибка обращения к памяти, когда программа пытается произвести запись из недоступной области

#include <iostream.h>
#include <windows.h>
int main(int, char **)
{
    int *ptr = (int *) 0x80000000;  //ОШИБКА: Указатель на зарезервированную
                                             часть адресного пространства
    for (int i=0; i < 2; i++) {
        //IPW + IPR: Попытка обращения к недопустимому указателю
        ptr[i] = i;
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n';
    }
    return(0);
}

MAF: Memory Allocation Failure Ошибка в запросе на распределение памяти

#include <iostream.h>
#include <windows.h>
#define VERY_LARGE 3000000000       //Больше, чем можем получить
int main(int, char **)
{
    int *ptr = new int[VERY_LARGE / sizeof(int)];   //MAF: нельзя так много
    if (ptr == 0) {
        cerr << "Failed to alloc, as expected\n";
                return (1);
    } else {
        cerr << "Got " << VERY_LARGE << " bytes @" << (unsigned long)ptr << '\n';
                delete[] ptr;
                return(0);
        }
}

MLK: Memory Leak Утечка памяти

#include <windows.h>
#include <iostream.h>
int main(int, char **)
{
    (void) new char[1000];
    (void) new char[1000];
    (void) new char[1000];
    (void) new char[1000];
    (void) new char[1000];
    //5 килобайт потерь
    return(0);
}

ИЛИ

void All::OnAppAbout()
{
        char *alex;                  //Указатель
        alex=(char *)malloc(20000);  //MLK: берем, но не отдаем
        CAboutDlg aboutDlg;
        aboutDlg.DoModal();
}

MPK: Potential Memory Leak Потенциальная утечка памяти (возникает когда производится операция над массивом не с нулевого элемента)

#include <iostream.h>
#include <windows.h>
int main(int, char **)
{
    static char *ptr = new char[500000];
    ptr += 100;   //MPK: обнаружится, как потенциально пропущенное
    return(0);
}

NPR: Null Pointer Read Попытка чтения с нулевого адреса

#include <iostream.h>
#include <windows.h>
int
main(int, char **)
{
    int *ptr = (int *) 0x0; //ОШИБКА
    for (int i=0; i < 2; i++) {
        //NPR: ошибка доступа
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n';
    }
    return(0);
}

NPW: Null Pointer Write Попытка записи в нулевой адрес

#include <iostream.h>
#include <windows.h>
int
main(int, char **)
{
    int *ptr = (int *) 0x0; //ОШИБКА
    for (int i=0; i < 2; i++) {
        //NPW: ошибка доступа
        ptr[i] = i;
        cerr << "ptr[" << i << "] == " << ptr[i] << '\n';
    }
    return(0);
}

UMC: Uninitialized Memory Copy Попытка копирования непроинициализированного блока памяти

#include <iostream.h>
#include <windows.h>
#include <string.h>

int main(int, char **)
{
    char *ptr = new char[10];
    char var[10];

        memcpy(var, ptr, 10);   //UMC предупреждение

        delete[] ptr;
    return(0);
}

UMR: Uninitialized Memory Read Попытка чтения непроинициализированного блока памяти

#include <iostream.h>
#include <windows.h>
int
main(int, char **)
{
    int *ptr = new int;
    cerr << "*ptr is " << *ptr << '\n';     //UMR: нет значения в ptr
    delete[] ptr;
    return(0);
}

Подведем итоги статьи описанием основных возможностей Purify:

  1. Отслеживание ошибок доступа к памяти
  2. Сбор и вывод статистики по использованию памяти
  3. Использование комплексного подхода к тщательному тестированию
  4. Технология OCI - Object Code Insertion позволяет детально отследить и выловить ошибку не только в контролируемом модуле, но и в модулях DLL сторонних разработчиков
  5. Тестирование ActiveX, COM/DCOM, ODBC, DLL
  6. Настраиваемый, двухуровневый способ тестирования (придирчивости) приложений
  7. Интеграция с Visual Studio
  8. Открытое API. Позволяет дописывать разработчикам собственные модули и присоединять их.
  9. Совместная работа с любым отладчиком
  10. Тестирование системных вызовов

Связаться с автором и получить дополнительную информацию можно по e-mail: rational@interface.ru

См. также: Эффективная разработка программного обеспечения с использованием технологий и инструментов компании RATIONAL

 

Размещение рекламы — тел. +7 495 4119920, ICQ 232284597

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

24 декабря

CITKIT.ru:

  • Новогодние поздравления
  • Сергей Кузнецов. Цикл Операционные системы: Ностальгия по будущему:

  • Алексей Федорчук. OpenSolaris 2008.11 Release

  • Сергей Голубев:

  • Евгений Чайкин aka StraNNik (Блогометки):

    17 декабря

  • С.Д.Кузнецов. Базы данных. Вводный курс

    10 декабря

    CITKIT.ru:

  • OpenSolaris 2008.11 Release

  • Альтернативные ОС: две грустные истории (С.Кузнецов)
  • Nokia N810 — доведение до ума
  • CitCity:

  • Платформа 2009: заоблачные перспективы Microsoft

    4 декабря

  • Лекция С.Д.Кузнецова Понятие модели данных. Обзор разновидностей моделей данных

    CITKIT.ru:

  • OpenSolaris 2008.11 Release. Первые впечатления

  • Linux vs FreeBSD: продолжим "Священные войны"?

  • Nokia N810 as is

  • Индульгенция для FOSS

  • Друзья СПО'2008

    26 ноября

  • Нечеткое сравнение коллекций: семантический и алгоритмический аспекты

    CitCity:

    CITKIT.ru:

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • 19 ноября

  • Проблемы экономики производства крупных программных продуктов

  • Язык модификации данных формата XML функциональными методами

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Заметки к книге:

  • FreeBSD: монтирование сменных устройств и механизм HAL
  • Текстовый редактор ee

    12 ноября

  • Правило пяти минут двадцать лет спустя, и как флэш-память изменяет правила (Гоц Грейф, перевод: Сергей Кузнецов)

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:
  • OSS в России: взгляд правоведа (В.Житомирский)

  • Новая статья из цикла С.Голубева "Железный марш":

    29 октября

  • О некоторых задачах обратной инженерии

  • Веб-сервисы и Ruby

  • Тестирование web-приложений с помощью Ruby

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

  • PuppyRus Linux - беседа с разработчиком (С.Голубев)

  • Сергей Кузнецов. Заметка не про Linux

    22 октября

  • Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки

    CITKIT.ru:

  • Сергей Кузнецов. Почему я равнодушен к Linux

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • Что надо иметь
    3. Базовые познания

    CitCity:

  • Управление IT-инфраструктурой на основе продуктов Microsoft

    15 октября

  • Методы бикластеризации для анализа интернет-данных

    CitCity:

  • Разъемы на ноутбуках: что они дают и зачем их так много?
  • AMD Puma и Intel Centrino 2: кто лучше?

    CITKIT.ru:

  • Новый цикл статей С.Голубева
    Железный марш:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    8 октября

  • Автоматизация тестирования web-приложений, основанных на скриптовых языках
  • Опыт применения технологии Azov для тестирования библиотеки Qt3

    Обзоры журнала Computer:

  • SOA с гарантией качества
  • Пикоджоуль ватт бережет
  • ICT и всемирное развитие

    CitCity:

  • Пиррова победа корпорации Microsoft

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Статья из архива:

  • Я живу в FreeBSD (Вадим Колонцов)

    Новые Блогометки:

  • Перекройка шаблона Blogger или N шагов к настоящему
  • Blogger. Comment style
  • Screenie или глянцевый снимок экрана

    2 октября

    CITKIT.ru:

  • Сага о FreeBSD (А. Федорчук)

    Zenwalk: пакет недели

  • Банинг — интеллектуальное развлечение (С.Голубев)

    CitCity:

    25 сентября

  • Клермонтский отчет об исследованиях в области баз данных

    CITKIT.ru:

  • Пользователям просьба не беспокоиться... (В.Попов)

  • Снова про ZFS: диск хорошо, а два лучше
  • Командная оболочка tcsh (А.Федорчук)

    Zenwalk: пакет недели

    17 сентября

  • T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов
  • Технология Azov автоматизации массового создания тестов работоспособности

    CITKIT.ru:

  • FreeBSD: ZFS vs UFS, и обе-две — против всех (А.Федорчук)

    Zenwalk: пакет недели

  • Дачнет — практика без теории (С.Голубев)

    10 сентября

  • За чем следить и чем управлять при работе приложений с Oracle
  • Планировщик заданий в Oracle
    (В.Пржиялковский)

    CITKIT.ru:

  • Microsoft: ответный "боян" (С.Голубев)

  • Причуды симбиоза, или снова "сделай сам" (В.Попов)

  • Файловые системы современного Linux'а: последнее тестирование
  • Zsh. Введение и обзор возможностей
    (А.Федорчук)

    Описания пакетов Zenwalk: Zsh, Thunar, Thunar-bulk-rename, Xfce4-places-plugin, Xfce4-fsguard-plugin

    Блогометки:

  • Google Chrome
  • Лончер для ASUS Eee PC 701

    3 сентября

    CITKIT.ru:

  • Заметки о ядре (А.Федорчук):

    Добавлены описания пакетов Zenwalk: Galculator, Screenshot, Gnumeric, Pidgin

    В дискуссинном клубе:

  • И еще о Википедии и Google Knol

  • Лекция для начинающего линуксоида (С.Голубев)

    26 августа

  • Транзакционная память (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Открыт новый проект Zenwalk: пакет недели

  • Статья Текстовые процессоры и их быстродействие: конец еще одной легенды?

    21 августа

    CITKIT.ru:

  • Почему школам следует использовать только свободные программы (Ричард Столлман)
  • Беседа Сергея Голубева с учителем В.В.Михайловым

  • Википедия или Гуглезнание? Приглашение к обсуждению (Алексей Федорчук)
  • Народная энциклопедия от Google (StraNNik)

  • Обзор Mandriva 2009.0 Beta 1 Thornicrofti
  • Новичок в Линукс: Оптимизируем Mandriva 2008.1

  • Книга Zenwalk. Приобщение к Linux:

    13 августа

    CitCity:

  • Мирный Atom на службе человеку. Обзор платы Intel D945GCLF с интегрированным процессором
  • Обзор процессоров Intel Atom 230 на ядре Diamondville

  • iPhone - год спустя. Скоро и в России?

    CITKIT.ru:

  • Интермедия 3.4. GRUB: установка и настройка (из книги Zenwalk. Приобщение к Linux)

    6 августа

  • СУБД с хранением данных по столбцами и по строкам: насколько они отличаются в действительности? (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Интермедия 2.2. Что неплохо знать для начала (из книги Zenwalk. Приобщение к Linux)

  • И снова про шрифты в Иксах (А.Федорчук)

  • 20 самых быстрых и простых оконных менеджеров для Linux

  • Дело о трех миллиардах (С.Голубев)

    30 июля

  • OLTP в Зазеркалье (Пересказ: С. Кузнецов)

    CitCity:

  • Будущее BI в облаках?
  • Тиражные приложения и заказная разработка. Преимущества для заказчика
  • Дискуссия со сторонниками заказной разработки

    CITKIT.ru:

  • Новые главы книги Zenwalk. Приобщение к Linux:
  • Глава 8. Пакеты: средства установки, системы управления, системы построения
  • Глава 9. Zenwalk: репозитории, пакеты, методы установки

    23 июля

    CITKIT.ru:

  • Все против всех. 64 vs 32, Intel vs AMD, tmpfs vs ext3
  • Две головы от Intel

  • Zenwalk: обзор штатных приложений (глава из книги "Zenwalk. Приобщение к Linux")

  • Нормально, Григорий...

    16 июля

    Обзоры журнала Computer:

  • Перспективы и проблемы программной инженерии в XXI веке
  • Большие хлопоты с большими объемами данных
  • Перспективы наноэлектроники

    CITKIT.ru:

  • Интермедия о лицензиях (А.Федорчук. "Zenwalk. Приобщение к Linux")

  • Есть ли будущее у KDE?

  • Linux в школе: альтернативный вариант в задачах

  • Шифр (приключения агента Никодима)

    10 июля

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия вступительная. Linux или GNU/Linux? Как вас теперь называть?
  • Глава 5. Среда Xfce
  • Глава 6. Xfce: приложения и плагины

  • ZUR (Zenwalk User Repository) FAQ

    2 июля

  • Персистентность данных в объектно-ориентированных приложениях (С. Кузнецов)

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия 1.2. Дорога к Zenwalk'у. Период бури и натиска
  • Интермедия 3.3. Немного о Linux'е и "железе"
  • Глава 4. Настройка: инструментами и руками
  • Интермедия 4.1. Zenpanel и конфиги: поиски корреляции

  • Интервью с Жан-Филиппом Гийоменом, создателем дистрибутива Zenwalk

  • Linux в школе: первые итоги (С. Голубев)

    25 июня

    CITKIT.ru:

  • Zenwalk. Приобщение к Linux (А. Федорчук)

  • Логика и риторика (С.Голубев)

  • Технология Tru64 AdvFS

  • Ханс Райзер предлагает отвести полицейских к телу Нины

    18 июня

  • Проекты по управлению данными в Google (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • ОС и поддержка "железа": мифы и реальность (А. Федорчук)

  • Linux в школе: другие дистрибутивы

  • Пинок (С. Голубев)

    4 июня

  • Ландшафт области управления данными: аналитический обзор (С. Кузнецов)

    CITKIT.ru:

  • Linux в школе: слово заинтересованным лицам

  • SlackBuild: пакеты своими руками

  • Linux от компании Novell. Установка и обзор openSUSE Linux

    Все публикации >>>




  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы — тел. +7 495 4119920, ICQ 232284597 Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2007 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...