[Python] Fix issue configuring sys.path during startup.
authorZachary Turner <zturner@google.com>
Thu, 9 Apr 2015 18:08:50 +0000 (18:08 +0000)
committerZachary Turner <zturner@google.com>
Thu, 9 Apr 2015 18:08:50 +0000 (18:08 +0000)
Previously, users on Windows had to manually specify PYTHONPATH
to point to the site-packages directory before running LLDB.
The reason for this was because sys.path was being initialized
with a path containing unescaped backslashes, causing escape
sequences to end up in the paths.

llvm-svn: 234516

lldb/include/lldb/Host/FileSpec.h
lldb/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/source/Host/common/FileSpec.cpp
lldb/source/Host/windows/HostInfoWindows.cpp
lldb/source/Interpreter/ScriptInterpreterPython.cpp

index a28eca4173bb0bc35f1be4f27cac1fec9ced6716..ceb2de4417d31497b02bee611d42f6559c05c1e3 100644 (file)
@@ -408,6 +408,17 @@ public:
     std::string
     GetPath (bool denormalize = true) const;
 
+    //------------------------------------------------------------------
+    /// Extract the full path to the file.
+    ///
+    /// Extract the directory and path into an llvm::SmallVectorImpl<>
+    ///
+    /// @return
+    ///     Returns a std::string with the directory and filename
+    ///     concatenated.
+    //------------------------------------------------------------------
+    void GetPath(llvm::SmallVectorImpl<char> &path, bool denormalize = true) const;
+
     //------------------------------------------------------------------
     /// Extract the extension of the file.
     ///
index e37b9cac6ccc493aa389683c6142b5d0080f3f96..28863a7600af055c0d121712d53246127599bbf6 100644 (file)
@@ -490,6 +490,13 @@ public:
         PyGILState_STATE         m_GILState;
        };
 protected:
+    enum class AddLocation
+    {
+        Beginning,
+        End
+    };
+
+    static void AddToSysPath(AddLocation location, std::string path);
 
     uint32_t
     IsExecutingPython () const
index a968dd93b61954691565140363986bbacdbe2731..a3f5e6d7c1019a856a37ab86ec0bf3a7d493b56c 100644 (file)
@@ -798,17 +798,23 @@ FileSpec::GetPath(char *path, size_t path_max_len, bool denormalize) const
 }
 
 std::string
-FileSpec::GetPath (bool denormalize) const
+FileSpec::GetPath(bool denormalize) const
 {
     llvm::SmallString<64> result;
+    GetPath(result, denormalize);
+    return std::string(result.begin(), result.end());
+}
+
+void
+FileSpec::GetPath(llvm::SmallVectorImpl<char> &path, bool denormalize) const
+{
     if (m_directory)
-        result.append(m_directory.GetCString());
+        path.append(m_directory.GetCString(), m_directory.GetCString() + m_directory.GetLength());
     if (m_filename)
-        llvm::sys::path::append(result, m_filename.GetCString());
-    if (denormalize && !result.empty())
-        DeNormalize(result, m_syntax);
-
-    return std::string(result.begin(), result.end());
+        llvm::sys::path::append(path, m_filename.GetCString());
+    Normalize(path, m_syntax);
+    if (denormalize && !path.empty())
+        DeNormalize(path, m_syntax);
 }
 
 ConstString
index b22920df2265438d3d8415259cd922fe514cdba7..b1c880f0ffecffc67cec7413a6848e91d5073fff 100644 (file)
@@ -13,7 +13,9 @@
 
 #include "lldb/Host/windows/HostInfoWindows.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Path.h"
 
 using namespace lldb_private;
 
@@ -107,11 +109,11 @@ HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec)
     FileSpec lldb_file_spec;
     if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
         return false;
-
-    char raw_path[PATH_MAX];
-    lldb_file_spec.AppendPathComponent("../lib/site-packages");
-    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
-
-    file_spec.GetDirectory().SetCString(raw_path);
+    llvm::SmallString<64> path;
+    lldb_file_spec.GetPath(path);
+    llvm::sys::path::remove_filename(path);
+    llvm::sys::path::append(path, "lib", "site-packages");
+    std::replace(path.begin(), path.end(), '\\', '/');
+    file_spec.GetDirectory().SetString(path.c_str());
     return true;
 }
index f8532e7e8c09075a1b416225f47f20aa1109d936..099cbaa0cedd60b47f22f60250bbc8fbc450493e 100644 (file)
@@ -3044,36 +3044,17 @@ ScriptInterpreterPython::InitializePrivate ()
     // Update the path python uses to search for modules to include the current directory.
 
     PyRun_SimpleString ("import sys");
-    PyRun_SimpleString ("sys.path.append ('.')");
-
-    // Find the module that owns this code and use that path we get to
-    // set the sys.path appropriately.
+    AddToSysPath(AddLocation::End, ".");
 
     FileSpec file_spec;
-    char python_dir_path[PATH_MAX];
+    // Don't denormalize paths when calling file_spec.GetPath().  On platforms that use
+    // a backslash as the path separator, this will result in executing python code containing
+    // paths with unescaped backslashes.  But Python also accepts forward slashes, so to make
+    // life easier we just use that.
     if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
-    {
-        std::string python_path("sys.path.insert(0,\"");
-        size_t orig_len = python_path.length();
-        if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
-        {
-            python_path.append (python_dir_path);
-            python_path.append ("\")");
-            PyRun_SimpleString (python_path.c_str());
-            python_path.resize (orig_len);
-        }
-
-        if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
-        {
-            if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
-            {
-                python_path.append (python_dir_path);
-                python_path.append ("\")");
-                PyRun_SimpleString (python_path.c_str());
-                python_path.resize (orig_len);
-            }
-        }
-    }
+        AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
+    if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
+        AddToSysPath(AddLocation::Beginning, file_spec.GetPath(false));
 
     PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line");
 
@@ -3089,6 +3070,28 @@ ScriptInterpreterPython::InitializePrivate ()
     stdin_tty_state.Restore();
 }
 
+void
+ScriptInterpreterPython::AddToSysPath(AddLocation location, std::string path)
+{
+    std::string path_copy;
+
+    std::string statement;
+    if (location == AddLocation::Beginning)
+    {
+        statement.assign("sys.path.insert(0,\"");
+        statement.append (path);
+        statement.append ("\")");
+    }
+    else
+    {
+        statement.assign("sys.path.append(\"");
+        statement.append(path);
+        statement.append("\")");
+    }
+    PyRun_SimpleString (statement.c_str());
+}
+
+
 //void
 //ScriptInterpreterPython::Terminate ()
 //{