servo icon indicating copy to clipboard operation
servo copied to clipboard

Android: 32-bit (x86 and ARM) apk crashes during startup.

Open mukilan opened this issue 1 year ago • 8 comments

Logs:

01-19 18:22:28.275  3931  3961 D simpleservo: thread 'Script(1,1)' panicked at /home/mukilan/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/7184f65/mozjs/src/gc/root.rs:150:28:
01-19 18:22:28.275  3931  3961 D simpleservo: misaligned pointer dereference: address must be a multiple of 0x8 but is 0xa85f2d8c

Enabling backtrace doesn't help as the names of functions are not printed.

Using logs and manual translation of addresses using nm and addr2line I was able to narrow the issue further to some miscompilation in the SM JIT. Specifically, the crash due to misaligned read from MutableHandle<Value> happens when loading servo.org because in the JIT code emitted by SM's CacheIRCompiler to invoke the VM function ProxyGetPropertyByValue, the address help by the MutableHandle is 4-byte aligned, instead of 8-byte (since JSValue is 8 bytes even on 32bit architectures).

It is unclear why this happens only after the rustc upgrade (which included upgrade to LLVM 16) .

mukilan avatar Jan 19 '24 14:01 mukilan

I am seeing similar crash on Apple silicon, should JIT be disabled temporarily for it too?

> ./mach run -r

UNSUPPORTED (log once): POSSIBLE ISSUE: unit 1 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) - using zero texture because texture unloadable
misaligned pointer dereference: address must be a multiple of 0x8 but is 0x4b4b4b4b4b4b4b4b (thread Script(1,1), at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs/src/rust.rs:809)
   0: <servo::backtrace::Print as core::fmt::Debug>::fmt
   1: core::fmt::rt::Argument::fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/rt.rs:138:9
      core::fmt::write
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/mod.rs:1114:21
   2: std::io::Write::write_fmt
   3: servo::backtrace::print
   4: servo::main2::main::{{closure}}
   5: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2021:9
      std::panicking::rust_panic_with_hook
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:735:13
   6: std::panicking::begin_panic_handler::{{closure}}
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:609:13
   7: std::sys_common::backtrace::__rust_end_short_backtrace
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:170:18
   8: rust_begin_unwind
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
   9: core::panicking::panic_nounwind_fmt
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:106:14
  10: core::panicking::panic_misaligned_pointer_dereference
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:193:5
  11: script::dom::bindings::conversions::get_dom_class
  12: <script::dom::node::SimpleNodeIterator<I> as core::iter::traits::iterator::Iterator>::next
  13: script::dom::document::Document::note_node_with_dirty_descendants
  14: script::dom::node::Node::note_dirty_descendants
  15: script::dom::element::Element::detach_shadow
  16: script::dom::document::Document::unregister_media_controls
  17: script::dom::htmlmediaelement::HTMLMediaElement::remove_controls
  18: <script::dom::htmlmediaelement::HTMLMediaElement as core::ops::drop::Drop>::drop
  19: core::ptr::drop_in_place<script::dom::htmlmediaelement::HTMLMediaElement>
  20: script::dom::bindings::codegen::Bindings::HTMLVideoElementBinding::HTMLVideoElement_Binding::_finalize::{{closure}}
  21: mozjs::panic::wrap_panic
  22: script::dom::bindings::codegen::Bindings::HTMLVideoElementBinding::HTMLVideoElement_Binding::_finalize
  23: _ZNK7JSClass10doFinalizeEPN2JS9GCContextEP8JSObject
             at /Users/rajveer/Projects/servo/target/release/build/mozjs_sys-166405fc766111da/out/build/dist/include/js/Class.h:649:5
      _ZN8JSObject8finalizeEPN2JS9GCContextE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/vm/JSObject-inl.h:99:12
      _ZN2js2gc5Arena8finalizeI8JSObjectEEmPN2JS9GCContextENS0_9AllocKindEm
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:132:10
  24: _ZL19FinalizeTypedArenasI8JSObjectEbPN2JS9GCContextERN2js2gc9ArenaListERNS5_15SortedArenaListENS5_9AllocKindERNS4_11SliceBudgetE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:204:29
      _ZL14FinalizeArenasPN2JS9GCContextERN2js2gc9ArenaListERNS3_15SortedArenaListENS3_9AllocKindERNS2_11SliceBudgetE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:235:5
  25: _ZN2js2gc9GCRuntime18foregroundFinalizeEPN2JS9GCContextEPNS2_4ZoneENS0_9AllocKindERNS_11SliceBudgetERNS0_15SortedArenaListE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:1736:8
  26: _ZN2js2gc9GCRuntime17finalizeAllocKindEPN2JS9GCContextERNS_11SliceBudgetE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:1937:8
  27: _ZN11sweepaction18SweepActionForEachI13ContainerIterIN7mozilla7EnumSetIN2js2gc9AllocKindEyEEES7_E3runERNS5_11SweepAction4ArgsE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:2163:19
  28: _ZN11sweepaction19SweepActionSequence3runERN2js2gc11SweepAction4ArgsE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:2128:23
  29: _ZN11sweepaction18SweepActionForEachIN2js2gc19SweepGroupZonesIterEP9JSRuntimeE3runERNS2_11SweepAction4ArgsE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:2163:19
  30: _ZN11sweepaction19SweepActionSequence3runERN2js2gc11SweepAction4ArgsE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:2128:23
  31: _ZN11sweepaction18SweepActionForEachIN2js2gc15SweepGroupsIterEP9JSRuntimeE3runERNS2_11SweepAction4ArgsE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:2163:19
  32: _ZN2js2gc9GCRuntime19performSweepActionsERNS_11SliceBudgetE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/Sweeping.cpp:2305:53
  33: _ZN2js2gc9GCRuntime16incrementalSliceERNS_11SliceBudgetEN2JS8GCReasonEb
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/GC.cpp:3668:11
  34: _ZN2js2gc9GCRuntime7gcCycleEbRKNS_11SliceBudgetEN2JS8GCReasonE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/GC.cpp:4179:3
  35: _ZN2js2gc9GCRuntime7collectEbRKNS_11SliceBudgetEN2JS8GCReasonE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/GC.cpp:4367:9
  36: _ZN2js2gc9GCRuntime2gcEN2JS9GCOptionsENS2_8GCReasonE
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/gc/GC.cpp:4444:3
  37: _ZN9JSRuntime14destroyRuntimeEv
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/vm/Runtime.cpp:266:8
  38: _ZN2js14DestroyContextEP9JSContext
             at /Users/rajveer/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d1f1519/mozjs-sys/mozjs/js/src/vm/JSContext.cpp:225:7
  39: <mozjs::rust::Runtime as core::ops::drop::Drop>::drop
  40: core::ptr::drop_in_place<mozjs::rust::Runtime>
  41: core::ptr::drop_in_place<script::script_runtime::Runtime>
  42: core::ptr::drop_in_place<script::script_thread::ScriptThread>
  43: std::sys_common::backtrace::__rust_begin_short_backtrace
  44: core::ops::function::FnOnce::call_once{{vtable.shim}}
  45: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2007:9
      <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/alloc/src/boxed.rs:2007:9
      std::sys::unix::thread::Thread::new::thread_start
             at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys/unix/thread.rs:108:17
  46: __pthread_joiner_wake
[2024-02-10T15:52:05Z ERROR servo::main2] misaligned pointer dereference: address must be a multiple of 0x8 but is 0x4b4b4b4b4b4b4b4b
thread caused non-unwinding panic. aborting.
Redirecting call to abort() to mozalloc_abort

Caught signal 11 in thread "Script(1,1)"
^CServo was terminated by signal 2

rajveermalviya avatar Feb 10 '24 15:02 rajveermalviya

For more info:

  • it crashes only on exit
  • ~~disabling js.baseline_interpreter.enabled, js.baseline_jit.enabled, js.ion.enabled seems to fix it.~~

rajveermalviya avatar Feb 10 '24 16:02 rajveermalviya

Can you file a new issue with that information? I think the JIT settings are just lucky and there's something broken in our media element teardown code.

jdm avatar Feb 10 '24 16:02 jdm

It is unclear why this happens only after the rustc upgrade (which included upgrade to LLVM 16) .

It reminds me of https://github.com/rust-lang/rust/issues/111229

sagudev avatar Feb 10 '24 16:02 sagudev

I was able to cross-compile Servo for 32-bit linux on a 64-bit host which allowed me to debug better.

I believe the root cause is the generateVMWrapper method in SM which is responsible for setting up the stack when invoking methods in the C++ VM from the jitted code. In particular, this method allocates the storage space for a JS Value on the stack and passes the address to that piece of stack memory as the MutableHandleValue out parameter of the invoked VM function.

Both armv7a and x86 backends seem to have the same issue where they don't ensure that stack address is properly aligned during allocation of the out parameter, which is a JS Value with alignas(8). Note that the alignas(8) is also propagated to the Value struct in jsapi.rs generated using bindgen, which means rust code also expects pointers to Values to be aligned to 8-bytes in 32-bit mode.

I suspect moving the call to setupUnalignedABICall in generateVMWrapper to be before we allocate the out parameter might fix the crash, but I haven't had a chance to verify this or dig deeper to ensure the logic for popping the stack will be able to take the out paramater in to account. I'll try to verify and report this upstream.

mukilan avatar Apr 01 '24 04:04 mukilan

@mukilan Just reminder that we use SM ESR 115 which may have different code: https://searchfox.org/mozilla-esr115/source

sagudev avatar Apr 01 '24 05:04 sagudev

The same issue is there in SM 115 as well, which is what I used during debugging. The logic for allocation of the out parameter has been refactored to a common method in latest code though.

mukilan avatar Apr 01 '24 05:04 mukilan

FYI I've reported this upstream.

mukilan avatar Apr 22 '24 09:04 mukilan