Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault on Raspberry Pi 5 #57

Open
michaellass opened this issue Dec 2, 2023 · 3 comments
Open

Segfault on Raspberry Pi 5 #57

michaellass opened this issue Dec 2, 2023 · 3 comments

Comments

@michaellass
Copy link

Running vkmark on a Raspberry Pi 5 (up-to-date Raspberry Pi OS, wayfire on wayland as window manager) leads to a segmentation fault:

$ vkmark -d
Debug: WindowSystemLoader: Looking in /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark for window system plugins
Debug: WindowSystemLoader: Loading options from /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/xcb.so... ok
Debug: WindowSystemLoader: Loading options from /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/kms.so... ok
Debug: WindowSystemLoader: Loading options from /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/wayland.so... ok
Debug: WindowSystemLoader: Probing /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/xcb.so... succeeded with priority 127
Debug: WindowSystemLoader: Probing /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/kms.so... succeeded with priority 255
Debug: WindowSystemLoader: Probing /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/wayland.so... succeeded with priority 255
Debug: WindowSystemLoader: Selected window system plugin /home/bevan/vkmark/lib/aarch64-linux-gnu/vkmark/kms.so (best match)
Debug: KMSWindowSystemPlugin: Using legacy modesetting
Segmentation fault

Backtrace with gdb:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6c8f4e8 in (anonymous namespace)::get_connected_connector (
    drm_fd=3, resources=0x0) at ../src/ws/kms_window_system.cpp:86
(gdb) bt
#0  0x00007ffff6c8f4e8 in (anonymous namespace)::get_connected_connector (
    drm_fd=3, resources=0x0) at ../src/ws/kms_window_system.cpp:86
#1  0x00007ffff6c905c0 in KMSWindowSystem::KMSWindowSystem (
    this=0x5555556a47c0, drm_device="/dev/dri/card0")
    at ../src/ws/kms_window_system.cpp:341
#2  0x00007ffff6c8ca20 in std::make_unique<KMSWindowSystem, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&> ()
    at /usr/include/c++/12/bits/unique_ptr.h:1065
#3  0x00007ffff6c88fb4 in vkmark_window_system_create (options=...)
    at ../src/ws/kms_window_system_plugin.cpp:124
#4  0x00005555555fa98c in WindowSystemLoader::load_window_system (
    this=0x7fffffffeb28) at ../src/window_system_loader.cpp:110
#5  0x000055555555cd74 in main (argc=1, argv=0x7fffffffef78)
    at ../src/main.cpp:117

It turns out that resources passed to get_connected_connector is NULL. The crash can therefore be caught by the following change:

--- a/src/ws/kms_window_system.cpp
+++ b/src/ws/kms_window_system.cpp
@@ -83,6 +83,8 @@ ManagedResource<drmModeCrtcPtr> get_crtc_with_id(int drm_fd, uint32_t crtc_id)
 ManagedResource<drmModeConnectorPtr> get_connected_connector(
     int drm_fd, drmModeResPtr resources)
 {
+    if (!resources)
+       throw std::runtime_error{"Invalid DRM resource pointer"};
     for (int c = 0; c < resources->count_connectors; c++)
     {
         auto connector = get_connector_with_id(drm_fd, resources->connectors[c]);

The crash can be circumvented by using anything else but /dev/dri/card0 as kms-drm-device, i.e., any of the following will work:

$ vkmark --winsys-options kms-drm-device=/dev/dri/card1
$ vkmark --winsys-options kms-drm-device=/dev/dri/renderD128
$ vkmark --winsys-options kms-drm-device=foobar

Note the last variant where I pass a nonsensical device. It turns out, the crash also vanishes when removing the default in the source code as follow:

--- a/src/ws/kms_window_system_plugin.cpp
+++ b/src/ws/kms_window_system_plugin.cpp
@@ -40,7 +40,7 @@ std::string const atomic_opt{"kms-atomic"};
 std::string get_drm_device_option(Options const& options)
 {
     auto const& winsys_options = options.window_system_options;
-    std::string drm_device{"/dev/dri/card0"};
+    std::string drm_device{};
 
     for (auto const& opt : winsys_options)
     {

If I remember correctly, this issue was not present on a Raspberry Pi 4. However, other Vulkan apps, such as vkcube run without issues.

@michaellass
Copy link
Author

The reason why choosing a different kms-drm-device is that the kms winsys then fails and wayland is used instead. So apart from the uncaught null pointer dereference, the main problem here is that kms is chosen by default altough being in a wayland environment.

@afrantzis
Copy link
Contributor

@michaellass Thanks for the report. The branch at https://github.com/vkmark/vkmark/tree/improve-ws-selection should improve both the winsys selection logic and the crash. Let me know how it works for you.

@michaellass
Copy link
Author

@michaellass Thanks for the report. The branch at https://github.com/vkmark/vkmark/tree/improve-ws-selection should improve both the winsys selection logic and the crash. Let me know how it works for you.

That branch looks very good indeed! The defaults are chosen correctly and even when explicitly passing --winsys kms in Raspberry Pi's wayfire session, the error is handled properly.

I went further and tested the branch in different environments. I can still trigger a segfault on an x86_64 system running in text-only mode (i.e., only kms is available, no graphical environment running) when explicitly passing --winsys wayland:

(gdb) run --winsys wayland
Starting program: /home/bevan/vkmark/bin/vkmark --winsys wayland

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff70ac8a4 in pthread_mutex_lock () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff70ac8a4 in pthread_mutex_lock () from /usr/lib/libc.so.6
#1  0x00007ffff750891b in wl_display_flush () from /usr/lib/libwayland-client.so.0
#2  0x00007ffff6fa6a2c in operator()<wl_display*> (__closure=0x55555577fc50, d=0x0) at ../src/ws/wayland_native_system.cpp:215
#3  0x00007ffff6fa840c in std::__invoke_impl<void, WaylandNativeSystem::create_native_window()::<lambda(auto:1)>&, wl_display*&>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/13.2.1/bits/invoke.h:61
#4  0x00007ffff6fa8214 in std::__invoke_r<void, WaylandNativeSystem::create_native_window()::<lambda(auto:1)>&, wl_display*&>(struct {...} &) (__fn=...) at /usr/include/c++/13.2.1/bits/invoke.h:150
#5  0x00007ffff6fa7f89 in std::_Function_handler<void(wl_display*&), WaylandNativeSystem::create_native_window()::<lambda(auto:1)> >::_M_invoke(const std::_Any_data &, wl_display *&) (__functor=..., __args#0=@0x55555577fc48: 0x0)
    at /usr/include/c++/13.2.1/bits/std_function.h:290
#6  0x00007ffff6fb00b9 in std::function<void (wl_display*&)>::operator()(wl_display*&) const (this=0x55555577fc50, __args#0=@0x55555577fc48: 0x0) at /usr/include/c++/13.2.1/bits/std_function.h:591
#7  0x00007ffff6fae26b in ManagedResource<wl_display*>::~ManagedResource (this=0x55555577fc48, __in_chrg=<optimized out>) at ../src/managed_resource.h:50
#8  0x00007ffff6fa513b in WaylandNativeSystem::WaylandNativeSystem (this=0x55555577fc30, width=800, height=600) at ../src/ws/wayland_native_system.cpp:146
#9  0x00007ffff6fa38d0 in std::make_unique<WaylandNativeSystem, int const&, int const&> () at /usr/include/c++/13.2.1/bits/unique_ptr.h:1070
#10 0x00007ffff6fa37e9 in vkmark_window_system_create (options=...) at ../src/ws/wayland_window_system_plugin.cpp:68
#11 0x0000555555686167 in WindowSystemLoader::load_window_system (this=0x7fffffffdb00) at ../src/window_system_loader.cpp:110
#12 0x00005555555994f6 in main (argc=3, argv=0x7fffffffde78) at ../src/main.cpp:117

From the backtrace, I'm actually not sure if vkmark or wayland itself is to blame for this one. I wonder if you can reproduce this and if there is anything that vkmark could do to handle this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants