1 #include "pseudo_barrier.h"
12 void test (SBDebugger &dbg, std::vector<std::string> args) {
16 SBTarget target = dbg.CreateTarget(args.at(0).c_str());
17 if (!target.IsValid())
18 throw Exception("Invalid target");
20 // Now set our breakpoint and launch:
21 SBFileSpec main_sourcefile("deep_stack.cpp");
22 SBBreakpoint bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint here",
24 if (bkpt.GetNumLocations() == 0)
25 throw Exception("Main breakpoint got no locations");
27 SBLaunchInfo launch_info = target.GetLaunchInfo();
28 SBProcess process = target.Launch(launch_info, error);
30 throw Exception("Failed to launch process");
31 if (!process.IsValid())
32 throw Exception("Process is not valid");
33 if (process.GetState() != lldb::eStateStopped)
34 throw Exception("Process was not stopped");
36 size_t num_threads = process.GetNumThreads();
38 throw Exception("Unexpected number of threads.");
39 SBThread cur_thread = process.GetThreadAtIndex(0);
40 if (!cur_thread.IsValid())
41 throw Exception("Didn't get a valid thread");
43 // Record the number of frames at the point where we stopped:
44 const size_t num_frames = cur_thread.GetNumFrames();
45 // Now step once to clear the frame cache:
46 cur_thread.StepOver();
48 // Create three threads and set them to getting frames simultaneously,
49 // and make sure we don't deadlock.
50 pseudo_barrier_t rendevous;
51 pseudo_barrier_init(rendevous, 5);
52 std::atomic_size_t success(true);
53 std::atomic_size_t largest(0);
55 auto lambda = [&](size_t stride){
56 pseudo_barrier_wait(rendevous);
59 size_t cursor = largest;
60 if (cursor > stride && !younger) {
68 SBFrame frame = cur_thread.GetFrameAtIndex(cursor);
69 if (!frame.IsValid()) {
70 if (cursor < num_frames)
78 std::thread thread1(lambda, 1);
79 std::thread thread2(lambda, 3);
80 std::thread thread3(lambda, 5);
81 std::thread thread4(lambda, 7);
82 std::thread thread5(lambda, 11);
90 throw Exception("One thread stopped before 1000");