InternalError: плохая разреженная магия переключения-что это значит?


Сегодня у меня есть stacktrace с очень странной ошибкой. На самом деле, я, возможно, первый человек, когда-либо получивший это (УРА!), так как до публикации этого вопроса единственные случаи "плохой магии разреженного переключения" в 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, поэтому я спрашиваю вас - может быть, есть кто - то, кто может объяснить мне-что пошло не так? Мне просто любопытно.

EDIT

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

1 3

1 ответ:

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

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

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

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