tatyana-krasnukha created this revision.
tatyana-krasnukha added reviewers: JDevlieghere, zturner.
tatyana-krasnukha added a project: LLDB.
Herald added subscribers: lldb-commits, abidh.

Running `dotest.py` with a path to tests directory results in:

  terminate called after throwing an instance of 'std::logic_error'
                what():  basic_string::_M_construct null not valid
  Aborted

for some tests. For example, when a test executes command "script import 
relative_path.py" the exception happens in 
ScriptInterpreterPython::LoadScriptingModule at the line

  std::string directory = target_file.GetDirectory().GetCString();

because GetCString returns nullptr.

The reason of such behavior is that llvm::RealFileSystem returns cached current 
working directory value until it will be updated with 
setCurrentWorkingDirectory. So, we permanently have cwd == directory of the 
first test, FileSystem::Resolve doesn't find the file and just returns the 
original value.

P.S. What about FileSpec::GetDirectory and FileSpec::GetFileName those never 
return nullptr? There is a lot of code that doesn't check result on nullptr 
(look at llvm.org/pr37054, for example). I made a patch where these functions 
return empty strings instead of nullptr, but some tests fail as they expect the 
result is None. Other API users can be broken also.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D55827

Files:
  include/lldb/API/SBHostOS.h
  include/lldb/Host/FileSystem.h
  packages/Python/lldbsuite/test/lldbtest.py
  scripts/interface/SBHostOS.i
  source/API/SBHostOS.cpp
  source/Host/common/FileSystem.cpp


Index: source/Host/common/FileSystem.cpp
===================================================================
--- source/Host/common/FileSystem.cpp
+++ source/Host/common/FileSystem.cpp
@@ -247,6 +247,11 @@
   file_spec.SetIsResolved(true);
 }
 
+bool FileSystem::SetCurrentWorkingDirectory(const llvm::Twine &cwd) {
+  std::error_code error = m_fs->setCurrentWorkingDirectory(cwd);
+  return !error;
+}
+
 std::shared_ptr<DataBufferLLVM>
 FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,
                              uint64_t offset) {
Index: source/API/SBHostOS.cpp
===================================================================
--- source/API/SBHostOS.cpp
+++ source/API/SBHostOS.cpp
@@ -94,6 +94,10 @@
   return sb_fspec;
 }
 
+bool SBHostOS::SetCurrentWorkingDirectory(const char *cwd) {
+  return cwd ? FileSystem::Instance().SetCurrentWorkingDirectory(cwd) : false;
+}
+
 lldb::thread_t SBHostOS::ThreadCreate(const char *name,
                                       lldb::thread_func_t thread_function,
                                       void *thread_arg, SBError *error_ptr) {
Index: scripts/interface/SBHostOS.i
===================================================================
--- scripts/interface/SBHostOS.i
+++ scripts/interface/SBHostOS.i
@@ -24,6 +24,9 @@
 
     static lldb::SBFileSpec
     GetUserHomeDirectory ();
+        
+    static bool
+    SetCurrentWorkingDirectory(const char *cwd);
 
     static void
     ThreadCreated (const char *name);
Index: packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- packages/Python/lldbsuite/test/lldbtest.py
+++ packages/Python/lldbsuite/test/lldbtest.py
@@ -552,6 +552,9 @@
                 print("Change dir to:", full_dir, file=sys.stderr)
             os.chdir(full_dir)
 
+        if not lldb.SBHostOS.SetCurrentWorkingDirectory(full_dir):
+            raise Exception("Failed to re-write cached cwd value.")
+
         # Set platform context.
         cls.platformContext = lldbplatformutil.createPlatformContext()
 
Index: include/lldb/Host/FileSystem.h
===================================================================
--- include/lldb/Host/FileSystem.h
+++ include/lldb/Host/FileSystem.h
@@ -130,6 +130,11 @@
   void Resolve(FileSpec &file_spec);
   /// @}
 
+  /// Set current working directory.
+  /// @{
+  bool SetCurrentWorkingDirectory(const llvm::Twine &cwd);
+  /// @}
+
   //// Create memory buffer from path.
   /// @{
   std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const llvm::Twine &path,
Index: include/lldb/API/SBHostOS.h
===================================================================
--- include/lldb/API/SBHostOS.h
+++ include/lldb/API/SBHostOS.h
@@ -25,6 +25,8 @@
 
   static lldb::SBFileSpec GetUserHomeDirectory();
 
+  static bool SetCurrentWorkingDirectory(const char *cwd);
+
   static void ThreadCreated(const char *name);
 
   static lldb::thread_t ThreadCreate(const char *name,


Index: source/Host/common/FileSystem.cpp
===================================================================
--- source/Host/common/FileSystem.cpp
+++ source/Host/common/FileSystem.cpp
@@ -247,6 +247,11 @@
   file_spec.SetIsResolved(true);
 }
 
+bool FileSystem::SetCurrentWorkingDirectory(const llvm::Twine &cwd) {
+  std::error_code error = m_fs->setCurrentWorkingDirectory(cwd);
+  return !error;
+}
+
 std::shared_ptr<DataBufferLLVM>
 FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,
                              uint64_t offset) {
Index: source/API/SBHostOS.cpp
===================================================================
--- source/API/SBHostOS.cpp
+++ source/API/SBHostOS.cpp
@@ -94,6 +94,10 @@
   return sb_fspec;
 }
 
+bool SBHostOS::SetCurrentWorkingDirectory(const char *cwd) {
+  return cwd ? FileSystem::Instance().SetCurrentWorkingDirectory(cwd) : false;
+}
+
 lldb::thread_t SBHostOS::ThreadCreate(const char *name,
                                       lldb::thread_func_t thread_function,
                                       void *thread_arg, SBError *error_ptr) {
Index: scripts/interface/SBHostOS.i
===================================================================
--- scripts/interface/SBHostOS.i
+++ scripts/interface/SBHostOS.i
@@ -24,6 +24,9 @@
 
     static lldb::SBFileSpec
     GetUserHomeDirectory ();
+        
+    static bool
+    SetCurrentWorkingDirectory(const char *cwd);
 
     static void
     ThreadCreated (const char *name);
Index: packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- packages/Python/lldbsuite/test/lldbtest.py
+++ packages/Python/lldbsuite/test/lldbtest.py
@@ -552,6 +552,9 @@
                 print("Change dir to:", full_dir, file=sys.stderr)
             os.chdir(full_dir)
 
+        if not lldb.SBHostOS.SetCurrentWorkingDirectory(full_dir):
+            raise Exception("Failed to re-write cached cwd value.")
+
         # Set platform context.
         cls.platformContext = lldbplatformutil.createPlatformContext()
 
Index: include/lldb/Host/FileSystem.h
===================================================================
--- include/lldb/Host/FileSystem.h
+++ include/lldb/Host/FileSystem.h
@@ -130,6 +130,11 @@
   void Resolve(FileSpec &file_spec);
   /// @}
 
+  /// Set current working directory.
+  /// @{
+  bool SetCurrentWorkingDirectory(const llvm::Twine &cwd);
+  /// @}
+
   //// Create memory buffer from path.
   /// @{
   std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const llvm::Twine &path,
Index: include/lldb/API/SBHostOS.h
===================================================================
--- include/lldb/API/SBHostOS.h
+++ include/lldb/API/SBHostOS.h
@@ -25,6 +25,8 @@
 
   static lldb::SBFileSpec GetUserHomeDirectory();
 
+  static bool SetCurrentWorkingDirectory(const char *cwd);
+
   static void ThreadCreated(const char *name);
 
   static lldb::thread_t ThreadCreate(const char *name,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to