This page was last modified 21:47, 27 May 2008.
Методы отладки
From Forum Nokia Wiki
Перевод с английского, оригинальная статья находится здесь.
Contents |
Эмулятор не отображает параметры возникшей паники
При возникновении паники, эмулятор отображает ее параметры только в том случае, если файл с именем "ErrRd" существует в определенной папке. Если такого файла нет, отображается сообщение следующего вида:
По такому сообщениию трудно определить причины возникновения паники.
В предыдущих версиях SDK (до 3-го издания) файл ErrRd нужно было создавать вручную, начиная с 3-го издания этот файл существует по умолчанию в папке "\Symbian\9.2\S60_3rd_FP1\Epoc32\winscw\c\resource". При наличии этого файла информация о возникшей панике отображается следующим образом:
Совет: Если вы используете 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; }
В этом примере, по окончанию выполнения программы, возникнет паника, так как массив не был удален - возникла утечка памяти.
Стоит отметить, что эти макросы работают только в отладочной версии программы и никак не влияют на итоговую версию программы.
Макросы для контроля инвариантности объектов
Существуют два системных макроса с помощью которых можно выполнить проверку состояния объекта: __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);
Замечание: Проверка параметра на вершине стека осуществляется только в отладочной версии программы, в итоговой версии данная проверка не используется.
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Проблема с CCalEntryView::FetchL() | truf | Russian Developer Forum - Форум Российских разработчиков | 7 | 2008-04-04 18:51 |
| Ошибка компиляции | 3bepek | Russian Developer Forum - Форум Российских разработчиков | 11 | 2007-12-11 08:59 |
| Forum Nokia Wiki (русскоязычный портал) - Ваши пожелания | Ecconaut | Russian Developer Forum - Форум Российских разработчиков | 27 | 2008-04-15 19:50 |
| SyncML Task Id | igor_k11 | Russian Developer Forum - Форум Российских разработчиков | 4 | 2008-09-30 09:32 |
| RMobileUssdMessaging | truf | Russian Developer Forum - Форум Российских разработчиков | 30 | 2008-02-16 19:05 |



