如果没有连接HDMI设备,没有X的SDL2会显示“分段故障”

问题描述 投票:1回答:1

我想做一个非常简单的电视面板测试仪。有了这个answer about SDL2 without X,我就可以用Raspberry Pi Zero准备这种测试仪,并且效果很好。运行时,我只能在电视之间切换电缆,并且在经过测试的电视上,我的绿屏非常快。但是,当我运行程序而未在HDMI上连接任何设备时,出现Segmentation fault

这是代码:

#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的速度很慢-甚至是极简主义的版本,所以也要使用。

[编辑]

[C0的输出:

full version of sample app

这是我从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
c++ raspberry-pi sdl-2 hdmi
1个回答
1
投票

如@genpfault在评论中指出,SDL ver。 2.0.10解决了分段故障,当不存在HDMI设备时。因此,如果有人使用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 () hg clone ...,请确保在构建自己的版本之前切换到SDL2源的正确版本。

© www.soinside.com 2019 - 2024. All rights reserved.