×
Namespaces

Variants
Actions

Archived:Методы отладки

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngОтправлено в архив: Данная статья отправлена в архив так как, на сегодняшний день, не представляет ценности для сторонних разработчиков коммерческих решений. If you think this article is still relevant, let us know by adding the template {{ForArchiveReview|write your reason here}}.

Article Metadata

Совместимость
Статья
Перевод:
Den123
Последнее редактирование: hamishwillee (27 Aug 2012)


Contents

Эмулятор не отображает параметры возникшей паники

При возникновении паники, эмулятор отображает ее параметры только в том случае, если файл с именем "ErrRd" существует в определенной папке. Если такого файла нет, отображается сообщение следующего вида:

Panic.jpg

По такому сообщениию трудно определить причины возникновения паники.

В предыдущих версиях SDK (до 3-го издания) файл ErrRd нужно было создавать вручную, начиная с 3-го издания этот файл существует по умолчанию в папке "\Symbian\9.2\S60_3rd_FP1\Epoc32\winscw\c\resource". При наличии этого файла информация о возникшей панике отображается следующим образом:

Panic with ErrRd.jpg

Совет: Если вы используете SDK для 3-го издания, однако файл ErrRd найти не можете, воспользуйтесь меню эмулятора Tools > Preferences и выберите Extended panic code file.

Поиск ошибок с помощью утверждений

Утверждения используются для проверки корректности значений различных переменных, например с их помощью можно проверить параметры функций, возвращаемые значения, состояния объектов и т.д. Для реализации утверждений в Symbian предусмотрено два макроса __ASSERT_ALWAYS и __ASSERT_DEBUG. Разница заключается в том, что __ASSERT_ALWAYS работает всегда, в то время как __ASSERT_DEBUG только в отладочных версиях программы.

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

Пример использования:

void TestValue(TInt aValue)
{
_LIT(KPanicCategory, "TestValue");
__ASSERT_DEBUG((aValue >= 0), User::Panic(KPanicCategory, 99));
// Выполнение функции
// ...
}

В этом примере генерируется паника -99 в случае если aValue меньше нуля. Проверка срабатывает только в отладочной версии программы.

Если нет необходимости обрабатывать сгенерированную в результате неверного утверждения панику, можно воспользоваться макросом ASSERT. При использовании ASSERT не нужно определять параметры выбрасываемой паники.

Определение этого макроса в файле e32def.h:

#define ASSERT(x) __ASSERT_DEBUG(x, User::Invariant())

Пример использования

void TestValue(TInt aValue)
{
ASSERT(aValue >= 0);
// Выполнение функции
// ...
}


Определение утечек памяти с помощью макросов __UHEAP_MARK и __UHEAP_MARKEND

Макросы __UHEAP_MARK и __UHEAP_MARKEND позволяют определить, насколько корректно ваше приложение использует динамическую память (нет ли утечек).

Пример использования:

GLDEF_C TInt E32Main()
{
// Начало проверки наличия утечек памяти
__UHEAP_MARK;
 
// Создаем массив из 10 элементов в куче
CArrayFixFlat<TInt>* fixFlatArray;
fixFlatArray = new(ELeave) CArrayFixFlat<TInt>(10);
// Массив не был удален - возникла утечка памяти
 
// Окончания проверки - генерация паники
__UHEAP_MARKEND;
 
return KErrNone;
}

В этом примере, по окончанию выполнения программы, возникнет паника, так как массив не был удален - возникла утечка памяти.

Memory leak MACRO.jpg

Стоит отметить, что эти макросы работают только в отладочной версии программы и никак не влияют на итоговую версию программы.


Макросы для контроля инвариантности объектов

Существуют два системных макроса с помощью которых можно выполнить проверку состояния объекта: __DECLARE_TEST и __TEST_INVARIANT. На практике эти макросы используются следующим образом: создается функция которая выполняет проверку состояния объекта, далее эта функция вызывается в коде, где эта проверка необходима (обычно в начале и в конце функции, которая изменяет состояние объекта). Ниже представлен пример использования данных макросов - класс CLivingPerson хранит информацию о человеке и контролирует значения пола и возраста.

class CLivingPerson : public CBase
{
public:
enum TGender {EMale, EFemale};
public:
CLivingPerson(TGender aGender);
~CLivingPerson();
public:
void SetAge(const TInt aAge);
private:
TGender iGender;
TInt iAgeInYears;
__DECLARE_TEST; // тестирование инвариантности объекта
};
 
CLivingPerson::CLivingPerson(TGender aGender) : iGender(aGender) {}
CLivingPerson::~CLivingPerson() {}
 
void CLivingPerson::SetAge(const TInt aAge)
{
// установка возраста и контроль инвариантности
__TEST_INVARIANT;
iAgeInYears = aAge;
__TEST_INVARIANT;
}
 
void CLivingPerson::__DbgTestInvariant() const
{
#ifdef _DEBUG // Только для отладочной версии
// Пол должен быть определен корректно
ASSERT((iGender == EMale) || (iGender == EFemale));
 
// Возраст не может быть отрицательным
ASSERT(iAgeInYears >= 0);
#endif
}

Если состояние объекта некорректное (возраст или пол определены неверно), будет сгенерирована паника USER 0.


Определение некорректного использования стека очистки

Объекты должны извлекаться из стека очистки, если далее в коде нет опасности возникновения сброса. Соответственно, извлечение из стека обычно осуществляется для того чтобы удалить объект. Для реализация извлечения из стека и последующего гарантированного удаления можно использовать функцию PopAndDestroy, которая позволяет избежать возникновения утечек памяти.

Обе функции CleanupStack::Pop и CleanupStack::PopAndDestroy имеют перегруженные варианты, которые принимают в качестве параметра "ожидаемый элемент", который должен быть извлечен из стека. В случае если этот параметр не равен элементу на вершине стека, генерируется паника E32USER-CBase 90. Благодаря такой реализации, можно обнаружить некорректное использование стека очистки.

CClass* obj = new(ELeave) CClass;
CleanupStack::PushL(obj);
// ...
// Генерируется паника, если "obj" не на вершине стека
CleanupStack::PopAndDestroy(obj);

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

This page was last modified on 27 August 2012, at 06:44.
76 page views in the last 30 days.
×