#!/usr/bin/env python2 # # Test-case for global symbol contamination bug. # # When libGL dlopens the llvmpipe-based swrast driver, it sets RTLD_GLOBAL # to maintain compatability with third party software (see bug #79469). # Since LLVM depends on libedit, and swrast depends on LLVM, libedit's symbols # are loaded as RTLD_GLOBAL. # # Libedit is a BSD-licensed reimplementation of GNU readline containing a # partial readline compatability layer, and hence shares some symbol names # with the original readline library. Python's readline module uses symbols # which are not implemented by libedit, causing some symbols to be resolved to # libedit and others to be resolved to readline, resulting in program # misbehaviour (e.g. not cleaning up the terminal correctly after termination) # and semi-random segfaults. As a specific example, rl_initialize is resolved # to libedit.so if libgl is loaded and libreadline.so if it is not. # # This is a variant of bug #93103. # Tested on Debian Sid with mesa commit 62a819184141133478cfdcfa76b62d5bb7e14fd5 import os from ctypes import * # Force use of swrast driver os.environ['LIBGL_ALWAYS_SOFTWARE'] = "1" # Get an X Display handle to feed libGL print "Loading libX11" libX11 = cdll.LoadLibrary("libX11.so.6") libX11.XOpenDisplay.argtypes = [c_char_p] libX11.XOpenDisplay.restype = c_void_p print "Calling XOpenDisplay(None)" dpy = libX11.XOpenDisplay(None) # Trigger libGL to dlopen the driver by calling glXQueryVersion print "Loading libGL" libGL = cdll.LoadLibrary("libGL.so.1") libGL.glXQueryVersion.argtypes = [c_void_p, POINTER(c_bool), POINTER(c_bool)] libGL.glXQueryVersion.restype = c_bool print "Calling glXQueryVersion(dpy, None, None)" success = libGL.glXQueryVersion(dpy, None, None) # Trigger python to load the readline library print "Loading readline module" import readline # Attempt to use the readline-enhanced raw_input function raw_input("Input: ")