Подтвердить что ты не робот

Как отладить ошибку стека стека во время выполнения?

Я действительно пытаюсь решить проблему стека, которую я получаю. След, который я получаю во время выполнения:

VerifyError: Error #1024: Stack underflow occurred.

at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

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

Есть ли у кого-нибудь советы о том, как отлаживать стекирование под потоком? Есть ли чистое объяснение того, что это значит для Flash?

В случае, если это помогает, эта ошибка возникает, когда я нажимаю кнопку, чей обработчик выполняет вызов RPC, который использует URLLoader, AsyncToken, а затем вызывает набор экземпляров AsyncResponder, связанных с AsyncToken. С некоторыми протоколами на стороне сервера, а также с некоторыми протоколами, взломанными в swf, я знаю, что UrlLoader успешно выполняет и GET'ing файл crossdomain.xml, правильно обрабатывает его (то есть: если я его обману, я получаю защиту ошибка), а также успешно завершает запрос "load" (сервер отправляет данные). Как представляется, процесс underflow происходит в процессе прослушивания/обработки Event.COMPLETE(как, конечно, подразумевается также трассировка).

mxmlc used = from 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() и соответствующие defintions являются/были:

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!), проблема полностью исчезла. Похоже, что происходило то, что обработчик события Event.COMPLETE(onComplete в трассировке стека) использовал глобальный объект SP. Что-то в компиляции release (vs debug) должно влиять на время запуска инициализации переменной SP. Перемещение обработчика позже в событие onCompletion разрешило все проблемы.

Как было сказано выше, мне все равно хотелось бы знать, какие трюки/инструменты доступны для отладки таких проблем с инициализацией.


ОБНОВЛЕНИЕ 2:

applicationComplete кажется еще лучшим событием, чем creationComplete, чтобы поместить код инициализации приложения. См. эту запись в блоге для некоторых объяснений и это видео (около 4:25) от Adobe Tech Евангелист за примером простой инициализации данных "запуска приложения".

4b9b3361

Ответ 1

Недостаток стека в основном означает, что компилятор испорчен.

Вы можете использовать SWFWire Inspector, чтобы посмотреть на байт-код обработчика событий, если вы хотите точно знать, как он перепутался. Вы также можете использовать SWFWire Debugger, чтобы узнать, какие методы были вызваны, но в этом случае вы уже знали, где это происходит.

Если вы опубликуете сломанный swf, я могу дать вам больше информации.

Ответ 2

Я избавился от этой ошибки, добавив аргумент компилятора:
-omit-следовая-выписка = ложь

Ответ 3

Шон прав, что для его отладки вы можете посмотреть на байтовый код, но это не звучит привлекательно для меня.

Основываясь на моем опыте и исследованиях, это часто связано с наличием оператора трассировки, который некорректно компилируется в режиме деблокирования и генерирует неверный код байта. Итак, я бы сказал "отлаживать" его: "Ищите места, где вы используете трассировку. Попробуйте прокомментировать их в функции оскорбления и посмотрите, не пропадет ли проблема".

В моем случае это был оператор trace как первая строка блока catch:

catch (e:TypeError) {
    trace(e.getStackTrace()); //This line is the problem
    throw new Error("Unexpected type encountered");
}

Я нашел кого-то другого с этой точной проблемой здесь.

Ответ 4

Этот код также приводит к переполнению стека только в режиме деблокирования (флаг -debug = false):

true && trace('123');

mxlmc flex sdk версия 4.5.0.20967, версия flashplayer 10.3.181.14 (linux).

Проверьте код для аналогичных выражений.

Ответ 5

Этот код вызвал у меня проблемы, когда я скомпилировал кандидат на выпуск из Flash Builder 4.5

public function set configVO( value:PopupConfigVO ):void
        {trace("CHANGING")

Решено путем вставки пробела между трассировкой и фигурной скобкой

public function set configVO( value:PopupConfigVO ):void
        { trace("CHANGING")

Надеюсь, что это поможет.

Ответ 6

Для людей, которые ищут одну и ту же проблему, я просто получил это из-за оператора трассировки в случае "по умолчанию" оператора switch. Прокомментировал трассировку, стекирование недополучено.

Ответ 7

Интересно... Я получал эту ошибку со SWF, который я снял с веб-страницы, демо-версию Away3D. В то время, когда я запускал это на Tamarin VM, а не в текущем времени работы 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        
}

Таким образом, существует очевидная проблема, когда "трассировка" была удалена, но компилятор добавил туда "поп": я бы не подумал, что это необходимо, поскольку вызов трассировки, по-видимому, должен быть выполнен с помощью callpropvoid?

Довольно, почему это не терпит неудачу в AIR/Flash, я не знаю..

В любом случае: выглядит мне как проблема компилятора ASC. Возможно, у одного из компиляторов ActionScript3 была ошибка с этим - следовательно, обходные решения, которые были упомянуты до сих пор.

Ответ 8

У меня была такая же проблема, но в моем случае причиной проблемы был оператор trace в месте, где компилятор не ожидал его найти сразу после объявления пакета в начале класса:

package utils 
{

trace ("trace something here");

И поэтому компиляция в режиме отладки устраняет проблему.

Ответ 9

Это довольно просто, и он не имеет ничего общего с пробелами до или после скобок, команд трассировки или что-то еще: это всего лишь 1 очень простая вещь:

НЕ ПОТЕРЯЙТЕ ПУСТОЙ!

Значение, при разработке, мы все//иногда комментируем некоторые строки, и когда это приводит к

 for (...) { 
             // skip for now
         }

компилятор получает:

      for(...){}

и что мои хорошие друзья, это то, что компилятор не любит!

Итак, NO пустых циклов, и вы снова на своем пути...

Счастливая охота, Р.