mib created this revision. mib added reviewers: JDevlieghere, bulbazord. mib added a project: LLDB. Herald added a project: All. mib requested review of this revision. Herald added a subscriber: lldb-commits.
This patch should fix an undeterministic error in TestStackCoreScriptedProcess. In order to test both the multithreading capability and shared library loading in Scripted Processes, the test would create multiple threads that would take the same variable as a reference. The first thread would alter the value and the second thread would monitor the value until it gets altered. This assumed a certain ordering regarding the `std::thread` spawning, however the ordering was not always guaranteed at runtime. To fix that, the test now makes use of a `std::condition_variable` shared between the each thread. On the former, it will notify the other thread when the variable gets initialized or updated and on the latter, it will wait until the variable it receives a new notification. This should fix the data racing issue while preserving the testing coverage. rdar://98678134 Signed-off-by: Med Ismail Bennani <medismail.benn...@gmail.com> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D139484 Files: lldb/test/API/functionalities/scripted_process/Makefile lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py lldb/test/API/functionalities/scripted_process/baz.c lldb/test/API/functionalities/scripted_process/baz.cpp lldb/test/API/functionalities/scripted_process/baz.h lldb/test/API/functionalities/scripted_process/main.cpp
Index: lldb/test/API/functionalities/scripted_process/main.cpp =================================================================== --- lldb/test/API/functionalities/scripted_process/main.cpp +++ lldb/test/API/functionalities/scripted_process/main.cpp @@ -1,10 +1,10 @@ #include <iostream> -#include <mutex> #include <thread> -extern "C" { -int baz(int); -} +#include "baz.h" + +std::condition_variable cv; +std::mutex mutex; int bar(int i) { int j = i * i; @@ -13,23 +13,22 @@ int foo(int i) { return bar(i); } -void call_and_wait(int &n) { - std::cout << "waiting for computation!" << std::endl; - while (baz(n) != 42) - ; - std::cout << "finished computation!" << std::endl; +void compute_pow(int &n) { + n = foo(n); } -void compute_pow(int &n) { n = foo(n); } +void call_and_wait(int &n, std::mutex& mutex, std::condition_variable& cv) { + cv.notify_one(); + while (baz(n, mutex, cv) != 42) { + cv.notify_one(); + } +} int main() { int n = 42; - std::mutex mutex; - std::unique_lock<std::mutex> lock(mutex); - std::thread thread_1(call_and_wait, std::ref(n)); + std::thread thread_1(call_and_wait, std::ref(n), std::ref(mutex), std::ref(cv)); std::thread thread_2(compute_pow, std::ref(n)); - lock.unlock(); thread_1.join(); thread_2.join(); Index: lldb/test/API/functionalities/scripted_process/baz.h =================================================================== --- lldb/test/API/functionalities/scripted_process/baz.h +++ lldb/test/API/functionalities/scripted_process/baz.h @@ -1,3 +1,6 @@ #pragma once -int baz(int j); +#include <condition_variable> +#include <mutex> + +int baz(int j, std::mutex& mutex, std::condition_variable& cv); Index: lldb/test/API/functionalities/scripted_process/baz.cpp =================================================================== --- /dev/null +++ lldb/test/API/functionalities/scripted_process/baz.cpp @@ -0,0 +1,10 @@ +#include "baz.h" + +#include <math.h> + +int baz(int j, std::mutex& mutex, std::condition_variable& cv) { + std::unique_lock<std::mutex> lock(mutex); + cv.wait(lock, [&j]{return j == 42 * 42;}); + int k = sqrt(j); + return k; // break here +} Index: lldb/test/API/functionalities/scripted_process/baz.c =================================================================== --- lldb/test/API/functionalities/scripted_process/baz.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "baz.h" - -#include <math.h> - -int baz(int j) { - int k = sqrt(j); - return k; // break here -} Index: lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py =================================================================== --- lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py +++ lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py @@ -17,7 +17,7 @@ def create_stack_skinny_corefile(self, file): self.build() target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here", - lldb.SBFileSpec("baz.c")) + lldb.SBFileSpec("baz.cpp")) self.assertTrue(process.IsValid(), "Process is invalid.") # FIXME: Use SBAPI to save the process corefile. self.runCmd("process save-core -s stack " + file) @@ -109,9 +109,9 @@ self.assertTrue(func, "Invalid function.") self.assertIn("baz", frame.GetFunctionName()) - self.assertEqual(frame.vars.GetSize(), 2) - self.assertEqual(int(frame.vars.GetFirstValueByName('j').GetValue()), 42 * 42) + self.assertGreater(frame.vars.GetSize(), 0) self.assertEqual(int(frame.vars.GetFirstValueByName('k').GetValue()), 42) + self.assertEqual(int(frame.vars.GetFirstValueByName('j').GetValue()), 42 * 42) corefile_dylib = self.get_module_with_name(corefile_target, 'libbaz.dylib') self.assertTrue(corefile_dylib, "Dynamic library libbaz.dylib not found.") Index: lldb/test/API/functionalities/scripted_process/Makefile =================================================================== --- lldb/test/API/functionalities/scripted_process/Makefile +++ lldb/test/API/functionalities/scripted_process/Makefile @@ -6,8 +6,8 @@ all: libbaz.dylib a.out -libbaz.dylib: baz.c +libbaz.dylib: baz.cpp $(MAKE) -f $(MAKEFILE_RULES) ARCH=$(ARCH) \ - DYLIB_ONLY=YES DYLIB_NAME=baz DYLIB_C_SOURCES=baz.c + DYLIB_ONLY=YES DYLIB_NAME=baz DYLIB_CXX_SOURCES=baz.cpp include Makefile.rules
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits