-
Notifications
You must be signed in to change notification settings - Fork 58
Suppress llvm_shutdown for external-interpreter clients. #891
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
|
|
||
| #include <algorithm> | ||
| #include <csignal> | ||
| #include <cstdlib> | ||
|
|
||
| using ::testing::StartsWith; | ||
|
|
||
|
|
@@ -149,6 +150,74 @@ TYPED_TEST(CPPINTEROP_TEST_MODE, Interpreter_DeleteInterpreter) { | |
| EXPECT_EQ(I2, Cpp::GetInterpreter()) << "I2 is not active"; | ||
| } | ||
|
|
||
| TYPED_TEST(CPPINTEROP_TEST_MODE, Interpreter_StaticDtorsRunOnDelete) { | ||
| #ifdef EMSCRIPTEN | ||
| GTEST_SKIP() << "Test fails for Emscripten builds"; | ||
| #endif | ||
| if (TypeParam::isOutOfProcess) | ||
| GTEST_SKIP() << "Test fails for OOP JIT builds"; | ||
|
|
||
| auto* I = TestFixture::CreateInterpreter(); | ||
| ASSERT_NE(I, nullptr); | ||
|
|
||
| // Host-side flag the JIT writes to; survives the interpreter deletion | ||
| // that frees JIT memory. Reset explicitly for --gtest_repeat. | ||
| static int HostFlag; | ||
| HostFlag = 0; | ||
| std::string Inject = "extern \"C\" void* dtor_sink = (void*)" + | ||
| std::to_string(reinterpret_cast<uintptr_t>(&HostFlag)) + | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "std::to_string" is directly included [misc-include-cleaner] std::to_string(reinterpret_cast<uintptr_t>(&HostFlag)) +
^
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "uintptr_t" is directly included [misc-include-cleaner] std::to_string(reinterpret_cast<uintptr_t>(&HostFlag)) +
^ |
||
| ";"; | ||
| Cpp::Declare(Inject.c_str(), I); | ||
| Cpp::Declare(R"( | ||
| struct DtorNotify { ~DtorNotify() { *static_cast<int*>(dtor_sink) = 1; } }; | ||
| )", | ||
| I); | ||
| Cpp::Process("static DtorNotify notify;"); | ||
|
|
||
| EXPECT_EQ(HostFlag, 0); | ||
| Cpp::DeleteInterpreter(I); | ||
| EXPECT_EQ(HostFlag, 1) << "JIT static dtor did not run on DeleteInterpreter"; | ||
| } | ||
|
|
||
| // Mirrors clang/unittests/Interpreter/InterpreterTest.cpp's | ||
| // ShutdownDoesNotMaterializeAgainstDestroyedGlobals at the CppInterOp | ||
| // wrapper level: two interpreters each register a static with a | ||
| // non-trivial dtor, then std::exit drives the C++ static-dtor phase. | ||
| // On LLVM 23+ our InterpreterShutdown calls llvm_shutdown which fires | ||
| // ~InterpreterInfo -> ~Interpreter -> JIT deinit; the deinit lookup | ||
| // skips lazy materialization (Platform::lookupResolvedInitSymbols, | ||
| // llvm/llvm-project#196874) and the process exits cleanly. | ||
| // | ||
| // Skipped on older LLVM: InterpreterShutdown's llvm_shutdown call is | ||
| // gated out (we leak instead of risking the JIT cleanUp crash), and | ||
| // driving the chain manually from the test deadlocks rather than | ||
| // crashing cleanly through the compat layer. The crash contract is | ||
| // pinned upstream by clang's | ||
| // ShutdownDoesNotMaterializeAgainstDestroyedGlobals test. | ||
| TYPED_TEST(CPPINTEROP_TEST_MODE, | ||
| Interpreter_ShutdownDoesNotMaterializeAgainstDestroyedGlobals) { | ||
| #ifdef EMSCRIPTEN | ||
| GTEST_SKIP() << "Test fails for Emscripten builds"; | ||
| #endif | ||
| if (TypeParam::isOutOfProcess) | ||
| GTEST_SKIP() << "Test fails for OOP JIT builds"; | ||
| #if LLVM_VERSION_MAJOR <= 22 | ||
| GTEST_SKIP() << "Requires LLVM 23+ (lookupResolvedInitSymbols)"; | ||
| #else | ||
| EXPECT_EXIT( | ||
| { | ||
| auto* I1 = TestFixture::CreateInterpreter(); | ||
| auto* I2 = TestFixture::CreateInterpreter(); | ||
| Cpp::ActivateInterpreter(I1); | ||
| Cpp::Process("struct S1 { S1() {} ~S1() {} }; static S1 s1;"); | ||
| Cpp::ActivateInterpreter(I2); | ||
| Cpp::Process("struct S2 { S2() {} ~S2() {} }; static S2 s2;"); | ||
| std::exit(0); | ||
| }, | ||
| ::testing::ExitedWithCode(0), ""); | ||
| #endif | ||
| } | ||
|
|
||
| TYPED_TEST(CPPINTEROP_TEST_MODE, Interpreter_ActivateInterpreter) { | ||
| #ifdef EMSCRIPTEN_STATIC_LIBRARY | ||
| GTEST_SKIP() << "Test fails for Emscipten static library build"; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]