Skip to content

Rust compilation fails on a trivial input with "undefined symbol: __gxx_personality_v0" #17128

Closed
@hoodmane

Description

@hoodmane

Reproduction

Make a file main.rs consisting of:

fn main() {}

then run:

$ rustc main.rs --target wasm32-unknown-emscripten

results in:

error: undefined symbol: __gxx_personality_v0 (referenced by top-level compiled C/C++ code)
          warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
          warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
          warning: ___gxx_personality_v0 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
          Error: Aborting compilation due to previous errors

My minimized version of the failing link command:

emcc -sEXPORTED_FUNCTIONS=[\"_rust_eh_personality\"] \
/src/.docker_home/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/\
lib/rustlib/wasm32-unknown-emscripten/lib/libpanic_unwind-17507931f2722222.rlib  \
-o main.js

libpanic_unwind consists of a single object file panic_unwind<junk>.o which after disassembling is ~280 lines of wat:

Disassembly of panic_unwind.o
000272 func[16] <_ZN4core3mem4drop17h77313b5f84a3c8baE>:
 local[0] type=i32
 i32.const 0
 i32.const 0
 i32.store 2 0
 local.get 1
 i32.load 2 0
 local.get 0
 call 0 <invoke_vi>
 i32.const 0
 i32.load 2 0
 local.set 2
 i32.const 0
 i32.const 0
 i32.store 2 0
 block
   local.get 2
   i32.const 1
   i32.eq
   br_if 0
   block
     local.get 1
     i32.load 2 4
     local.tee 2
     i32.eqz
     br_if 0
     local.get 0
     local.get 2
     local.get 1
     i32.load 2 8
     call 1 <env.__rust_dealloc>
   end
   return
 end
 call 2 <__cxa_find_matching_catch_2>
 local.set 2
 call 3 <getTempRet0>
 drop
 local.get 0
 local.get 1
 call 17 <_ZN5alloc5alloc8box_free17h0b9b1e04bc852fdcE>
 local.get 2
 call 4 <__resumeException>
 unreachable
 end
0002ee func[17] <_ZN5alloc5alloc8box_free17h0b9b1e04bc852fdcE>:
 local[0] type=i32
 block
   local.get 1
   i32.load 2 4
   local.tee 2
   i32.eqz
   br_if 0
   local.get 0
   local.get 2
   local.get 1
   i32.load 2 8
   call 1 <env.__rust_dealloc>
 end
 end
000310 func[18] <__rust_panic_cleanup>:
 local[0] type=i32
 local.get 1
 i32.load 2 0
 call 5 <env.__cxa_begin_catch>
 local.set 2
 block
   local.get 1
   i32.load8_u 0 4
   i32.eqz
   br_if 0
   local.get 2
   i32.load8_u 0 8
   local.set 1
   local.get 2
   i32.const 1
   i32.store8 0 8
   block
     block
       block
         local.get 1
         br_if 0
         local.get 2
         i32.load 2 0
         local.set 1
         local.get 2
         i32.const 0
         i32.store 2 0
         local.get 1
         br_if 2
         i32.const 0
         i32.const 0
         i32.store 2 0
         i32.const 1
         i32.const 0
         i32.const 43
         i32.const 96
         call 7 <invoke_viii>
         i32.const 0
         i32.load 2 0
         local.set 2
         i32.const 0
         i32.const 0
         i32.store 2 0
         local.get 2
         i32.const 1
         i32.eq
         br_if 1
         unreachable
       end
       unreachable
       unreachable
     end
     call 2 <__cxa_find_matching_catch_2>
     drop
     call 3 <getTempRet0>
     drop
     call 8 <env._ZN4core9panicking15panic_no_unwind17h8f4ab85dd1f16b50E>
     unreachable
   end
   local.get 2
   i32.load 2 4
   local.set 2
   call 9 <env.__cxa_end_catch>
   local.get 0
   local.get 2
   i32.store 2 4
   local.get 0
   local.get 1
   i32.store 2 0
   return
 end
 call 10 <env.__rust_foreign_exception>
 unreachable
 end
0003d8 func[19] <__rust_start_panic>:
 local[0..2] type=i32
 global.get 0 <env.__stack_pointer>
 i32.const 16
 i32.sub
 local.tee 1
 global.set 0 <env.__stack_pointer>
 local.get 1
 i32.const 8
 i32.add
 local.get 0
 i32.load 2 0
 local.get 0
 i32.load 2 4
 i32.load 2 12
 call_indirect 0 0
 local.get 1
 i32.load 2 12
 local.set 0
 local.get 1
 i32.load 2 8
 local.set 2
 block
   i32.const 8
   call 11 <env.__cxa_allocate_exception>
   local.tee 3
   br_if 0
   i32.const 0
   i32.const 0
   i32.store 2 0
   local.get 0
   i32.load 2 0
   local.get 2
   call 0 <invoke_vi>
   i32.const 0
   i32.load 2 0
   local.set 3
   i32.const 0
   i32.const 0
   i32.store 2 0
   block
     local.get 3
     i32.const 1
     i32.eq
     br_if 0
     block
       local.get 0
       i32.load 2 4
       local.tee 3
       i32.eqz
       br_if 0
       local.get 2
       local.get 3
       local.get 0
       i32.load 2 8
       call 1 <env.__rust_dealloc>
     end
     local.get 1
     i32.const 16
     i32.add
     global.set 0 <env.__stack_pointer>
     i32.const 3
     return
   end
   call 2 <__cxa_find_matching_catch_2>
   local.set 1
   call 3 <getTempRet0>
   drop
   local.get 2
   local.get 0
   call 17 <_ZN5alloc5alloc8box_free17h0b9b1e04bc852fdcE>
   local.get 1
   call 4 <__resumeException>
   unreachable
 end
 local.get 3
 i32.const 0
 i32.store8 0 8
 local.get 3
 local.get 0
 i32.store 2 4
 local.get 3
 local.get 2
 i32.store 2 0
 local.get 3
 i32.const 56
 i32.const 2
 call 12 <env.__cxa_throw>
 unreachable
 end
0004d2 func[20] <_ZN12panic_unwind8real_imp17exception_cleanup17h416500fee4aa23e5E>:
 local[0] type=i32
 block
   block
     local.get 0
     i32.load 2 0
     local.tee 1
     i32.eqz
     br_if 0
     local.get 0
     i32.load 2 4
     local.set 0
     i32.const 0
     i32.const 0
     i32.store 2 0
     i32.const 3
     local.get 1
     local.get 0
     call 13 <invoke_vii>
     i32.const 0
     i32.load 2 0
     local.set 0
     i32.const 0
     i32.const 0
     i32.store 2 0
     local.get 0
     i32.const 1
     i32.ne
     br_if 1
     call 2 <__cxa_find_matching_catch_2>
     drop
     call 3 <getTempRet0>
     drop
     call 8 <env._ZN4core9panicking15panic_no_unwind17h8f4ab85dd1f16b50E>
     unreachable
   end
   local.get 0
   return
 end
 call 14 <env.__rust_drop_panic>
 unreachable
 end
000545 func[21] <rust_eh_personality>:
 local.get 0
 local.get 1
 local.get 2
 local.get 3
 local.get 4
 call 15 <env.__gxx_personality_v0>
 end

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions