Как отладить ошибку underflow стека времени выполнения?
Я действительно изо всех сил пытаюсь решить стек underflow, который я получаю. Трассировка, которую я получаю во время выполнения:
VerifyError: Error #1024: Stack underflow occurred. at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at flash.net::URLLoader/onComplete()
это особенно трудно отлаживать, потому что когда я запускаю в режиме отладки, его не происходит вообще. Это происходит только при компиляции в релиз.
есть ли у кого-нибудь советы по отладке стека Underflow? Есть ли четкое объяснение того, что это означает для Flash?
в случае, если это помогает, эта ошибка происходит, когда я нажимаю кнопку, обработчик которой делает вызов RPC, который использует URLLoader, AsyncToken, а затем вызывает набор экземпляров AsyncResponder, связанных с AsyncToken. С некоторыми серверными журналами, а также некоторыми журналами, взломанными в swf, я знаю, что UrlLoader успешно выполняет и получает crossdomain.xml-файл, правильно его обрабатывает (т. е.: если я его разрушу, я получу ошибку безопасности), а также успешно завершает запрос "load" (сервер отправляет данные.) Кажется, что в этом случае происходит утечка.Полный процесс прослушивания/обработки (как, конечно, подразумевается и обратной трассировкой).
mxmlc используется = из flex_sdk_4.5.0.20967
пример игрока (я пробовал несколько) = 10.2.153.1
обновление: моя конкретная проблема решается... но я оставляю вопрос как есть, так как я хотел бы знать, как обычно отлаживать такую проблему, а не просто получать мои конкретные решение.
в моем коде у меня было следующее определение приложения:
<s:Application height="100%" width="100%"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="InitData();">
обратите внимание, что код / был прикреплен к initialize
событие.
InitData () и соответствующие определения:
import classes.RpcServerProxy;
public var SP:RpcServerProxy;
public function InitData():void {
SP = new RpcServerProxy("http://192.168.1.102:1234");
}
когда я переключил вызов InitData (), чтобы быть на onCompletion
событие вместо initialize
(спасибо J_A_X!), проблема полностью исчезает. То, что, кажется, происходило, было именно этим событием.Полный обработчик событий (onComplete в стеке trace) использовал глобальный объект SP. Что-то в компиляции release (vs debug) должно было повлиять на время запуска инициализации переменной SP. Перемещение обработчика позже в onCompletion
событие решило все проблемы.
как сказано выше, я все равно хотел бы знать, какие трюки/инструменты доступны для отладки таких проблем инициализации.
обновление 2:
applicationComplete
кажется, даже лучше, чем creationComplete
поставить код инициализации приложения. См.эта запись в блоге для некоторого объяснения, и видео (около 4:25) евангелистом Adobe Tech для примера простой инициализации данных "запуск приложения".
9 ответов
Stack underflow в основном означает, что компилятор испортился.
можно использовать SWFWire Инспектор чтобы посмотреть байт-код обработчика событий, если вы хотите точно знать, как он испортился. Вы также можете использовать Отладчик SWFWire чтобы увидеть, какие методы были вызваны, но в этом случае, вы уже знали, где это происходило.
Если вы опубликуете сломанный swf, я могу дать вам больше информации.
Шон прав, что для его отладки вы можете посмотреть на байтовый код, но это не звучало привлекательным для меня.
основываясь на моем опыте и исследованиях, это часто связано с наличием оператора трассировки, который неправильно компилируется в режиме выпуска и генерирует недопустимый байтовый код. Итак, я бы сказал " отладить "его:" ищите места, где вы используете трассировку. Попробуйте прокомментировать их все в оскорбительной функции и посмотреть, исчезнет ли проблема."
в моем случае, это был оператор трассировки как первая строка блока catch:
catch (e:TypeError) {
trace(e.getStackTrace()); //This line is the problem
throw new Error("Unexpected type encountered");
}
Я нашел кого-то еще с этим вопросом здесь.
этот код также приводит к стеку underflow только в режиме выпуска (флаг-debug=false):
true && trace('123');
mxlmc flex sdk версии 4.5.0.20967, flashplayer версии 10.3.181.14 (linux).
проверьте код на наличие подобных выражений.
этот код вызвал у меня проблемы, когда я скомпилировал кандидата на выпуск из flash builder 4.5
public function set configVO( value:PopupConfigVO ):void
{trace("CHANGING")
разрешено путем вставки пространства между трассировкой и фигурной скобкой
public function set configVO( value:PopupConfigVO ):void
{ trace("CHANGING")
надеюсь, что это помогает.
для людей, ищущих ту же проблему, я только что получил это, вызванное оператором трассировки в случае "по умолчанию" оператора switch. Прокомментировал трассировку, stack underflow разрешен.
интересные... Я получал эту ошибку с SWF, который я вытащил из интернета, графическую демонстрацию на основе Away3D. В то время я запускал это на VM Tamarin, а не фактическое время выполнения Flash/AIR, поэтому мог придерживаться точки останова в строке "verifyFailed(kStackUnderflowError)" и видеть, что происходит.
флаг-Dverbose также помог найти виновника:
typecheck MethodInfo-1480()
outer-scope = [global]
[Object~ Object] {} ()
0:pop
VERIFY FAILED: Error #1024: Stack underflow occurred.
и глядя на ABC с помощью SWFInvestigator, я нашел это:
var function(Object):void /* disp_id=0 method_id=1480 nameIndex = 0 */
{
// local_count=2 max_scope=0 max_stack=0 code_len=2
// method position=52968 code position=155063
0 pop
1 returnvoid
}
таким образом, существует очевидная проблема, когда "трассировка" была удалена, но компилятор поместил туда "pop": я бы не подумал, что это необходимо, поскольку вызов трассировки предположительно должен был быть сделан через "callpropvoid"?
вполне почему это не терпит неудачу на AIR / Flash, я не знаю..
в любом случае: похоже на проблему компилятора ASC i.e возможно, один из компиляторов ActionScript3 имел ошибку с этим-следовательно, обходные пути, которые были до сих пор говорилось.
У меня была точно такая же проблема, но в моем случае причиной проблемы была инструкция trace в месте, где компилятор не ожидал, что он ее найдет, сразу после объявления пакета в начале класса:
package utils
{
trace ("trace something here");
и именно поэтому компиляция в режиме отладки удалила проблему.
это довольно просто, и это не имеет ничего общего с пробелами до или после скобок, команд трассировки или что-то еще: это просто 1 действительно простая вещь:
НЕ ЦИКЛ ПУСТОЙ!
значение, при разработке, мы все / / иногда комментируем некоторые строки, и когда это приводит к
for (...) {
// skip for now
}
компилятор получает :
for(...){}
и что мои хорошие друзья, это то, что компилятору не нравится!
Итак, никаких пустых петель и ты снова в пути...
счастливой охоты, П.