InternalError: Плохая редкая магия переключения - что это значит? - PullRequest
3 голосов
/ 20 марта 2012

Сегодня у меня есть трассировка стека с очень странной ошибкой. На самом деле, я могу быть первым, кто получил это (YAY!), Так как до публикации этого вопроса единственные случаи "плохой редкой магии переключения" в Google были в исходном коде Android.

Вот часть stacktrace (Android 2.3.4):

java.lang.InternalError: bad sparse switch magic
at org.my.app.MyItemAdapter.(MyItemAdapter.java:64)
at org.my.app.MyActivity.onCreate(MyActivity.java:78)

Ошибка при выходе из конструктора MyItemAdapter. Поскольку это внутреннее, я уверен, что это не моя вина, но я просто хотел бы знать, что случилось в Dalvik VM.

Эта ошибка, похоже, связана с инструкцией switch, просто для пояснения - я не использовал ее непосредственно в конструкторе MyItemAdapter. Чтобы понять, что пошло не так, мне, вероятно, придется внимательно изучить много кода, связанного с dalvik, поэтому я спрашиваю вас - может быть, есть кто-то, кто может объяснить мне - что пошло не так? Мне просто интересно.

РЕДАКТИРОВАТЬ

Вот фрагмент кода Android, который выдает эту ошибку: http://androidxref.com/source/xref/dalvik/vm/interp/Interp.cpp#1070

1 Ответ

4 голосов
/ 20 марта 2012

Существует декс-байт с разреженным переключателем, который указывает интерпретатору Android на область памяти, которая на самом деле не является оператором разреженного переключения.

Байт-код Dex может представлять два типа операторов переключения: упакованный или разреженный. Упакованный оператор switch должен хранить только самое низкое значение для включения. Каждое последующее значение переключателя увеличивается на единицу от предыдущего значения, так что операторы case сохраняют только цель перехода в байтовом коде. Формат разреженного переключателя имеет запись для одного значения и цель перехода для каждого оператора case. См. Раздел «sparse-switch-payload» в документе «Байт-код для Dalvik VM» (http://source.android.com/tech/dalvik/dalvik-bytecode.html).

Операторы разреженного переключения в dex указываются инструкцией с байтовым кодом noop со вторым байтом 0x02 (http://androidxref.com/source/xref/dalvik/libdex/DexOpcodes.h#53).) Первый байт инструкции noop всегда 0x00, так что полная "магическая сигнатура" разрежена оператор switch равен 0x0200.

Инструкция по байт-коду dex для фактического выполнения оператора разреженного переключателя называется sparse-switch. Это код 0x2c, и он также требует регистр для проверки с оператором switch и адрес таблицы переключателей . Я считаю, что адрес таблицы переключателей в вашем файле dex неверен. Без дополнительной информации было бы трудно сказать, почему.

...