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.

Паника(Panic)

From Wiki
Jump to: navigation, search
Article Metadata

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

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

Symbian SDK представляет несколько макросов для организации утверждений:

  • ASSERT - выбрасывает панику "USER 0" только в отладочной версии программы
  • __ASSERT_DEBUG и __ASSERT_ALWAYS позволяют вам выполнить действия если утверждение неверно для отладочной и для любой версии соответственно.

Кроме того, в исходном коде можно использовать вызов User::Panic(). Этот метод прерывает выполнение текущей нити, выбрасывает панику с кратким описанием и кодом. Ниже описаны часто встречающиеся коды паник, полный перечень можно найти в документации SDK:

 Symbian OS v9.x » Symbian OS reference » System panic reference[1]»

Contents

E32USER-CBase 63

Генерируется при попытке извлечь слишком много элементов из стека очистки на текущем уровне:

HBufC* buffer = HBufC::NewL(15);
CleanupStack::PushL(buffer);
// Стек очистки содержит только один элемент, buffer.
// Извлечение двух элементов из стека -> E32USER-CBase 63 panic
CleanupStack::PopAndDestroy(2);

E32USER-CBase 69

Все программы должны создавать свой собственный стек очистки.Данная паника генерируется при попытке использовать стек очистки если он предварительно не создан. Пример функция GLDEF_C TInt E32Main():

{
// Выбрасывание E32USER-CBase 69 panic
HBufC* buffer = HBufC::NewLC(10);
 
return KErrNone;
}

Правильный код:

void MainL()
{
HBufC* buffer = HBufC::NewLC(10);
 
return KErrNone;
}
 
GLDEF_C TInt E32Main()
{
CTrapCleanup* cleanup=CTrapCleanup::New();
TRAPD(error,MainL());
delete cleanup;
}

E32USER-CBase 71

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

TRAPD(error, pointer = CExample::SomeFunctionLC());

В этом примере паника генерируется при завершении действия ловушки так как функция SomeFunctionLC() поместила указатель в стек очистки. Чтобы избежать такой ошибки необходимо извлечь указатель из стека до завершения ловушки:

TRAPD( error, pointer = CExample::SomeFunctionLC();
CleanupStack::Pop(pointer) );

Теперь, если во время выполения функции произойдет сброс - указатель будет уничтожен стеком очистки. Если же сброса не будет, указатель будет извлечен из стека с помощью функции Pop().

Замечание: Не рекомендуется вызывать LC-функции внутри ловушки.

KERN-EXEC 3

Обычно это неперехваченное исключение общего характера. Определить причину его возникновения достаточно сложно. Ниже приведена пара характерных примеров.

Использование неинициализированной переменной:

CConsoleBase* console;
// Инициализация переменной Console не происходит, как результат -
// KERN-EXEC 3 panic при попытке использования
// console = Console::NewL(KTextConsoleTitle,
// TSize(KConsFullScreen, KConsFullScreen));
console->Printf(KTextHello);

Попытка использования слишком большого значения в строке форматирования:

_LIT(KUnitTxt, "units");
HBufC* unitTxt = KUnitTxt().AllocLC();
// Целое слишком большое, не помещается в "%d"; нужно использовать "%Ld"
TInt64 totalSize = 12345678901;
console->Printf(_L("Total size is %d %S"), totalSize, unitTxt);
CleanupStack::PopAndDestroy(unitTxt);

USER 13

Генерируется при передаче неправильного списка переменных в функцию AppendFormatList при использовании форматов %S или %s. В примере, приведенном ниже, паника генерируется макросом _L так как формат %d сможет принять только первые 32 бита 64-битной переменной totalWeight. Соответственно, оставшиеся 32 бита не помещаются и воспринимаются как указатель для следующего форматирующего символа %S.

_LIT(KUnitTxt, "kg");
// TInt64 требует использовать %Ld/%Lu в качестве форматирующего символа, не %d
TInt64 totalWeight = 150;
console->Printf(_L("Total weight is %d %S"), totalWeight, &KUnitTxt);
Замечание: Паника возникнет только в отладочном режиме.

Различные паники

Код паники Причина Решение
E32USER-CBase 90 Попытка извлечь значение не равное ожидаемому. Проверьте вызовы CleanupStack::Pop
USER 0 Утверждение (assertion) неверно. Проверьте утверждения.
This page was last modified on 8 December 2011, at 23:29.
242 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.

×