Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Обработка ошибок

From Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: Error Handling
Den123
Последнее редактирование: hamishwillee (08 Dec 2011)

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

При выполнении программы может возникнуть целое множество различных ошибок - нехватка памяти (наиболее распространенная и понятная ошибка), различные ошибки взаимодействия и т.д. Уделение особого внимания обработке ошибок значительно повышает сложность создания ПО, поэтому Symbian предлагает ряд средств способных серьезно помочь разработчику.

Contents

Сбросы и ловушки

Сбрасываемый код является формой обработки исключительных ситуаций. Метод User::Leave() эквивалентен выбрасыванию исключения, перехват достигается с помощью макроса TRAP или TRAPD. Метод User::Leave() принимает один целочисленный параметр - код ошибки (не должен быть KErrNone). После вызова User::Leave() управление передается самому глубокому TRAP в стеке вызовов. Согласно договоренности, имена всех методов, которые могут привести к сбросу(сбрасываемые) должны оканчиваться буквой L. Вызывая метод с таким именем, разработчик должен быть готов к возможному возникновению сброса. Если метод в своем коде не содержит прямой вызов User::Leave(), однако, вызывает другие методы, в которых может произойти сброс - он также является сбрасываемым. Разработчик может проигнорировать соглашение об именовании и не поместить в конец имени сбрасываемого метода букву L, либо метод, объявленный как сбрасываемый может никогда не приводить к сбросу - таким ситуациям уделяется особое внимание - это исключения из общего правила.

В качестве альтернативы сбросу, код ошибки можно возвращать как результат выполнения функции. Множество функций в Symbian ОС возвращают код ошибки вместо генерации сброса. Если метод, в качестве результата выполнения, может просто вернуть код ошибки - он должен возвращать код ошибки, вариант сброса должен рассматриваться особо. Обычно сброс используется, если при возникновении ошибки необходимо передать контроль по стеку вызовов выше, чем на один уровень ("развернуть" стек вызовов). Также стоит отметить - использование сброса и ловушек требует дополнительных ресурсов, возврат кода ошибки, в качестве результата выполнения, работает быстрее.

Пример:

TRAPD(retVal, DoServiceL(aCmd, msgId));
if(retVal != KErrNone)
{
WriteErrorL(retVal, msgId);
}

Макрос TRAPD объявляет переменную retVal и производит вызов DoServiceL(). В этом случае метод DoServiceL() должен быть объявлен как void. Если во время его выполнения не произошло сброса (нормальное развитие событий), значение retVal будет установлено в KErrNone. Если же будет сгенерирован сброс, в retVal будет записан код сброса, который может быть обработан в дальнейшем.

Стек очистки

Стек очистки - это стек указателей (и некоторой дополнительной информации). Указатель на объект, созданный в динамической памяти, может быть помещен в стек очистки. При использовании макроса TRAP в стек очистки заносится маркер и, если произойдет сброс, то все объекты, указатели на которые хранятся в стеке до маркера TRAP буду автоматически уничтожены.

В стек очистки можно поместить только указатели на динамически созданные объекты. Следовательно, статически созданные объекты не будут уничтожаться при сбросе, поэтому только объекты T-классов должны создаваться статически. Стек очистки - это настоящий стек, Вы можете помещать в него указатели (метод PushL) и извлекать их из него (метод Pop()). Как и в обычном стеке, нет возможности извлечь элемент, если он не находится на вершине стека, поэтому извлекать элементы из стека нужно в строго определенном порядке (обратном тому, каким они были помещены в стек).

Двухфазное конструирование

Одна из частых причин возникновения сброса - нехватка памяти. В Symbian ОС используется концепция двухфазного конструирования сложных объектов чтобы корректно обрабатывать эту проблему. Первая фаза - выделение памяти под объект в куче (конструктор не должен генерировать сброс, либо вызывать функции, которые могут привести к сбросу). После создания объекта он помещается в стек очистки, далее выполняется вторая фаза конструирования (вызывается конструктор второй фазы, обычно он называется ConstructL()) во время выполнения которой уже может произойти сброс. Часто обе фазы конструирования объединяют в рамках одной статической функции-фабрики.

Паники

Все, что обсуждалось выше, относится к ошибкам времени выполнения которые можно предвидеть. К сожалению, подобные методы обработки ошибок нельзя применить к программным ошибкам (к ошибкам в логике работы программы). Такого рода ошибки должны быть выявлены и устранены на этапе разработки/отладки программы. Если такого рода ошибка происходит в релизной версии программы и дальнейшая корректная работа программы невозможна, выполнение программы должно быть аккуратно завершено.

Для этого в Symbian ОС предусмотрен метод User::Panic(). В качестве параметров он принимает строку (до 16 символов) и целочисленный код паники. Вызов этого метода приводит к тому, что Ваша нить (фактически процесс) уничтожаются и выводится сообщение об ошибке. Во время отладки Symbian может предоставить достаточно много информации о причинах возникновения паники; в итоговой версии программы вся доступная информация (ваше сообщение об ошибке и код паники) будут выведены на экран телефона конечного пользователя, который в дальнейшем может проинформировать Вас (надейтесь).

Стандартный способ использования паник - это утверждения(assertions). В Symbian представлены следующие макросы: __ASSERT_DEBUG и __ASSERT_ALWAYS. Оба макроса принимают два параметра: утверждение и выражение. Если утверждение неверно - выполняется выражение, которое обычно содержит вызов User::Panic(). Существует множество мнений по поводу того, стоит ли включать утверждения в итоговую версию программы. Хорошей практикой является использования как можно большего числа проверок в отладочной версии.

This page was last modified on 8 December 2011, at 23:34.
158 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×