Bug 1181085 - SDL 1.2 programs crash with certain libGL implementations
Summary: SDL 1.2 programs crash with certain libGL implementations
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: libX11
Version: 21
Hardware: x86_64
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Adam Jackson
QA Contact: Fedora Extras Quality Assurance
URL: https://bugzilla.libsdl.org/show_bug....
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-01-12 11:04 UTC by uakudm
Modified: 2015-12-02 17:03 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-12-02 07:16:10 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description uakudm 2015-01-12 11:04:53 UTC
Description of problem:

Some libGL implementations call XInitThreads() on dlopen. For example, the
latest nVidia proprietary implementation does it, probably because it needs to
use threads for performance. This causes applications that use SDL 1.2 to crash. 

From XInitThreads(3):

	The XInitThreads function initializes Xlib support for concurrent threads.
	This function must be the first Xlib function a multi-threaded program
	calls, and it must complete before any other Xlib call is made.

From <https://wiki.libsdl.org/SDL_GL_LoadLibrary>:

	This should be done after initializing the video driver, but before creating
	any OpenGL windows. If no OpenGL library is loaded, the default library will
	be loaded upon creation of the first OpenGL window.

But SDL_VideoInit() calls XOpenDisplay() and nVidia libGL implementation calls
XInitThreads() on dlopen:

	(gdb) break XInitThreads
	Function "XInitThreads" not defined.
	Make breakpoint pending on future shared library load? (y or [n]) y
	Breakpoint 1 (XInitThreads) pending.
	(gdb) run
	Starting program: /mnt/data/home/woky/src/xonotic/darkplaces/darkplaces-sdl 
	[Thread debugging using libthread_db enabled]
	Using host libthread_db library "/lib64/libthread_db.so.1".
	Game is DarkPlaces-Quake using base gamedir id1
	gamename for server filtering: DarkPlaces-Quake
	DarkPlaces-Quake Linux 18:50:26 Jan 11 2015 - debug
	Current nice level is below the soft limit - cannot use niceness
	Playing shareware version.
	Skeletal animation uses SSE code path
	DPSOFTRAST available (SSE2 instructions detected)
	Failed to init SDL joystick subsystem: 
	couldn't exec quake.rc
	couldn't exec default.cfg
	execing config.cfg
	couldn't exec autoexec.cfg
	Client using an automatically assigned port
	Client opened a socket on address 0.0.0.0:0
	Linked against SDL version 1.2.15
	Using SDL library version 1.2.15

	Breakpoint 1, XInitThreads () at locking.c:573
	573	{
	(gdb) thread apply all bt

	Thread 1 (Thread 0x7ffff7fcc700 (LWP 8884)):
	#0  XInitThreads () at locking.c:573
	#1  0x00007fffea173136 in ?? () from /usr/lib64/nvidia/libGL.so.1
	#2  0x00007fffea1956cd in ?? () from /usr/lib64/nvidia/libGL.so.1
	#3  0x00007fffea173b9d in ?? () from /usr/lib64/nvidia/libGL.so.1
	#4  0x00007ffff7deaf0d in call_init (l=0x2923d80, argc=argc@entry=1, argv=argv@entry=0x7fffffffe038, env=env@entry=0x7fffffffe048) at dl-init.c:62
	#5  0x00007ffff7deb05b in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=<optimized out>) at dl-init.c:34
	#6  _dl_init (main_map=main_map@entry=0x2923d80, argc=1, argv=0x7fffffffe038, env=0x7fffffffe048) at dl-init.c:124
	#7  0x00007ffff7defa51 in dl_open_worker (a=a@entry=0x7fffffffcdc8) at dl-open.c:566
	#8  0x00007ffff7deadf4 in _dl_catch_error (objname=objname@entry=0x7fffffffcdb8, errstring=errstring@entry=0x7fffffffcdc0, mallocedp=mallocedp@entry=0x7fffffffcdb7, 
			operate=operate@entry=0x7ffff7def590 <dl_open_worker>, args=args@entry=0x7fffffffcdc8) at dl-error.c:187
	#9  0x00007ffff7deeee3 in _dl_open (file=0x7ffff701a7b6 "libGL.so.1", mode=-2147483390, caller_dlopen=0x7ffff6ff968b <X11_GL_LoadLibrary+59>, nsid=-2, argc=<optimized out>, 
			argv=<optimized out>, env=0x7fffffffe048) at dl-open.c:650
	#10 0x00007ffff725c039 in dlopen_doit (a=a@entry=0x7fffffffcfe0) at dlopen.c:66
	#11 0x00007ffff7deadf4 in _dl_catch_error (objname=0x292d090, errstring=0x292d098, mallocedp=0x292d088, operate=0x7ffff725bfe0 <dlopen_doit>, args=0x7fffffffcfe0) at dl-error.c:187
	#12 0x00007ffff725c69d in _dlerror_run (operate=operate@entry=0x7ffff725bfe0 <dlopen_doit>, args=args@entry=0x7fffffffcfe0) at dlerror.c:163
	#13 0x00007ffff725c0d1 in __dlopen (file=file@entry=0x7ffff701a7b6 "libGL.so.1", mode=mode@entry=258) at dlopen.c:87
	#14 0x00007ffff6ff968b in X11_GL_LoadLibrary (this=0x2975760, path=0x7ffff701a7b6 "libGL.so.1") at src/video/x11/SDL_x11gl.c:506
	#15 0x0000000000409616 in VID_InitModeGL (mode=0x7fffffffd4e0) at ../../../vid_sdl.c:2461
	#16 0x0000000000409cdf in VID_InitMode (mode=0x7fffffffd4e0) at ../../../vid_sdl.c:2758
	#17 0x00000000006fdbfd in VID_Mode (fullscreen=1, width=640, height=480, bpp=32, refreshrate=60, stereobuffer=0, samples=1) at ../../../vid_shared.c:1857
	#18 0x00000000006fe4e5 in VID_Start () at ../../../vid_shared.c:2022
	#19 0x000000000057400c in Host_StartVideo () at ../../../host.c:1088
	#20 0x000000000047ad16 in SCR_BeginLoadingPlaque (startup=true) at ../../../cl_screen.c:761
	#21 0x000000000057454b in Host_Init () at ../../../host.c:1324
	#22 0x0000000000572d99 in Host_Main () at ../../../host.c:679
	#23 0x000000000040444e in main (argc=1, argv=0x7fffffffe038) at ../../../sys_sdl.c:223

So if a program is written according to the SDL docs and runs with nVidia libGL
implementation, the XInitThreads() is called too late from libGL and bad things
happen[1]. This problem doesn't occur with SDL 2.0.3 because it calls
XInitThreads() during video initialization.

I experience this problem for about 3-6 months now so it's probably caused by
change in nVidia proprietary libGL implementation. However, it breaks some
packages already present in Fedora which use SDL 1.2. Xonotic is affected for
example. The crash happens during closing of the display where libX11 tries to
release mutex which is NULL (or some random memory, see [1]).

SDL 1.2 should be patched to explicitly call XInitThreads in SDL_VideoInit() to
avoid such crashes under arbitrary libGL implementations.

I wouldn't be able to figure this out without the insight of Xonotic core team
wizards, especially divVerent. Thank you.

[1] http://forums.fedoraforum.org/showthread.php?t=302471

Version-Release number of selected component (if applicable): SDL-1.2.15-17.fc21.x86_64

Steps to Reproduce:
1. sudo dnf install xonotic
2. xonotic-sdl
3. # from game UI, either exit the game or change the resolution

Actual results: Game segfaults.

Expected results: Game doesn't segfault.

Comment 1 Petr Pisar 2015-01-12 12:15:21 UTC
I forwarded the request to the upstream <https://bugzilla.libsdl.org/show_bug.cgi?id=2843>.

I think this is not specific to SDL. Any X11 toolkit can suffer from this. Also I'm not sure what performance penalty is initializing X11 threads in a single-thread applications. I hope SDL upsream will have some comments.

Comment 2 uakudm 2015-01-22 02:31:42 UTC
So I've just noticed that this bug is probably not really related to SDL because it affects other non-SDL applications in Fedora. Nomacs for instance has been segfaulting for me about same time as Xonotic linked to SDL-1.2 (on start, I just stopped using it). Today I finally decided to check stacktrace and found that it segfaults on a similar path to Xonotic:

  gdb nomacs
  ...
  (gdb) run
  ...
  Program received signal SIGSEGV, Segmentation fault.
  0x00007ffff44f8830 in pthread_mutex_lock () from /lib64/libpthread.so.0
  (gdb) bt
  #0  0x00007ffff44f8830 in pthread_mutex_lock () from /lib64/libpthread.so.0
  #1  0x00007ffff1b0c43a in XrmQGetResource (db=0x8ea230, names=names@entry=0x7fffffffabf0, classes=classes@entry=0x7fffffffac00, pType=pType@entry=0x7fffffffabec, 
      pValue=pValue@entry=0x7fffffffac10) at Xrm.c:2549
  #2  0x00007ffff1ae8826 in XGetDefault (dpy=dpy@entry=0x921710, prog=prog@entry=0x7ffff245f63d "Xcursor", name=name@entry=0x7ffff245f6cf "core") at GetDflt.c:231
  #3  0x00007ffff245c748 in _XcursorGetDisplayInfo (dpy=0x921710) at display.c:151
  #4  0x00007ffff245c789 in XcursorSupportsARGB (dpy=<optimized out>) at display.c:297
  #5  0x00007ffff245f121 in XcursorNoticeCreateBitmap (dpy=0x0, pid=140737488333808, width=4294945792, height=384) at xlib.c:132
  #6  0x00007ffff1ae2d41 in XCreatePixmap (dpy=dpy@entry=0x921710, d=656, width=width@entry=32, height=height@entry=32, depth=depth@entry=1) at CrPixmap.c:61
  #7  0x00007ffff1ae1b91 in XCreateBitmapFromData (display=0x921710, d=<optimized out>, 
      data=0xac3760 '\377' <repeats 37 times>, "\373\377\377\377\375\377\377\377\377\377\377\377\376\377\377\377\347\377\377\377\367\377\377\377\377\377\377\377\377\337\377\377\377\337\377\377\367\377\377\377\356\377\377\377\337\373\377\377\375\277\377\377\373\337\377\377\357\367\377\377\177\376", '\377' <repeats 29 times>, width=32, height=32) at CrBFData.c:56
  #8  0x00007ffff739db6f in QX11PixmapData::createBitmapFromImage(QImage const&) () from /lib64/libQtGui.so.4
  #9  0x00007ffff739dc63 in QX11PixmapData::bitmapFromImage(QImage const&) () from /lib64/libQtGui.so.4
  #10 0x00007ffff739e232 in QX11PixmapData::fromImage(QImage const&, QFlags<Qt::ImageConversionFlag>) () from /lib64/libQtGui.so.4
  #11 0x00007ffff739cfb3 in qt_toX11Pixmap(QImage const&) () from /lib64/libQtGui.so.4
  #12 0x00007ffff739d9c7 in qt_toX11Pixmap(QPixmap const&) () from /lib64/libQtGui.so.4
  #13 0x00007ffff733a745 in QCursorData::setBitmap(QBitmap const&, QBitmap const&, int, int) () from /lib64/libQtGui.so.4
  #14 0x00007ffff72c722c in QCursor::QCursor(QPixmap const&, int, int) () from /lib64/libQtGui.so.4
  #15 0x0000000000502692 in nmc::DkEditableRect::DkEditableRect(QRectF, QWidget*, QFlags<Qt::WindowType>) ()
  #16 0x0000000000502c07 in nmc::DkCropWidget::DkCropWidget(QRectF, QWidget*, QFlags<Qt::WindowType>) ()
  #17 0x00000000005182e4 in nmc::DkControlWidget::DkControlWidget(nmc::DkViewPort*, QFlags<Qt::WindowType>) ()
  #18 0x000000000051a3b9 in nmc::DkViewPort::DkViewPort(QWidget*, QFlags<Qt::WindowType>) ()
  #19 0x000000000056fe6b in nmc::DkNoMacsIpl::DkNoMacsIpl(QWidget*, QFlags<Qt::WindowType>) ()
  #20 0x000000000048dd80 in main ()
  (gdb) frame 1
  #1  0x00007ffff1b0c43a in XrmQGetResource (db=0x8ea230, names=names@entry=0x7fffffffabf0, classes=classes@entry=0x7fffffffac00, pType=pType@entry=0x7fffffffabec, 
      pValue=pValue@entry=0x7fffffffac10) at Xrm.c:2549
  2549		_XLockMutex(&db->linfo);

So fixing this in SDL-1.2 is not really fix. Is Fedora concerned about issues with nVidia proprietary driver or should I just move all this to nVidia forums?

Comment 3 Petr Pisar 2015-01-22 08:45:46 UTC
I don't know much about OpenGL in X11. There are various paths (direct, indirect etc.) how to access OpenGL implementation in the card, so I'm not sure where to reassign this issue. I even don't know whether X11 OpenGL implementation is allowed to use threads. Maybe it's just an undefined behaviour.

I think Fedora is not concerned much about proprietary drivers, but it's still good to have the possibility to use them. You should raise your question to nVidia support too.

I will reassign this to libX11 hoping its maintainer will know more.

Comment 4 uakudm 2015-02-01 10:29:37 UTC
Whoops. Found the problem. Some time ago, out of curiosity, I put this into my profile.

export __GL_THREADED_OPTIMIZATIONS=1

Removing it or setting it to 0 fixes the problem for me. Sorry for the noise.

Comment 5 Fedora End Of Life 2015-11-04 13:51:17 UTC
This message is a reminder that Fedora 21 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 21. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '21'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 21 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 6 Fedora End Of Life 2015-12-02 07:16:13 UTC
Fedora 21 changed to end-of-life (EOL) status on 2015-12-01. Fedora 21 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.