InternalError:糟糕的稀疏开关魔法 - 这意味着什么?

时间:2012-03-20 13:39:08

标签: java android dalvik

今天我有一个带有非常奇怪错误的堆栈跟踪。实际上,我可能是第一个得到这个的人(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 个答案:

答案 0 :(得分:4)

有一个稀疏开关的dex字节代码,它将Android解释器指向一个实际上不是稀疏开关语句的内存区域。

Dex字节代码可以表示两种类型的switch语句:packed或sparse。打包的switch语句只需存储最低值即可打开。每个后续开关值从前一个值加1,因此case语句仅在字节代码中存储分支目标。稀疏开关格式具有一个值的条目和每个case语句的分支目标。请参阅“Dalvik VM的字节码”文档(http://source.android.com/tech/dalvik/dalvik-bytecode.html)中的“sparse-switch-payload”部分。

dex中的稀疏开关语句由noop字节代码指令指示,第二个字节为0x02(http://androidxref.com/source/xref/dalvik/libdex/DexOpcodes.h#53)。 noop指令的第一个字节总是0x00,因此稀疏switch语句的完整“魔术签名”是0x0200。

实际执行稀疏switch语句的dex字节代码指令称为稀疏开关。它的代码是0x2c,它还需要一个寄存器来测试switch语句和switch表的地址。我相信你的dex文件中的switch表的地址是不正确的。没有更多信息,就很难说出原因。