https://github.com/jeffreytan81 created https://github.com/llvm/llvm-project/pull/85260
None >From 6cccde22723157260e7c0b19bf8372aae8d1afaa Mon Sep 17 00:00:00 2001 From: jeffreytan81 <jeffrey...@fb.com> Date: Wed, 6 Mar 2024 12:07:03 -0800 Subject: [PATCH 1/2] Fix strcmp build error on buildbot --- lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp b/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp index b0a4446ba01581..40cb63755ee8a5 100644 --- a/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp +++ b/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp @@ -1,6 +1,7 @@ #include <assert.h> #include <iostream> #include <mutex> +#include <string.h> #include <sys/wait.h> #include <thread> #include <unistd.h> >From 6982a47579b372b0e34c751c9952b4aa03531aeb Mon Sep 17 00:00:00 2001 From: jeffreytan81 <jeffrey...@fb.com> Date: Thu, 14 Mar 2024 09:24:58 -0700 Subject: [PATCH 2/2] Single thread timeout prototype --- lldb/include/lldb/Target/ThreadPlan.h | 3 +- .../Target/ThreadPlanSingleThreadTimeout.h | 134 ++++++++++++++++++ .../lldb/Target/ThreadPlanStepOverRange.h | 2 + .../source/Target/ThreadPlanStepOverRange.cpp | 14 +- 4 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 lldb/include/lldb/Target/ThreadPlanSingleThreadTimeout.h diff --git a/lldb/include/lldb/Target/ThreadPlan.h b/lldb/include/lldb/Target/ThreadPlan.h index bf68a42e54d18f..3b488841bd9010 100644 --- a/lldb/include/lldb/Target/ThreadPlan.h +++ b/lldb/include/lldb/Target/ThreadPlan.h @@ -302,7 +302,8 @@ class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>, eKindStepInRange, eKindRunToAddress, eKindStepThrough, - eKindStepUntil + eKindStepUntil, + eKindSingleThreadTimeout }; virtual ~ThreadPlan(); diff --git a/lldb/include/lldb/Target/ThreadPlanSingleThreadTimeout.h b/lldb/include/lldb/Target/ThreadPlanSingleThreadTimeout.h new file mode 100644 index 00000000000000..a7b8b4ffaa8c40 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanSingleThreadTimeout.h @@ -0,0 +1,134 @@ +//===-- ThreadPlanSingleThreadTimeout.h -------------------------------------*- +// C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// TODO +#ifndef LLDB_TARGET_THREADPLANSINGLETHREADTIMEOUT_H +#define LLDB_TARGET_THREADPLANSINGLETHREADTIMEOUT_H + +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/State.h" + +#include <thread> + +namespace lldb_private { + +enum class SingleThreadPlanTimeoutState { + InitialResume, + TimeoutHalt, + ResumingAllThreads, + AfterThreadResumed, +}; + +class ThreadPlanSingleThreadTimeout : public ThreadPlan { +public: + ThreadPlanSingleThreadTimeout(Thread &thread) + : ThreadPlan(ThreadPlan::eKindSingleThreadTimeout, + "Single thread timeout", thread, eVoteNo, eVoteNoOpinion), + m_state(SingleThreadPlanTimeoutState::InitialResume) { + std::thread t(thread_function, this); + t.detach(); + } + + ~ThreadPlanSingleThreadTimeout() override = default; + + void GetDescription(Stream *s, lldb::DescriptionLevel level) override { + s->Printf("SingleThreadPlanTimeout, state(%d)", (int)m_state); + } + bool ValidatePlan(Stream *error) override { return true; } + bool WillStop() override { return true; } + bool DoPlanExplainsStop(Event *event_ptr) override { return true; } + lldb::StateType GetPlanRunState() override { return lldb::eStateRunning; } + static void thread_function(ThreadPlanSingleThreadTimeout *self) { + int timeout_ms = 5000; // 5 seconds timeout + std::this_thread::sleep_for( + std::chrono::milliseconds(timeout_ms)); + self->HandleTimeout(); + } + + bool MischiefManaged() override { + // return m_state == SingleThreadPlanTimeoutState::AfterThreadResumed; + return GetPreviousPlan()->MischiefManaged(); + } + + bool ShouldStop(Event *event_ptr) override { + if (m_state == SingleThreadPlanTimeoutState::InitialResume) { + return GetPreviousPlan()->ShouldStop(event_ptr); + } + return HandleEvent(event_ptr); + } + + void SetStopOthers(bool new_value) override { + GetPreviousPlan()->SetStopOthers(new_value); + } + + bool StopOthers() override { + if (m_state == SingleThreadPlanTimeoutState::ResumingAllThreads || + m_state == SingleThreadPlanTimeoutState::AfterThreadResumed) + return false; + else + return GetPreviousPlan()->StopOthers(); + } + +protected: + bool DoWillResume(lldb::StateType resume_state, bool current_plan) override { + if (m_state == SingleThreadPlanTimeoutState::ResumingAllThreads) { + m_state = SingleThreadPlanTimeoutState::AfterThreadResumed; + } + return GetPreviousPlan()->WillResume(resume_state, current_plan); + } + + bool HandleEvent(Event *event_ptr) { + lldb::StateType stop_state = + Process::ProcessEventData::GetStateFromEvent(event_ptr); + Log *log = GetLog(LLDBLog::Step); + LLDB_LOGF(log, + "ThreadPlanSingleThreadTimeout::HandleEvent(): got event: %s.", + StateAsCString(stop_state)); + + bool should_stop = true; + if (m_state == SingleThreadPlanTimeoutState::TimeoutHalt && + stop_state == lldb::eStateStopped) { + if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr)) { + // If we were restarted, we just need to go back up to fetch + // another event. + LLDB_LOGF( + log, "ThreadPlanSingleThreadTimeout::HandleEvent(): Got a stop and " + "restart, so we'll continue waiting."); + + } else { + GetThread().GetCurrentPlan()->SetStopOthers(false); + m_state = SingleThreadPlanTimeoutState::ResumingAllThreads; + } + should_stop = false; + } + if (should_stop) + return GetPreviousPlan()->ShouldStop(event_ptr); + else + return false; + } + + void HandleTimeout() { + m_state = SingleThreadPlanTimeoutState::TimeoutHalt; + m_process.SendAsyncInterrupt(); + } + +private: + SingleThreadPlanTimeoutState m_state; + + ThreadPlanSingleThreadTimeout(const ThreadPlanSingleThreadTimeout &) = delete; + const ThreadPlanSingleThreadTimeout & + operator=(const ThreadPlanSingleThreadTimeout &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_THREADPLANSINGLETHREADTIMEOUT_H diff --git a/lldb/include/lldb/Target/ThreadPlanStepOverRange.h b/lldb/include/lldb/Target/ThreadPlanStepOverRange.h index 8585ac62f09b35..c895620eb85f53 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOverRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOverRange.h @@ -28,6 +28,7 @@ class ThreadPlanStepOverRange : public ThreadPlanStepRange, void GetDescription(Stream *s, lldb::DescriptionLevel level) override; bool ShouldStop(Event *event_ptr) override; + void DidPush() override; protected: bool DoPlanExplainsStop(Event *event_ptr) override; @@ -44,6 +45,7 @@ class ThreadPlanStepOverRange : public ThreadPlanStepRange, bool IsEquivalentContext(const SymbolContext &context); bool m_first_resume; + lldb::RunMode m_run_mode; ThreadPlanStepOverRange(const ThreadPlanStepOverRange &) = delete; const ThreadPlanStepOverRange & diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 84f282f1de5207..17edc6ba3cfeb5 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -15,6 +15,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlanSingleThreadTimeout.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepThrough.h" #include "lldb/Utility/LLDBLog.h" @@ -36,13 +37,24 @@ ThreadPlanStepOverRange::ThreadPlanStepOverRange( : ThreadPlanStepRange(ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others), - ThreadPlanShouldStopHere(this), m_first_resume(true) { + ThreadPlanShouldStopHere(this), m_first_resume(true), + m_run_mode(stop_others) { SetFlagsToDefault(); SetupAvoidNoDebug(step_out_avoids_code_without_debug_info); } ThreadPlanStepOverRange::~ThreadPlanStepOverRange() = default; +void ThreadPlanStepOverRange::DidPush() { + if (m_run_mode == lldb::eOnlyThisThread) { + Thread &thread = GetThread(); + auto timeout_plan = new ThreadPlanSingleThreadTimeout(thread); + ThreadPlanSP thread_plan_sp(timeout_plan); + auto status = thread.QueueThreadPlan(thread_plan_sp, + /*abort_other_plans*/ false); + } +} + void ThreadPlanStepOverRange::GetDescription(Stream *s, lldb::DescriptionLevel level) { auto PrintFailureIfAny = [&]() { _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits