Skip to content

[lldb] Don't rely on ScriptInterpreterPythonImpl::Initialize in the unit tests #82096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2024

Conversation

JDevlieghere
Copy link
Member

@JDevlieghere JDevlieghere commented Feb 17, 2024

The unit tests only test the Python objects and don't actually use
anything from the LLDB module. That means that all the additional
complexity in ScriptInterpreterPythonImpl::Initialize is overkill.

By doing the initialization by hand, we avoid the annoying
ModuleNotFoundError.

Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'lldb'

The error is the result of us stubbing out the SWIG (specifically
PyInit__lldb) because we cannot link against libLLDB from the unit
tests.

The downside of doing the initialization manually is that we do lose a
bit of test coverage. For example, issue #70453 also manifested itself
in the unit tests.

…nittests

The unit tests only test the Python objects and don't actually use
anything from the LLDB module. That means that all the additional
complexity in ScriptInterpreterPythonImpl::Initialize is overkill.

By doing the initialization by hand, we avoid the annoying
ModuleNotFoundError.

  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  ModuleNotFoundError: No module named 'lldb'

The error is the result of us stubbing out the SWIG (specifically
`PyInit__lldb`) because we cannot link against libLLDB from the unit
tests.

The downside of doing the initialization manually is that we do lose a
bit of test coverage. For example, issue llvm#70453 also manifested itself
in the unit tests.
@JDevlieghere JDevlieghere changed the title [lldb] Don't rely on ScriptInterpreterPythonImpl::Initialize in the u… [lldb] Don't rely on ScriptInterpreterPythonImpl::Initialize in the unit tests Feb 17, 2024
@JDevlieghere JDevlieghere marked this pull request as ready for review February 17, 2024 07:07
@llvmbot llvmbot added the lldb label Feb 17, 2024
@llvmbot
Copy link
Member

llvmbot commented Feb 17, 2024

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

The unit tests only test the Python objects and don't actually use
anything from the LLDB module. That means that all the additional
complexity in ScriptInterpreterPythonImpl::Initialize is overkill.

By doing the initialization by hand, we avoid the annoying
ModuleNotFoundError.

Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'lldb'

The error is the result of us stubbing out the SWIG (specifically
PyInit__lldb) because we cannot link against libLLDB from the unit
tests.

The downside of doing the initialization manually is that we do lose a
bit of test coverage. For example, issue #70453 also manifested itself
in the unit tests.


Full diff: https://github.com/llvm/llvm-project/pull/82096.diff

1 Files Affected:

  • (modified) lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp (+5-21)
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
index 5f0cc4c23db7b2..23162436d42c94 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -9,43 +9,27 @@
 #include "gtest/gtest.h"
 
 #include "Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h"
-#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
-#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h"
 #include "Plugins/ScriptInterpreter/Python/lldb-python.h"
 
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostInfo.h"
-
 #include "PythonTestSuite.h"
 #include <optional>
 
-using namespace lldb_private;
-class TestScriptInterpreterPython : public ScriptInterpreterPythonImpl {
-public:
-  using ScriptInterpreterPythonImpl::Initialize;
-};
-
 void PythonTestSuite::SetUp() {
-  FileSystem::Initialize();
-  HostInfoBase::Initialize();
-  // ScriptInterpreterPython::Initialize() depends on HostInfo being
-  // initializedso it can compute the python directory etc.
-  TestScriptInterpreterPython::Initialize();
-
   // Although we don't care about concurrency for the purposes of running
   // this test suite, Python requires the GIL to be locked even for
   // deallocating memory, which can happen when you call Py_DECREF or
   // Py_INCREF.  So acquire the GIL for the entire duration of this
   // test suite.
+  Py_InitializeEx(0);
   m_gil_state = PyGILState_Ensure();
+  PyRun_SimpleString("import sys");
 }
 
 void PythonTestSuite::TearDown() {
   PyGILState_Release(m_gil_state);
 
-  TestScriptInterpreterPython::Terminate();
-  HostInfoBase::Terminate();
-  FileSystem::Terminate();
+  // We could call Py_FinalizeEx here, but initializing and finalizing Python is
+  // pretty slow, so just keep Python initialized across tests.
 }
 
 // The following functions are the Pythonic implementations of the required
@@ -219,7 +203,7 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommandObject(
 }
 
 bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallParsedCommandObject(
-    PyObject *implementor, lldb::DebuggerSP debugger, 
+    PyObject *implementor, lldb::DebuggerSP debugger,
     StructuredDataImpl &args_impl,
     lldb_private::CommandReturnObject &cmd_retobj,
     lldb::ExecutionContextRefSP exe_ctx_ref_sp) {

@bulbazord
Copy link
Member

The downside of doing the initialization manually is that we do lose a bit of test coverage. For example, issue #70453 also manifested itself in the unit tests.

I think this is an acceptable tradeoff. The unit tests are for testing LLDB's python internals, not for testing LLDB's python interface and integration.

@JDevlieghere JDevlieghere merged commit 5c96e71 into llvm:main Feb 18, 2024
@JDevlieghere JDevlieghere deleted the PythonTestSuiteInit branch February 18, 2024 04:55
@DavidSpickett
Copy link
Collaborator

This change has caused a failing test on Linux: https://lab.llvm.org/buildbot/#/builders/68/builds/69157

That's not the first build, because the bot was red for ages beforehand and I'm not going to check them all. I've bisected it on arm64 instead to confirm it and get a better traceback:

******************** TEST 'lldb-unit :: ScriptInterpreter/Python/./ScriptInterpreterPythonTests/32/39' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests-lldb-unit-831825-32-39.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=39 GTEST_SHARD_INDEX=32 /home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests
--

Note: This is test shard 33 of 39.
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PythonDataObjectsTest
[ RUN      ] PythonDataObjectsTest.TestPythonFile
/usr/lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/optional:477: _Tp &std::_Optional_base_impl<lldb_private::FileSystem, std::_Optional_base<lldb_private::FileSystem, false, false>>::_M_get() [_Tp = lldb_private::FileSystem, _Dp = std::_Optional_base<lldb_private::FileSystem, false, false>]: Assertion 'this->_M_is_engaged()' failed.
 #0 0x0000aaaac51c9630 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests+0xaf630)
 #1 0x0000aaaac51c792c llvm::sys::RunSignalHandlers() (/home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests+0xad92c)
 #2 0x0000aaaac51ca088 SignalHandler(int) (/home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests+0xb0088)
 #3 0x0000ffffac90c5c0 (linux-vdso.so.1+0x5c0)
 #4 0x0000ffffabba9d78 raise /build/glibc-RIFKjK/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x0000ffffabb96aac abort /build/glibc-RIFKjK/glibc-2.31/stdlib/abort.c:81:7
 #6 0x0000ffffabde95d8 std::__glibcxx_assert_fail(char const*, int, char const*, char const*) (/lib/aarch64-linux-gnu/libstdc++.so.6+0xd75d8)
 #7 0x0000aaaac51fa924 lldb_private::FileSystem::Instance() (/home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests+0xe0924)
 #8 0x0000aaaac5180b60 PythonDataObjectsTest_TestPythonFile_Test::TestBody() (/home/david.spickett/build-llvm-aarch64/tools/lldb/unittests/ScriptInterpreter/Python/./ScriptInterpreterPythonTests+0x66b60)

Seems like this Initialize had some side effects beyond Python itself?

@rupprecht
Copy link
Collaborator

This change has caused a failing test on Linux: https://lab.llvm.org/buildbot/#/builders/68/builds/69157

Fixed w/ 6757913

@DavidSpickett
Copy link
Collaborator

Thanks! Fixed the x86 bot and I confirmed it locally.

@JDevlieghere
Copy link
Member Author

Thank you!

JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Apr 17, 2024
…nit tests (llvm#82096)

The unit tests only test the Python objects and don't actually use
anything from the LLDB module. That means that all the additional
complexity in ScriptInterpreterPythonImpl::Initialize is overkill.

By doing the initialization by hand, we avoid the annoying
ModuleNotFoundError.

  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  ModuleNotFoundError: No module named 'lldb'

The error is the result of us stubbing out the SWIG (specifically
`PyInit__lldb`) because we cannot link against libLLDB from the unit
tests.

The downside of doing the initialization manually is that we do lose a
bit of test coverage. For example, issue llvm#70453 also manifested itself
in the unit tests.

(cherry picked from commit 5c96e71)
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request May 24, 2024
…nit tests (llvm#82096)

The unit tests only test the Python objects and don't actually use
anything from the LLDB module. That means that all the additional
complexity in ScriptInterpreterPythonImpl::Initialize is overkill.

By doing the initialization by hand, we avoid the annoying
ModuleNotFoundError.

  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  ModuleNotFoundError: No module named 'lldb'

The error is the result of us stubbing out the SWIG (specifically
`PyInit__lldb`) because we cannot link against libLLDB from the unit
tests.

The downside of doing the initialization manually is that we do lose a
bit of test coverage. For example, issue llvm#70453 also manifested itself
in the unit tests.

(cherry picked from commit 5c96e71)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants