SDL2 без X показывает «Ошибка сегментации», если не подключено устройство HDMI - PullRequest
1 голос
/ 27 февраля 2020

Хочу сделать очень простой тестер ТВ панели. С этим ответом о SDL2 без X я смог подготовить такой тестер с Raspberry Pi Zero, и он работает очень хорошо. Во время работы я могу переключать только кабели между телевизорами, и у меня очень быстрый зеленый экран на проверенном телевизоре. Однако, когда я запускаю программу без подключения какого-либо устройства по HDMI, у меня Ошибка сегментации .

Это код:

#include <SDL.h>
#include <iostream>

int main( int argc, char** argv )
{

    if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
    {
        std::cerr << "SDL_Init(): " << SDL_GetError() << '\n';
        return EXIT_FAILURE;
    }

    SDL_Window* window = SDL_CreateWindow
        (
        "SDL2",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        1920, 1080,
        SDL_WINDOW_SHOWN
        );
    if( nullptr == window )
    {
        std::cerr << "SDL_CreateWindow(): " << SDL_GetError() << '\n';
        return EXIT_FAILURE;
    }

    SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );
    if( nullptr == renderer )
    {
        std::cerr << "SDL_CreateRenderer(): " << SDL_GetError() << '\n';
        return EXIT_FAILURE;
    }

    bool running = true;
    while( running )
    {
        SDL_Event ev;
        while( SDL_PollEvent( &ev ))
        {
            if( ev.type == SDL_QUIT )
            {
                running = false;
            }
        }

        SDL_SetRenderDrawColor( renderer, 0x00, 0xff, 0x00, SDL_ALPHA_OPAQUE );
        SDL_RenderClear( renderer );
        SDL_RenderPresent( renderer );
    }

    SDL_DestroyRenderer( renderer );
    SDL_DestroyWindow( window );
    SDL_Quit();
    return 0;
}

Это конец strace эта программа:

close(5)                                = 0
openat(AT_FDCWD, "/usr/share/drirc.d/00-mesa-defaults.conf", O_RDONLY|O_LARGEFILE) = 5
read(5, "<?xml version=\"1.0\" standalone=\""..., 4096) = 4096
getrandom("\x26\x27\xac\x36", 4, GRND_NONBLOCK) = 4
read(5, ">\n\n        <application name=\"Un"..., 4096) = 4096
read(5, "_glsl_abs_sqrt\" value=\"true\" />\n"..., 4096) = 4096
read(5, "ation>\n\n        <application nam"..., 4096) = 4096
read(5, "daptive_sync\" value=\"false\" />\n "..., 4096) = 4096
read(5, "ation>\n        <application name"..., 4096) = 4096
read(5, "executable=\"dota2\">\n            "..., 4096) = 1062
read(5, "", 4096)                       = 0
close(5)                                = 0
openat(AT_FDCWD, "/etc/drirc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/pi/.drirc", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
ioctl(4, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb98e0) = 0
fcntl64(4, F_DUPFD_CLOEXEC, 3)          = 5
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb9860) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb9860) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb9860) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb9860) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb9860) = 0
ioctl(5, DRM_IOCTL_GET_CAP, 0xbecb9860) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb9898) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb98a8) = 0
gettimeofday({tv_sec=1582731761, tv_usec=164921}, NULL) = 0
openat(AT_FDCWD, "/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 6
read(6, "0\n", 8192)                    = 2
close(6)                                = 0
openat(AT_FDCWD, "/proc/self/auxv", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 6
read(6, "\20\0\0\0\326\201\0\0", 8)     = 8
close(6)                                = 0
futex(0xb5f4e3d0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
ioctl(5, DRM_IOCTL_TEGRA_GET_SYNCPT_BASE or DRM_IOCTL_VC4_GET_TILING, 0xbecb9860) = -1 ENOENT (No such file or directory)
ioctl(3, DRM_IOCTL_GET_CAP, 0xbecb9910) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb8cf0) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb8cf0) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb8cf0) = 0
ioctl(5, DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE or DRM_IOCTL_EXYNOS_VIDI_CONNECTION or DRM_IOCTL_TEGRA_GET_SYNCPT or DRM_IOCTL_VC4_GET_PARAM or DRM_IOCTL_VIA_DMA_INIT, 0xbecb8cf0) = 0
ioctl(3, DRM_IOCTL_MODE_GETRESOURCES, 0xbecba340) = 0
ioctl(3, DRM_IOCTL_MODE_GETRESOURCES, 0xbecba340) = 0
ioctl(3, DRM_IOCTL_MODE_GETCONNECTOR, 0xbecba2f0) = 0
ioctl(3, DRM_IOCTL_MODE_GETCONNECTOR, 0xbecba2f0) = 0
ioctl(3, DRM_IOCTL_MODE_GETCONNECTOR, 0xbecba2f0) = 0
ioctl(3, DRM_IOCTL_MODE_GETCONNECTOR, 0xbecba2f0) = 0
close(5)                                = 0
close(4)                                = 0
munmap(0xb50af000, 17353000)            = 0
munmap(0xb14ea000, 115624)              = 0
munmap(0xb14cf000, 106672)              = 0
munmap(0xb14a5000, 168220)              = 0
munmap(0xb148d000, 94536)               = 0
munmap(0xb1476000, 90356)               = 0
close(3)                                = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x4} ---
+++ killed by SIGSEGV +++
Segmentation fault

А это config.txt hdmi_ и отображение связанной части:

framebuffer_width=1920
framebuffer_height=1080
hdmi_force_hotplug=1
hdmi_ignore_edid=0xa5000080
hdmi_edid_file=1
hdmi_ignore_edid_audio=1
hdmi_force_edid_3d=1
hdmi_ignore_cec_init=1
hdmi_ignore_cec=1
hdmi_pixel_encoding=2
hdmi_blanking=0
edid_content_type=0
hdmi_group=1
hdmi_mode=16
hdmi_force_mode=1
dtoverlay=vc4-kms-v3d

Как я могу решить эту проблему?

Есть ли что-то, что я могу использовать в качестве фиктивного выхода HDMI до того, как будет подключено первое устройство?

Поскольку я хочу сделать этот тестер устройством без автоматического запуска и потому, что он будет включен перед любым Выход HDMI будет подключен (так как загрузка rPi-Zero идет медленно - даже минимальная c версия).

[EDIT]

Выход из полная версия примера приложения :

Testing video drivers...
SDL_VIDEODRIVER available: x11 KMSDRM RPI dummy
SDL_VIDEODRIVER usable   : KMSDRM
SDL_VIDEODRIVER selected : KMSDRM
SDL_RENDER_DRIVER available: opengles2 opengles software
SDL_RENDER_DRIVER selected : opengles2

Вот что я получаю от gdb:

Starting program: /home/pi/hdmitester/minimal
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0xb6a8d450 (LWP 645)]

Thread 1 "minimal" received signal SIGSEGV, Segmentation fault.
KMSDRM_VideoQuit (_this=<optimized out>) at /usr/src/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c:665
665         if (dispdata->conn) {
(gdb) bt
#0  KMSDRM_VideoQuit (_this=<optimized out>) at /usr/src/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c:665
#1  0xb6f40174 in SDL_VideoQuit_REAL () at /usr/src/SDL/src/video/SDL_video.c:2869
#2  0xb6f40c38 in SDL_VideoQuit_REAL () at /usr/src/SDL/src/video/SDL_video.c:2853
#3  SDL_VideoInit_REAL (driver_name=<optimized out>) at /usr/src/SDL/src/video/SDL_video.c:533
#4  0xb6e9d63c in SDL_InitSubSystem_REAL (flags=62001) at /usr/src/SDL/src/SDL.c:206
#5  0x00010aac in main ()

1 Ответ

1 голос
/ 28 февраля 2020

Как отметил @genpfault в комментариях, SDL вер. 2.0.10 решено Ошибка сегментации при отсутствии устройства HDMI. Поэтому, если кто-то использует hg clone ... или git clone ..., убедитесь, что вы переключаетесь на правильную версию источников SDL2 перед сборкой собственной версии.

...