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

Crash when closing secondary window with Vulkan renderer on Linux w/ Wayland #12053

Open
Clownacy opened this issue Jan 22, 2025 · 5 comments
Open
Labels
notourbug This bug is caused by an external component
Milestone

Comments

@Clownacy
Copy link
Contributor

Clownacy commented Jan 22, 2025

Description

My program crashes upon closing any window that isn't the main one. This problem did not occur when using SDL2, but has occurred with every version of SDL3 since v3.1.3. I held off on reporting this since I figured it would be fixed before the first stable release, but that was not the case.

I am running x86-64 Arch Linux, with an AMD APU and an Nvidia RTX 3050 Ti Mobile GPU. I am using the proprietary Nvidia driver. This crash occurs when using either SDL_RENDER_DRIVER=vulkan or SDL_RENDER_DRIVER=gpu (which internally uses Vulkan). The crash does not occur with the X11 backend, but it does with the Wayland backend.

Call Stack

Vulkan

#0  0x0000000000000000 in ?? ()
#1  0x00007fffe47f2e65 in ?? () from /usr/lib/libnvidia-glcore.so.565.77
#2  0x00007fffe4937eaf in ?? () from /usr/lib/libnvidia-glcore.so.565.77
#3  0x000055555560f521 in VULKAN_RenderPresent (renderer=0x5555559b8900) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/render/vulkan/SDL_render_vulkan.c:4197
#4  0x00005555555e0ae8 in SDL_RenderPresent_REAL (renderer=0x5555559b8900) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/render/SDL_render.c:5116
#5  0x000055555558f18c in SDL_RenderPresent (a=0x5555559b8900) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:780
#6  0x000055555557b171 in SDL_AppIterate (appstate=0x0) at /home/clownacy/git/clownmdemu-frontend/main.cpp:31
#7  0x0000555555757b80 in SDL_IterateMainCallbacks (pump_events=true) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/SDL_main_callbacks.c:130
#8  0x000055555572cbfe in GenericIterateMainCallbacks () at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/generic/SDL_sysmain_callbacks.c:51
#9  0x000055555572cce8 in SDL_EnterAppMainCallbacks_REAL (argc=1, argv=0x7fffffffe3c8, appinit=0x55555557b083 <SDL_AppInit(void**, int, char**)>, appiter=0x55555557b129 <SDL_AppIterate(void*)>, 
    appevent=0x55555557b178 <SDL_AppEvent(void*, SDL_Event*)>, appquit=0x55555557b1c2 <SDL_AppQuit(void*, SDL_AppResult)>)
    at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/generic/SDL_sysmain_callbacks.c:62
#10 0x000055555558a54b in SDL_EnterAppMainCallbacks (a=1, b=0x7fffffffe3c8, c=0x55555557b083 <SDL_AppInit(void**, int, char**)>, d=0x55555557b129 <SDL_AppIterate(void*)>, 
    e=0x55555557b178 <SDL_AppEvent(void*, SDL_Event*)>, f=0x55555557b1c2 <SDL_AppQuit(void*, SDL_AppResult)>) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:207
#11 0x000055555557b055 in SDL_main (argc=1, argv=0x7fffffffe3c8) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/include/SDL3/SDL_main_impl.h:59
#12 0x00005555555cfe90 in SDL_RunApp_REAL (argc=1, argv=0x7fffffffe3c8, mainFunction=0x55555557b019 <SDL_main(int, char**)>, reserved=0x0)
    at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/SDL_runapp.c:40
#13 0x0000555555582a6f in SDL_RunApp_DEFAULT (a=1, b=0x7fffffffe3c8, c=0x55555557b019 <SDL_main(int, char**)>, d=0x0) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:804
#14 0x000055555558f5c0 in SDL_RunApp (a=1, b=0x7fffffffe3c8, c=0x55555557b019 <SDL_main(int, char**)>, d=0x0) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:804
#15 0x000055555557b080 in main (argc=1, argv=0x7fffffffe3c8) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/include/SDL3/SDL_main_impl.h:137

GPU

#0  0x0000000000000000 in ?? ()
#1  0x00007fffe47f2e65 in ?? () from /usr/lib/libnvidia-glcore.so.565.77
#2  0x00007fffe4937eaf in ?? () from /usr/lib/libnvidia-glcore.so.565.77
#3  0x0000555555727c85 in VULKAN_Submit (commandBuffer=0x555555d62820) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c:10497
#4  0x00005555555b21f2 in SDL_SubmitGPUCommandBuffer_REAL (command_buffer=0x555555d62820) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/gpu/SDL_gpu.c:2815
#5  0x00005555555e5a08 in GPU_RenderPresent (renderer=0x5555559d1470) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/render/gpu/SDL_render_gpu.c:982
#6  0x00005555555e0ae8 in SDL_RenderPresent_REAL (renderer=0x5555559d1470) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/render/SDL_render.c:5116
#7  0x000055555558f18c in SDL_RenderPresent (a=0x5555559d1470) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:780
#8  0x000055555557b171 in SDL_AppIterate (appstate=0x0) at /home/clownacy/git/clownmdemu-frontend/main.cpp:31
#9  0x0000555555757b80 in SDL_IterateMainCallbacks (pump_events=true) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/SDL_main_callbacks.c:130
#10 0x000055555572cbfe in GenericIterateMainCallbacks () at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/generic/SDL_sysmain_callbacks.c:51
#11 0x000055555572cce8 in SDL_EnterAppMainCallbacks_REAL (argc=1, argv=0x7fffffffe3c8, appinit=0x55555557b083 <SDL_AppInit(void**, int, char**)>, appiter=0x55555557b129 <SDL_AppIterate(void*)>, 
    appevent=0x55555557b178 <SDL_AppEvent(void*, SDL_Event*)>, appquit=0x55555557b1c2 <SDL_AppQuit(void*, SDL_AppResult)>)
    at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/generic/SDL_sysmain_callbacks.c:62
#12 0x000055555558a54b in SDL_EnterAppMainCallbacks (a=1, b=0x7fffffffe3c8, c=0x55555557b083 <SDL_AppInit(void**, int, char**)>, d=0x55555557b129 <SDL_AppIterate(void*)>, 
    e=0x55555557b178 <SDL_AppEvent(void*, SDL_Event*)>, f=0x55555557b1c2 <SDL_AppQuit(void*, SDL_AppResult)>) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:207
#13 0x000055555557b055 in SDL_main (argc=1, argv=0x7fffffffe3c8) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/include/SDL3/SDL_main_impl.h:59
#14 0x00005555555cfe90 in SDL_RunApp_REAL (argc=1, argv=0x7fffffffe3c8, mainFunction=0x55555557b019 <SDL_main(int, char**)>, reserved=0x0)
    at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/main/SDL_runapp.c:40
#15 0x0000555555582a6f in SDL_RunApp_DEFAULT (a=1, b=0x7fffffffe3c8, c=0x55555557b019 <SDL_main(int, char**)>, d=0x0) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:804
#16 0x000055555558f5c0 in SDL_RunApp (a=1, b=0x7fffffffe3c8, c=0x55555557b019 <SDL_main(int, char**)>, d=0x0) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/src/dynapi/SDL_dynapi_procs.h:804
#17 0x000055555557b080 in main (argc=1, argv=0x7fffffffe3c8) at /home/clownacy/git/clownmdemu-frontend/libraries/SDL/include/SDL3/SDL_main_impl.h:137

Minimum Reproducible Example

#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>
#include <SDL3/SDL.h>

static SDL_Window *window1;
static SDL_Renderer *renderer1;

static SDL_Window *window2;
static SDL_Renderer *renderer2;

SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv)
{
	if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD))
		return SDL_APP_FAILURE;

	if (!SDL_CreateWindowAndRenderer("window 1", 300, 300, SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE, &window1, &renderer1))
		return SDL_APP_FAILURE;

	if (!SDL_CreateWindowAndRenderer("window 2", 200, 200, SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE, &window2, &renderer2))
		return SDL_APP_FAILURE;

	return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppIterate(void *appstate)
{
	SDL_RenderClear(renderer2);
	SDL_RenderPresent(renderer2);

	SDL_RenderClear(renderer1);
	SDL_RenderPresent(renderer1);

	return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
	switch (event->type)
	{
		case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
		case SDL_EVENT_QUIT:
			SDL_DestroyRenderer(renderer2);
			SDL_DestroyWindow(window2);
			break;
	}

	return SDL_APP_CONTINUE;
}

void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
	SDL_DestroyRenderer(renderer1);
	SDL_DestroyWindow(window1);

	SDL_Quit();
}
@slouken
Copy link
Collaborator

slouken commented Jan 22, 2025

Can you git bisect where this starts?

SDL2 did not have a Vulkan renderer, so it would make sense that it didn't happen there.

@slouken slouken added this to the 3.x milestone Jan 22, 2025
@Clownacy Clownacy changed the title Crash when closing secondary window with Vulkan renderer on Linux Crash when closing secondary window with Vulkan renderer on Linux w/ Wayland Jan 22, 2025
@Clownacy
Copy link
Contributor Author

The crashes for both SDL_Renderer backends go all the way back to the commits which introduced them (cab2011 and 2e7d5bb).

While bisecting, I noticed that this crash does not occur in the X11 backend; it only happens on the Wayland backend.

@maia-s
Copy link
Contributor

maia-s commented Jan 22, 2025

I don't think this is an SDL bug. You destroy renderer2 in AppEvent, and then that destroyed renderer is later used in AppIterate.

Does it still crash if you set renderer2 to NULL after destroying it in AppEvent (and window2 too), and check for NULL before using it in AppIterate?

@Clownacy
Copy link
Contributor Author

Even with a minimal reproducible example that avoids that (and works on older versions of SDL3), the problem still occurs.

#include <stdlib.h>

#include <SDL3/SDL.h>

static SDL_Window *window1;
static SDL_Renderer *renderer1;

static SDL_Window *window2;
static SDL_Renderer *renderer2;

int main(int argc, char **argv)
{
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD);

	SDL_CreateWindowAndRenderer("window 1", 300, 300, SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE, &window1, &renderer1);

	SDL_CreateWindowAndRenderer("window 2", 200, 200, SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE, &window2, &renderer2);

	int quit = 0;
	while (!quit)
	{
		SDL_Event event;
		if (SDL_WaitEvent(&event))
		{
			switch (event.type)
			{
				case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
				case SDL_EVENT_QUIT:
					if (window2 != NULL)
					{
						SDL_DestroyRenderer(renderer2);
						SDL_DestroyWindow(window2);
						window2 = NULL;
					}
					else
					{
						quit = 1;
					}
					break;
			}
		}

		if (window2 != NULL)
		{
			SDL_RenderClear(renderer2);
			SDL_RenderPresent(renderer2);
		}

		SDL_RenderClear(renderer1);
		SDL_RenderPresent(renderer1);
	}

	SDL_DestroyRenderer(renderer1);
	SDL_DestroyWindow(window1);

	SDL_Quit();

	return EXIT_SUCCESS;
}

@Kontrabant
Copy link
Contributor

Kontrabant commented Jan 22, 2025

This can be reproduced with the testmodal test app as well, by using any Vulkan renderer and simply closing the modal window.

This is almost certainly an Nvidia driver bug, given that the crash is happening several calls into their driver, and it's fine under Mesa (you can force the Mesa llvmpipe driver with VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json for testing).

e: The Vulkan validation layers don't show any problems either.

@slouken slouken added the notourbug This bug is caused by an external component label Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
notourbug This bug is caused by an external component
Projects
None yet
Development

No branches or pull requests

4 participants