I see that, Dart stack trace all ends with 3/7/b/f (ARM architecture), while we know ARM/Thumb/Thumb(2) instructions are 2 or 4 bytes.

example: https://github.com/dart-lang/sdk/issues/43274

Warning: This VM has been configured to produce stack traces that violate the Dart standard.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 29278, tid: 29340, name 1.ui
isolate_dso_base: 6fe9d64000, vm_dso_base: 6fe9d64000
isolate_instructions: 6fe9d74000, vm_instructions: 6fe9d66000
    #00 abs 0000006fe9f4e87b virt 00000000001ea87b _kDartIsolateSnapshotInstructions+0x1da87b
    #01 abs 0000006fe9f4e4a3 virt 00000000001ea4a3 _kDartIsolateSnapshotInstructions+0x1da4a3
    #02 abs 0000006fe9d83ca3 virt 000000000001fca3 _kDartIsolateSnapshotInstructions+0xfca3

Thus, I wonder how could this happen? IMHO the ARM CPU will run the machine instructions (assembly) in the .so file in Android. But how can the CPU run it if all instructions do not align with 2/4 bytes?

Thanks for any suggestions!


Solution 1: Jake 'Alquimista' LEE

The lsb is the "thumb bit" so to say.

You can switch between ARM and thumb mode with the instruction bx or blx.

These instructions scan the lsb, and if it's set, it will switch to thumb mode and to ARM mode if otherwise. Then branch to address&~1

The stack trace shows the return address of the caller functions, and that they are odd indicates that they are written/compiled in thumb mode.