×
Namespaces

Variants
Actions

Паника(Panic)

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: Panic
Den123
Последнее редактирование: hamishwillee (09 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 9 December 2011, at 02:29.
70 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.

×