emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.67k stars 3.29k forks source link

Compiler crashes when compiling OpenCV 4.10.0 with `-fwasm-exceptions` #22170

Closed mologie closed 2 months ago

mologie commented 3 months ago

Hi! It is currently not possible to build OpenCV with -fwasm-exceptions. The compiler crashes during a WebAssembly pass while attempting to compile cv::JpegEncoder::write(cv::Mat const&, std::__2::vector<int, std::__2::allocator<int> > const&) in grfmt_jpeg.cpp.

I built a short automated reproducer script which downloads and builds OpenCV with affected arguments in the current directory.

https://gist.github.com/mologie/97406aa20ffbd04435ebab593d8a89e6

Usage:

git clone https://gist.github.com/97406aa20ffbd04435ebab593d8a89e6.git crash
cd crash
./build.sh

This Gist contains preprocessed sources and run script as emitted by clang via the reproducer script too. It's probably sufficient to reproduce the issue without building all of OpenCV.

The issue does not happen when merely setting -sSUPPORT_LONGJMP=wasm, so I guess that something in the WASM exception handling codegen code is the issue.

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.61 (67fa4c16496b157a7fc3377afd69ee0445e8a6e3)
clang version 19.0.0git (https:/github.com/llvm/llvm-project 7cfffe74eeb68fbb3fb9706ac7071f8caeeb6520)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/tri/.local/opt/emsdk/upstream/bin

Failing command line in full:

FAILED: modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o 
/usr/bin/ccache /home/tri/.local/opt/emsdk/upstream/emscripten/em++ -DHAVE_IMGCODEC_HDR -DHAVE_IMGCODEC_PFM -DHAVE_IMGCODEC_PXM -DHAVE_IMGCODEC_SUNRASTER -D_USE_MATH_DEFINES -D__OPENCV_BUILD=1 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-build/3rdparty/zlib -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/3rdparty/zlib -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/3rdparty/libpng -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-build/3rdparty/libjpeg-turbo -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/3rdparty/libjpeg-turbo/src -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgcodecs/include -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-build/modules/imgcodecs -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/core/include -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgproc/include -isystem /home/tri/devel/emscripten-opencv-linker-crash/opencv-build -fwasm-exceptions -Wno-#pragma-messages -Wno-deprecated-declarations   -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-unnamed-type-template-args -Wno-comment -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -fdiagnostics-show-option -Qunused-arguments -ffunction-sections -fdata-sections  -fvisibility=hidden -fvisibility-inlines-hidden -Wno-deprecated-declarations -Os -DNDEBUG -std=c++11 -fPIC -MD -MT modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o -MF modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o.d -o modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o -c /home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgcodecs/src/grfmt_jpeg.cpp
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.  Program arguments: /home/tri/.local/opt/emsdk/upstream/bin/clang++ -target wasm32-unknown-emscripten -mllvm -combiner-global-alias-analysis=false -mllvm -wasm-enable-sjlj -mllvm -disable-lsr --sysroot=/home/tri/.local/opt/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -fwasm-exceptions -Wno-#pragma-messages -Wno-deprecated-declarations -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-unnamed-type-template-args -Wno-comment -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -fdiagnostics-show-option -Qunused-arguments -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden -Wno-deprecated-declarations -Os -std=c++11 -fPIC -DHAVE_IMGCODEC_HDR -DHAVE_IMGCODEC_PFM -DHAVE_IMGCODEC_PXM -DHAVE_IMGCODEC_SUNRASTER -D_USE_MATH_DEFINES -D__OPENCV_BUILD=1 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-build/3rdparty/zlib -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/3rdparty/zlib -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/3rdparty/libpng -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-build/3rdparty/libjpeg-turbo -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/3rdparty/libjpeg-turbo/src -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgcodecs/include -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-build/modules/imgcodecs -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/core/include -I/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgproc/include -isystem /home/tri/devel/emscripten-opencv-linker-crash/opencv-build -DNDEBUG -c -MD -MT modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o -MF modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o.d /home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgcodecs/src/grfmt_jpeg.cpp -o modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o
1.  <eof> parser at end of file
2.  Code generation
3.  Running pass 'Function Pass Manager' on module '/home/tri/devel/emscripten-opencv-linker-crash/opencv-4.10.0/modules/imgcodecs/src/grfmt_jpeg.cpp'.
4.  Running pass 'WebAssembly Instruction Selection' on function '@_ZN2cv11JpegEncoder5writeERKNS_3MatERKNSt3__26vectorIiNS4_9allocatorIiEEEE'
 #0 0x00005929925128d8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x2ecf8d8)
 #1 0x000059299250fd0e llvm::sys::RunSignalHandlers() (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x2eccd0e)
 #2 0x0000592992511b2f llvm::sys::CleanupOnSignal(unsigned long) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x2eceb2f)
 #3 0x00005929924758d9 CrashRecoverySignalHandler(int) (.llvm.10295579019845466845) CrashRecoveryContext.cpp:0:0
 #4 0x0000792af91a2320 (/lib/x86_64-linux-gnu/libc.so.6+0x45320)
 #5 0x0000592993781279 llvm::SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(llvm::BasicBlock const*) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x413e279)
 #6 0x0000592993780693 llvm::SelectionDAGBuilder::visit(llvm::Instruction const&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x413d693)
 #7 0x00005929938348e5 llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void, true>, false, true>, llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void, true>, false, true>, bool&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x41f18e5)
 #8 0x0000592993834076 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x41f1076)
 #9 0x0000592993830fba llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x41edfba)
#10 0x0000592991a4d0f8 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x240a0f8)
#11 0x0000592991fcc45b llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x298945b)
#12 0x0000592991fd6813 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x2993813)
#13 0x0000592991fcd530 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x298a530)
#14 0x0000592992d906b0 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::__2::unique_ptr<llvm::raw_pwrite_stream, std::__2::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x374d6b0)
#15 0x0000592992da9bfd clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x3766bfd)
#16 0x000059299422bf79 clang::ParseAST(clang::Sema&, bool, bool) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x4be8f79)
#17 0x000059299324dd81 clang::FrontendAction::Execute() (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x3c0ad81)
#18 0x00005929931a8e70 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x3b65e70)
#19 0x0000592993345967 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x3d02967)
#20 0x0000592991203418 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x1bc0418)
#21 0x00005929912000f3 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#22 0x0000592993004239 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__2::optional<llvm::StringRef>>, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>*, bool*) const::$_0>(long) Job.cpp:0:0
#23 0x0000592992475668 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x2e32668)
#24 0x0000592993003ca4 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__2::optional<llvm::StringRef>>, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>*, bool*) const (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x39c0ca4)
#25 0x0000592992fc00b0 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x397d0b0)
#26 0x0000592992fe040b clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__2::pair<int, clang::driver::Command const*>>&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x399d40b)
#27 0x00005929911ff2aa clang_main(int, char**, llvm::ToolContext const&) (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x1bbc2aa)
#28 0x000059299120f27a main (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x1bcc27a)
#29 0x0000792af91871ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#30 0x0000792af918728b call_init ./csu/../csu/libc-start.c:128:20
#31 0x0000792af918728b __libc_start_main ./csu/../csu/libc-start.c:347:5
#32 0x0000592991172c6a _start (/home/tri/.local/opt/emsdk/upstream/bin/clang+++0x1b2fc6a)

Full link command and output with -v appended: (does not reach linker)

aheejin commented 3 months ago

Thanks for the report! I'm investigating. In case you have used previous versions of Emscripten, do you have any idea in which version this error started to appear?

mologie commented 3 months ago

Thanks for looking into it! I have not used older versions of Emscripten/LLVM with OpenCV unfortunately. However, sumant85 commented in the linked LLVM issue that 3.1.54 introduced the issue and indeed, OpenCV compiles with 3.1.53.