llvm-project/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
Dave Lee 41d0b20cc9 [lldb] Avoid moving ThreadPlanSP from plans vector
Change `ThreadPlanStack::PopPlan` and `::DiscardPlan` to not do the following:

1. Move the last plan, leaving a moved `ThreadPlanSP` in the plans vector
2. Operate on the last plan
3. Pop the last plan off the plans vector

This leaves a period of time where the last element in the plans vector has been moved. I am not sure what, if any, guarantees there are when doing this, but it seems like it would/could leave a null `ThreadPlanSP` in the container. There are asserts in place to prevent empty/null `ThreadPlanSP` instances from being pushed on to the stack, and so this could break that invariant during multithreaded access to the thread plan stack.

An open question is whether this use of `std::move` was the result of a measure performance problem.

Differential Revision: https://reviews.llvm.org/D106171
2021-08-01 10:40:04 -07:00

58 lines
1.8 KiB
C++

//===-- ThreadPlanStepOverBreakpoint.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
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_TARGET_THREADPLANSTEPOVERBREAKPOINT_H
#define LLDB_TARGET_THREADPLANSTEPOVERBREAKPOINT_H
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
namespace lldb_private {
class ThreadPlanStepOverBreakpoint : public ThreadPlan {
public:
ThreadPlanStepOverBreakpoint(Thread &thread);
~ThreadPlanStepOverBreakpoint() override;
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
bool ValidatePlan(Stream *error) override;
bool ShouldStop(Event *event_ptr) override;
bool StopOthers() override;
lldb::StateType GetPlanRunState() override;
bool WillStop() override;
void DidPop() override;
bool MischiefManaged() override;
void ThreadDestroyed() override;
void SetAutoContinue(bool do_it);
bool ShouldAutoContinue(Event *event_ptr) override;
bool IsPlanStale() override;
lldb::addr_t GetBreakpointLoadAddress() const { return m_breakpoint_addr; }
protected:
bool DoPlanExplainsStop(Event *event_ptr) override;
bool DoWillResume(lldb::StateType resume_state, bool current_plan) override;
void ReenableBreakpointSite();
private:
lldb::addr_t m_breakpoint_addr;
lldb::user_id_t m_breakpoint_site_id;
bool m_auto_continue;
bool m_reenabled_breakpoint_site;
ThreadPlanStepOverBreakpoint(const ThreadPlanStepOverBreakpoint &) = delete;
const ThreadPlanStepOverBreakpoint &
operator=(const ThreadPlanStepOverBreakpoint &) = delete;
};
} // namespace lldb_private
#endif // LLDB_TARGET_THREADPLANSTEPOVERBREAKPOINT_H