92 lines · plain
1#include "pseudo_barrier.h"2 3#include <atomic>4#include <thread>5 6%include_SB_APIs%7 8#include "common.h"9 10using namespace lldb;11 12void test (SBDebugger &dbg, std::vector<std::string> args) {13 14SBError error;15 dbg.SetAsync(false);16 SBTarget target = dbg.CreateTarget(args.at(0).c_str());17 if (!target.IsValid())18 throw Exception("Invalid target");19 20 // Now set our breakpoint and launch:21 SBFileSpec main_sourcefile("deep_stack.cpp");22 SBBreakpoint bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint here",23 main_sourcefile);24 if (bkpt.GetNumLocations() == 0)25 throw Exception("Main breakpoint got no locations");26 27 SBLaunchInfo launch_info = target.GetLaunchInfo();28 SBProcess process = target.Launch(launch_info, error);29 if (error.Fail())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");35 36 size_t num_threads = process.GetNumThreads();37 if (num_threads != 1)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");42 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();47 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);54 55 auto lambda = [&](size_t stride){56 pseudo_barrier_wait(rendevous);57 bool younger = true;58 while (1) {59 size_t cursor = largest;60 if (cursor > stride && !younger) {61 cursor -= stride;62 younger = true;63 } else {64 cursor += stride;65 largest += stride;66 younger = false;67 }68 SBFrame frame = cur_thread.GetFrameAtIndex(cursor);69 if (!frame.IsValid()) {70 if (cursor < num_frames)71 success = false;72 break;73 }74 }75 76 };77 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);83 thread1.join();84 thread2.join();85 thread3.join();86 thread4.join();87 thread5.join();88 89 if (!success)90 throw Exception("One thread stopped before 1000");91}92