[Lldb-commits] [lldb] r202243 - Suppress python readline module under Linux to fix a seg fault.

Todd Fiala tfiala at google.com
Tue Feb 25 23:39:20 PST 2014


Author: tfiala
Date: Wed Feb 26 01:39:20 2014
New Revision: 202243

URL: http://llvm.org/viewvc/llvm-project?rev=202243&view=rev
Log:
Suppress python readline module under Linux to fix a seg fault.

Bug fix for pr18841:
http://llvm.org/bugs/show_bug.cgi?id=18841

This change creates a stub Python readline.so module that does almost
nothing. Its whole purpose is to prevent Python from loading the real
module, something it does during the embedded Python interpreter's
initialization sequence (and way before lldb ever requests it within
embedded_interpreter.py).

On Ubuntu 12.04 and 13.10 x86_64, and in the Python 2.7.6 tree, the
stock Python readline module links against the GNU readline library.
This appears to be the case on all Pythons except where __APPLE__ is
defined. LLDB now requires linking against the libedit library.
Something about having both libedit.so and libreadline.so linked into
the same process space is causing the Python readline.so to trigger a
NULL memory access. I have put in a separate patch to python.org.

This suppression of embedded interpreter readline support can be
removed if at least any one of the following happens:

1. The stock python distribution accepts a patch similar to what I
submitted to Python 2.7.6's Modules/readline.c file.

2. The stock python distribution implements Modules/readline.c in
terms of libedit's readline compatibility mode (i.e. essentially
compiles it the way __APPLE__ compiles that module) under Linux.

3. a clean-room implementation of the python readline module is
implemented against libedit (either readline compatibility mode or
native libedit). This could be implemented within the readline.cpp
file that this change introduces. It cannot be a fork of python's
readline.c module due to llvm licensing.

The net effect of this change on Linux is that the embedded python's
readline support will not exist.

Added:
    lldb/trunk/scripts/Makefile
    lldb/trunk/scripts/Python/Makefile
    lldb/trunk/scripts/Python/modules/
    lldb/trunk/scripts/Python/modules/CMakeLists.txt
    lldb/trunk/scripts/Python/modules/Makefile
    lldb/trunk/scripts/Python/modules/readline/
    lldb/trunk/scripts/Python/modules/readline/CMakeLists.txt
    lldb/trunk/scripts/Python/modules/readline/Makefile
    lldb/trunk/scripts/Python/modules/readline/readline.cpp
Modified:
    lldb/trunk/Makefile
    lldb/trunk/scripts/CMakeLists.txt
    lldb/trunk/source/Interpreter/embedded_interpreter.py

Modified: lldb/trunk/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/Makefile?rev=202243&r1=202242&r2=202243&view=diff
==============================================================================
--- lldb/trunk/Makefile (original)
+++ lldb/trunk/Makefile Wed Feb 26 01:39:20 2014
@@ -14,7 +14,7 @@ ifndef LLDB_LEVEL
 
 IS_TOP_LEVEL := 1
 LLDB_LEVEL := .
-DIRS := include source lib tools
+DIRS := include scripts source lib tools
 
 PARALLEL_DIRS :=
 endif

Modified: lldb/trunk/scripts/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/CMakeLists.txt?rev=202243&r1=202242&r2=202243&view=diff
==============================================================================
--- lldb/trunk/scripts/CMakeLists.txt (original)
+++ lldb/trunk/scripts/CMakeLists.txt Wed Feb 26 01:39:20 2014
@@ -18,3 +18,6 @@ ADD_CUSTOM_TARGET(swig_wrapper ALL echo
 if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
   install(SCRIPT lldb_python_module.cmake -DCMAKE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\" -DCMAKE_BUILD_DIR=\"${CMAKE_BUILD_DIR}\")
 endif()
+
+# build Python modules
+add_subdirectory(Python/modules)

Added: lldb/trunk/scripts/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Makefile?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Makefile (added)
+++ lldb/trunk/scripts/Makefile Wed Feb 26 01:39:20 2014
@@ -0,0 +1,15 @@
+##===- scripts/Makefile ------------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ..
+include $(LLDB_LEVEL)/../../Makefile.config
+
+DIRS := Python
+
+include $(LLDB_LEVEL)/Makefile

Added: lldb/trunk/scripts/Python/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/Makefile?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/Makefile (added)
+++ lldb/trunk/scripts/Python/Makefile Wed Feb 26 01:39:20 2014
@@ -0,0 +1,15 @@
+##===- scripts/Python/Makefile------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../..
+include $(LLDB_LEVEL)/../../Makefile.config
+
+DIRS := modules
+
+include $(LLDB_LEVEL)/Makefile

Added: lldb/trunk/scripts/Python/modules/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modules/CMakeLists.txt?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/modules/CMakeLists.txt (added)
+++ lldb/trunk/scripts/Python/modules/CMakeLists.txt Wed Feb 26 01:39:20 2014
@@ -0,0 +1,4 @@
+# build the Python readline suppression module only on Linux
+if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+   add_subdirectory(readline)
+endif()

Added: lldb/trunk/scripts/Python/modules/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modules/Makefile?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/modules/Makefile (added)
+++ lldb/trunk/scripts/Python/modules/Makefile Wed Feb 26 01:39:20 2014
@@ -0,0 +1,20 @@
+##===- scripts/Python/modules/Makefile ---------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../..
+include $(LLDB_LEVEL)/../../Makefile.config
+
+DIRS:=
+
+# only build the readline suppression module on Linux
+ifeq ($(HOST_OS), Linux)
+DIRS += readline
+endif
+
+include $(LLDB_LEVEL)/Makefile

Added: lldb/trunk/scripts/Python/modules/readline/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modules/readline/CMakeLists.txt?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/modules/readline/CMakeLists.txt (added)
+++ lldb/trunk/scripts/Python/modules/readline/CMakeLists.txt Wed Feb 26 01:39:20 2014
@@ -0,0 +1,19 @@
+# FIXME: if a non-standard version of python is requested, the cmake macro
+# below will need Python_ADDITIONAL_VERSIONS set in order to find it.
+include(FindPythonInterp)
+SET(PYTHON_DIRECTORY python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
+
+# Build the readline python module
+include_directories(${PYTHON_INCLUDE_DIR})
+add_library(readline SHARED readline.cpp)
+
+# FIXME: the LIBRARY_OUTPUT_PATH seems to be ignored - this is not a
+# functional issue for the build dir, though, since the shared lib dir
+# for the build is in the python shared library load path, and thus
+# python finds it when loading the python readline module.
+set_target_properties(readline PROPERTIES
+                               PREFIX ""
+                               LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib/${PYTHON_DIRECTORY})
+
+# Install the readline module.
+install(TARGETS readline LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${PYTHON_DIRECTORY})

Added: lldb/trunk/scripts/Python/modules/readline/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modules/readline/Makefile?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/modules/readline/Makefile (added)
+++ lldb/trunk/scripts/Python/modules/readline/Makefile Wed Feb 26 01:39:20 2014
@@ -0,0 +1,99 @@
+##===- scripts/Python/modules/readline/Makefile ------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+# Skip this entire Makefile if python is disabled.
+ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS)))
+
+LEVEL := ../../../../../..
+LLDB_LEVEL := ../../../..
+
+LIBRARYNAME = readline
+
+NO_BUILD_ARCHIVE = 1
+LINK_LIBS_IN_SHARED = 1
+SHARED_LIBRARY = 1
+LOADABLE_MODULE = 1
+
+PYTHON_INCLUDES = $(shell python-config --includes)
+
+# Include all archives in the shared lib
+USEDLIBS :=
+
+include $(LLDB_LEVEL)/../../Makefile.config
+
+LINK_COMPONENTS :=
+
+include $(LEVEL)/Makefile.common
+
+# include python headers
+CXXFLAGS += $(PYTHON_INCLUDES)
+
+ifeq ($(HOST_OS),Darwin)
+    LLVMLibsOptions += -Wl,-all_load
+    # set dylib internal version number to llvmCore submission number
+    ifdef LLDB_SUBMIT_VERSION
+        LLVMLibsOptions += -Wl,-current_version \
+                           -Wl,$(LLDB_SUBMIT_VERSION).$(LLDB_SUBMIT_SUBVERSION) \
+                           -Wl,-compatibility_version -Wl,1
+    endif
+    # extra options to override libtool defaults
+    LVMLibsOptions += -F/System/Library/Frameworks -F/System/Library/PrivateFrameworks
+    LLVMLibsOptions += -framework Foundation -framework CoreFoundation
+    LLVMLibsOptions += -framework CoreServices -framework Carbon -framework Security
+    LLVMLibsOptions += -framework DebugSymbols $(PYTHON_BUILD_FLAGS) -lobjc
+    # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
+    DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
+    ifneq ($(DARWIN_VERS),8)
+       LLVMLibsOptions  += -Wl,-install_name \
+                           -Wl,"@executable_path/../lib/$(LIBRARYNAME)$(SHLIBEXT)"
+    endif
+endif
+
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD))
+    # Include everything from the .a's into the shared library.
+    ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
+                       -Wl,--no-whole-archive
+    # Link in libedit
+    # LLVMLibsOptions += -ledit
+    LLVMLibsOptions += -Wl,--soname,$(LIBRARYNAME)$(SHLIBEXT)
+endif
+
+ifeq ($(HOST_OS),FreeBSD)
+    # Include everything from the .a's into the shared library.
+    ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
+                       -Wl,--no-whole-archive
+    # Allow unresolved symbols.
+    LLVMLibsOptions += -Wl,--allow-shlib-undefined
+    # Link in libedit
+    # LLVMLibsOptions += -L/usr/local/lib -ledit
+endif
+
+# FIXME: dynamically construct the version from `python -V`
+PYTHON_VERSION:=2.7
+LLDB_PYTHON_MODULE_REL_DIR:=python$(PYTHON_VERSION)/site-packages
+LLDB_PYTHON_MODULE_DIR:=$(LibDir)/$(LLDB_PYTHON_MODULE_REL_DIR)
+
+# Target to move readline module from shared lib build location to
+# local python module directory.
+all-local:: $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)
+
+$(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT): $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT)
+	$(Echo) Staging $(BuildMode) $(LIBRARYNAME)$(SHLIBEXT) to $(LLDB_PYTHON_MODULE_DIR)
+	$(Verb) $(MKDIR) "$(LLDB_PYTHON_MODULE_DIR)"
+	$(Verb) $(ProgInstall) $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT) $(LLDB_PYTHON_MODULE_DIR)
+
+# Target to move the shared library from the build python lib dir to
+# the install python lib dir.
+install-local:: $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)
+	$(Echo) Installing $(BuildMode) $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT) to $(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)
+	$(Verb) $(MKDIR) "$(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)"
+	$(Verb) $(ProgInstall) "$(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)" "$(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)"
+	$(Verb) $(RM) "$(DESTDIR)$(prefix)/lib/$(LIBRARYNAME)$(SHLIBEXT)"
+
+endif  # if !defined(LLDB_DISABLE_PYTHON)

Added: lldb/trunk/scripts/Python/modules/readline/readline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modules/readline/readline.cpp?rev=202243&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/modules/readline/readline.cpp (added)
+++ lldb/trunk/scripts/Python/modules/readline/readline.cpp Wed Feb 26 01:39:20 2014
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "Python.h"
+
+// Python readline module intentionally built to not implement the
+// readline module interface. This is meant to work around llvm
+// pr18841 to avoid seg faults in the stock Python readline.so linked
+// against GNU readline.
+
+static struct PyMethodDef moduleMethods[] =
+{
+    {0, 0}
+};
+
+PyDoc_STRVAR(
+    moduleDocumentation,
+    "Stub module meant to effectively disable readline support.");
+
+PyMODINIT_FUNC
+initreadline(void)
+{
+    Py_InitModule4(
+        "readline",
+        moduleMethods,
+        moduleDocumentation,
+        static_cast<PyObject *>(NULL),
+        PYTHON_API_VERSION);
+}

Modified: lldb/trunk/source/Interpreter/embedded_interpreter.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/embedded_interpreter.py?rev=202243&r1=202242&r2=202243&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/embedded_interpreter.py (original)
+++ lldb/trunk/source/Interpreter/embedded_interpreter.py Wed Feb 26 01:39:20 2014
@@ -9,6 +9,10 @@ try:
     import rlcompleter
 except ImportError:
     have_readline = False
+except AttributeError:
+    # This exception gets hit by the rlcompleter when Linux is using
+    # the readline suppression import.
+    have_readline = False
 else:
     have_readline = True
     if 'libedit' in readline.__doc__:





More information about the lldb-commits mailing list