opencv / opencv

Open Source Computer Vision Library
https://opencv.org
Apache License 2.0
76.67k stars 55.65k forks source link

highgui: wayland: opencv_test_highgui fails #25550

Closed Kumataro closed 1 month ago

Kumataro commented 1 month ago

System Information

OpenCV version: 4.x ( bc95f27e56d89e486c25e76db0573b610bee6496 ) Operating System / Platform: Ubuntu 24.04 Compiler & compiler version: GCC 13.2

--   GUI:                           Wayland
--     Wayland:                     (Experimental) YES
--       Wayland Client:            YES (ver 1.22.0)
--       Wayland Cursor:            YES (ver 1.22.0)
--       Wayland Protocols:         YES (ver 1.34)
--       Xkbcommon:                 YES (ver 1.6.0)
--       Wayland EGL(Option):       YES (ver 18.1.0)

Detailed description

opencv_test_highgui with wayland fails.

kmtr@kmtr-VMware-Virtual-Platform:~/work/build4-main$ ./bin/opencv_test_highgui CTEST_FULL_OUTPUT OpenCV version: 4.9.0-dev OpenCV VCS version: 4.9.0-423-gbc95f27e56 Build type: Debug Compiler: /usr/bin/c++ (ver 13.2.0) [ INFO:0@0.004] global registry_parallel.impl.hpp:96 ParallelBackendRegistry core(parallel): Enabled backends(3, sorted by priority): ONETBB(1000); TBB(990); OPENMP(980) Parallel framework: pthreads (nthreads=8) CPU features: SSE SSE2 SSE3 SSE4.1 SSE4.2 FP16 AVX AVX2 AVX512-SKX? Intel(R) IPP version: ippIP AVX2 (l9) 2021.11.0 (-) Feb 1 2024 Intel(R) IPP features code: 0x8000 [ INFO:0@0.005] global ocl.cpp:1185 haveOpenCL Initialize OpenCL runtime... [ INFO:0@0.005] global ocl.cpp:1191 haveOpenCL OpenCL: found 0 platforms OpenCL is disabled TEST: Skip tests with tags: 'mem_6gb', 'verylong', 'debug_verylong' [==========] Running 4 tests from 1 test case. [----------] Global test environment set-up. [----------] 4 tests from Highgui_GUI [ RUN ] Highgui_GUI.regression [ INFO:0@0.006] global registry.impl.hpp:114 UIBackendRegistry UI: Enabled backends(3, sorted by priority): GTK(1000); GTK3(990); GTK2(980) + BUILTIN(Wayland) [] DEBUG: handle_toplevel_configure: maximized=0 fullscreen=0 resizing=0 focused=0 size=[0 x 0] [] DEBUG: handle_toplevel_configure: maximized=0 fullscreen=0 resizing=0 focused=1 size=[800 x 624] /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:53: Failure //////////////// (D) Expected equality of these values: rc.size() Which is: -1x-1 img.size() Which is: 800x600 Google Test trace: /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:80: 0 Exception message: OpenCV(4.9.0-dev) /home/kmtr/work/opencv4/modules/core/include/opencv2/core/mat.inl.hpp:910: error: (-215:Assertion failed) (unsigned)(i1 DataType<_Tp>::channels) < (unsigned)(size.p[1] channels()) in function 'at'

/home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:49: Failure /////////////////(A) Expected: imshow(nm, img) doesn't throw an exception. Actual: it throws. Google Test trace: /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:80: 1 : : : [ FAILED ] Highgui_GUI.regression (8729 ms) [ RUN ] Highgui_GUI.trackbar_unsafe [ WARN:0@8.778] global window.cpp:701 createTrackbar UI/Trackbar(trackbar@trackbar_test_window): Using 'value' pointer is unsafe and deprecated. Use NULL as value pointer. To fetch trackbar value setup callback. /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:154: Failure //////////////// (E) Expected equality of these values: (int)1 Which is: 1 createTrackbar(trackbar_name, window_name, &value, 100, Foo, &callback_count) Which is: 0 /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:155: Failure ////////////////////////// (B) Expected equality of these values: value Which is: 50 getTrackbarPos(trackbar_name, window_name) Which is: 0 /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:160: Failure ////////////////////// (C) Expected equality of these values: callback_count_base + 1 Which is: 1 callback_count Which is: 0 /home/kmtr/work/opencv4/modules/highgui/test/test_gui.cpp:161: Failure /////////////////////////////// (C) Expected equality of these values: 90 value Which is: 50 [ FAILED ] Highgui_GUI.trackbar_unsafe (44 ms) : : [ RUN ] Highgui_GUI.currentUIFramework UI framework: "WAYLAND" [ OK ] Highgui_GUI.currentUIFramework (0 ms) [----------] 4 tests from Highgui_GUI (8793 ms total)

[----------] Global test environment tear-down [==========] 4 tests from 1 test case ran. (8793 ms total) [ PASSED ] 1 test. [ FAILED ] 3 tests, listed below: [ FAILED ] Highgui_GUI.regression [ FAILED ] Highgui_GUI.trackbar_unsafe [ FAILED ] Highgui_GUI.trackbar

3 FAILED TESTS kmtr@kmtr-VMware-Virtual-Platform:~/work/build4-main$



### Steps to reproduce

build opencv and run ` ./bin/opencv_test_highgui`

### Issue submission checklist

- [X] I report the issue, it's not a question
- [X] I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- [X] I updated to the latest OpenCV version and the issue is still there
- [X] There is reproducer code and related data files (videos, images, onnx, etc)
asmorkalov commented 1 month ago

Tested manually with Kubuntu 24.04 and Wayland session. Works well for me.

asmorkalov commented 1 month ago

The only issue I see for now is incorrect handling of invalid display case (e.g. ssh session without gui login). It crashes with sigsegv, but not assert/exception:

[----------] 4 tests from Highgui_GUI
[ RUN      ] Highgui_GUI.regression
[ INFO:0@0.344] global registry.impl.hpp:114 UIBackendRegistry UI: Enabled backends(3, sorted by priority): GTK(1000); GTK3(990); GTK2(980) + BUILTIN(Wayland)
Exception message: OpenCV(4.9.0-dev) /home/vlad/Projects/opencv/modules/highgui/src/window_wayland.cpp:845: error: (-3:Internal error) Could not connect to display: No such file or directory in function 'init'

/home/vlad/Projects/opencv/modules/highgui/test/test_gui.cpp:73: Failure
Expected: destroyAllWindows() doesn't throw an exception.
  Actual: it throws.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f75bf0 in cv_wl_display::get_surface (this=0x0) at /home/vlad/Projects/opencv/modules/highgui/src/window_wayland.cpp:901
901         return wl_compositor_create_surface(compositor_);
(gdb) bt
#0  0x00007ffff7f75bf0 in cv_wl_display::get_surface (this=0x0) at /home/vlad/Projects/opencv/modules/highgui/src/window_wayland.cpp:901
#1  0x00007ffff7f7be17 in cv_wl_window::cv_wl_window (this=0x5555555ff800, display=std::shared_ptr<cv_wl_display> (empty) = {...}, title="", flags=1) at /home/vlad/Projects/opencv/modules/highgui/src/window_wayland.cpp:1757
#2  0x00007ffff7f96a8c in std::_Construct<cv_wl_window, std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> (__p=0x5555555ff800) at /usr/include/c++/13/bits/stl_construct.h:119
#3  0x00007ffff7f93e87 in std::allocator_traits<std::allocator<void> >::construct<cv_wl_window, std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> (__p=0x5555555ff800)
    at /usr/include/c++/13/bits/alloc_traits.h:661
#4  std::_Sp_counted_ptr_inplace<cv_wl_window, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> (
    this=0x5555555ff7f0, __a=...) at /usr/include/c++/13/bits/shared_ptr_base.h:604
#5  0x00007ffff7f913d2 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<cv_wl_window, std::allocator<void>, std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> (
    this=0x7fffffffd698, __p=@0x7fffffffd690: 0x0, __a=...) at /usr/include/c++/13/bits/shared_ptr_base.h:971
#6  0x00007ffff7f8d893 in std::__shared_ptr<cv_wl_window, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<void>, std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> (
    this=0x7fffffffd690, __tag=...) at /usr/include/c++/13/bits/shared_ptr_base.h:1712
#7  0x00007ffff7f89638 in std::shared_ptr<cv_wl_window>::shared_ptr<std::allocator<void>, std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> (this=0x7fffffffd690, __tag=...)
    at /usr/include/c++/13/bits/shared_ptr.h:464
#8  0x00007ffff7f85217 in std::make_shared<cv_wl_window, std::shared_ptr<cv_wl_display>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&> () at /usr/include/c++/13/bits/shared_ptr.h:1010
#9  0x00007ffff7f7f90b in cv_wl_core::create_window (this=0x555555621420, name="opencv_highgui_test_window", flags=1) at /home/vlad/Projects/opencv/modules/highgui/src/window_wayland.cpp:2329
#10 0x00007ffff7f7fbcb in cvNamedWindow (name=0x555555622d90 "opencv_highgui_test_window", flags=1) at /home/vlad/Projects/opencv/modules/highgui/src/window_wayland.cpp:2374
#11 0x00007ffff7f69509 in cv::namedWindow (winname="opencv_highgui_test_window", flags=1) at /home/vlad/Projects/opencv/modules/highgui/src/window.cpp:485
#12 0x0000555555562374 in opencv_test::(anonymous namespace)::Highgui_GUI_regression_Test::Body (this=0x555555622e60) at /home/vlad/Projects/opencv/modules/highgui/test/test_gui.cpp:74
#13 0x00005555555620c2 in opencv_test::(anonymous namespace)::Highgui_GUI_regression_Test::TestBody (this=0x555555622e60) at /home/vlad/Projects/opencv/modules/highgui/test/test_gui.cpp:67
#14 0x00005555555a2faa in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void> (object=0x555555622e60, method=&virtual testing::Test::TestBody(), location=0x5555555bf07b "the test body")
    at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:3919
#15 0x000055555559c9f4 in testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void> (object=0x555555622e60, method=&virtual testing::Test::TestBody(), location=0x5555555bf07b "the test body")
    at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:3955
#16 0x00005555555811fa in testing::Test::Run (this=0x555555622e60) at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:3993
#17 0x0000555555581a6d in testing::TestInfo::Run (this=0x5555555f1500) at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:4169
#18 0x000055555558221e in testing::TestCase::Run (this=0x5555555f1950) at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:4287
#19 0x000055555558ec83 in testing::internal::UnitTestImpl::RunAllTests (this=0x5555555f16b0) at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:6662
#20 0x00005555555a410d in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x5555555f16b0, 
    method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x55555558e9ba <testing::internal::UnitTestImpl::RunAllTests()>, location=0x5555555bf938 "auxiliary test code (environments or event listeners)")
    at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:3919
#21 0x000055555559dad3 in testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x5555555f16b0, 
    method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x55555558e9ba <testing::internal::UnitTestImpl::RunAllTests()>, location=0x5555555bf938 "auxiliary test code (environments or event listeners)")
    at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:3955
#22 0x000055555558d22e in testing::UnitTest::Run (this=0x5555555dda00 <testing::UnitTest::GetInstance()::instance>) at /home/vlad/Projects/opencv/modules/ts/src/ts_gtest.cpp:6271
#23 0x0000555555568589 in RUN_ALL_TESTS () at /home/vlad/Projects/opencv/modules/ts/include/opencv2/ts/ts_gtest.h:22229
#24 0x0000555555568791 in main (argc=1, argv=0x7fffffffe1a8) at /home/vlad/Projects/opencv/modules/highgui/test/test_main.cpp:10
Kumataro commented 1 month ago

Thank you for your test. I fixed it. Usually I login ssh session, but I also login GUI at same time too. So I have missed this phenomenon.

TEST(Highgui_GUI, regression)
#endif
{
    const std::string window_name("opencv_highgui_test_window");
    const cv::Size image_size(800, 600);

    EXPECT_NO_THROW(destroyAllWindows()); // A
    ASSERT_NO_THROW(namedWindow(window_name)); // B

Exception is happend at A. However it uses EXPECT_* macro so test will be continued. Next, B is called with no display connection status. Invalid status causes SEGV, but it is not good way.

I add CV_CheckTrue(); to check connection display. cv_wl_windows will not be created with nullptr display.

$ git diff -b 358699d2973371f9bf8bc1ab59045d517920dcd0
diff --git a/modules/highgui/src/window_wayland.cpp b/modules/highgui/src/window_wayland.cpp
index d21d1984ca..28c084794f 100644
--- a/modules/highgui/src/window_wayland.cpp
+++ b/modules/highgui/src/window_wayland.cpp
@@ -2326,6 +2326,7 @@ std::string const &cv_wl_core::get_window_name(void *handle) {
 }

 bool cv_wl_core::create_window(std::string const &name, int flags) {
+    CV_CheckTrue(display_ != nullptr, "Display is not connected.");
     auto window = std::make_shared<cv_wl_window>(display_, name, flags);
     auto result = windows_.insert(std::make_pair(name, window));
     handles_[window.get()] = window->get_title();