[sanitizer][NFCI] Add Options parameter to LowerAllowCheckPass (#122765)
[llvm-project.git] / lldb / unittests / Process / ProcessEventDataTest.cpp
blob9f65b71fc1c318dd5b20d38990e7a0825ed19bf4
1 //===-- ProcessEventDataTest.cpp ------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
10 #include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
11 #include "TestingSupport/TestUtilities.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Host/FileSystem.h"
14 #include "lldb/Host/HostInfo.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Target/StopInfo.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/ArchSpec.h"
19 #include "lldb/Utility/Event.h"
20 #include "gtest/gtest.h"
22 using namespace lldb_private;
23 using namespace lldb_private::repro;
24 using namespace lldb;
26 namespace {
27 class ProcessEventDataTest : public ::testing::Test {
28 public:
29 void SetUp() override {
30 FileSystem::Initialize();
31 HostInfo::Initialize();
32 PlatformMacOSX::Initialize();
33 std::call_once(TestUtilities::g_debugger_initialize_flag,
34 []() { Debugger::Initialize(nullptr); });
36 void TearDown() override {
37 PlatformMacOSX::Terminate();
38 HostInfo::Terminate();
39 FileSystem::Terminate();
43 class DummyProcess : public Process {
44 public:
45 DummyProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
46 : Process(target_sp, listener_sp) {}
48 bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override {
49 return true;
51 Status DoDestroy() override { return {}; }
52 void RefreshStateAfterStop() override {}
53 size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
54 Status &error) override {
55 return 0;
57 bool DoUpdateThreadList(ThreadList &old_thread_list,
58 ThreadList &new_thread_list) override {
59 return false;
61 llvm::StringRef GetPluginName() override { return "Dummy"; }
63 ProcessModID &GetModIDNonConstRef() { return m_mod_id; }
66 class DummyThread : public Thread {
67 public:
68 using Thread::Thread;
70 ~DummyThread() override { DestroyThread(); }
72 void RefreshStateAfterStop() override {}
74 lldb::RegisterContextSP GetRegisterContext() override { return nullptr; }
76 lldb::RegisterContextSP
77 CreateRegisterContextForFrame(StackFrame *frame) override {
78 return nullptr;
81 bool CalculateStopInfo() override { return false; }
84 class DummyStopInfo : public StopInfo {
85 public:
86 DummyStopInfo(Thread &thread, uint64_t value) : StopInfo(thread, value) {}
88 bool ShouldStop(Event *event_ptr) override { return m_should_stop; }
90 StopReason GetStopReason() const override { return m_stop_reason; }
92 bool m_should_stop = true;
93 StopReason m_stop_reason = eStopReasonBreakpoint;
96 class DummyProcessEventData : public Process::ProcessEventData {
97 public:
98 DummyProcessEventData(ProcessSP &process_sp, StateType state)
99 : ProcessEventData(process_sp, state) {}
100 bool ShouldStop(Event *event_ptr, bool &found_valid_stopinfo) override {
101 m_should_stop_hit_count++;
102 return false;
105 int m_should_stop_hit_count = 0;
107 } // namespace
109 typedef std::shared_ptr<Process::ProcessEventData> ProcessEventDataSP;
110 typedef std::shared_ptr<Event> EventSP;
112 TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) {
113 PlatformSP platform_sp;
114 TargetSP target_sp;
115 debugger_sp->GetTargetList().CreateTarget(
116 *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp);
118 return target_sp;
121 ThreadSP CreateThread(ProcessSP &process_sp, bool should_stop,
122 bool has_valid_stopinfo) {
123 ThreadSP thread_sp = std::make_shared<DummyThread>(*process_sp.get(), 0);
124 if (thread_sp == nullptr) {
125 return nullptr;
128 if (has_valid_stopinfo) {
129 StopInfoSP stopinfo_sp =
130 std::make_shared<DummyStopInfo>(*thread_sp.get(), 0);
131 static_cast<DummyStopInfo *>(stopinfo_sp.get())->m_should_stop =
132 should_stop;
133 if (stopinfo_sp == nullptr) {
134 return nullptr;
137 thread_sp->SetStopInfo(stopinfo_sp);
140 process_sp->GetThreadList().AddThread(thread_sp);
142 return thread_sp;
145 // Disable this test till I figure out why changing how events are sent
146 // to Secondary Listeners (44d9692e6a657ec46e98e4912ac56417da67cfee)
147 // caused this test to fail. It is testing responses to events that are
148 // not delivered in the way Process events are meant to be delivered, it
149 // bypasses the private event queue, and I'm not sure is testing real
150 // behaviors.
151 #if 0
152 TEST_F(ProcessEventDataTest, DoOnRemoval) {
153 ArchSpec arch("x86_64-apple-macosx-");
155 Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch));
157 DebuggerSP debugger_sp = Debugger::CreateInstance();
158 ASSERT_TRUE(debugger_sp);
160 TargetSP target_sp = CreateTarget(debugger_sp, arch);
161 ASSERT_TRUE(target_sp);
163 ListenerSP listener_sp(Listener::MakeListener("dummy"));
164 ProcessSP process_sp = std::make_shared<DummyProcess>(target_sp, listener_sp);
165 ASSERT_TRUE(process_sp);
168 Should hit ShouldStop if state is eStateStopped
170 ProcessEventDataSP event_data_sp =
171 std::make_shared<DummyProcessEventData>(process_sp, eStateStopped);
172 EventSP event_sp = std::make_shared<Event>(0, event_data_sp);
173 event_data_sp->SetUpdateStateOnRemoval(event_sp.get());
174 event_data_sp->DoOnRemoval(event_sp.get());
175 bool result = static_cast<DummyProcessEventData *>(event_data_sp.get())
176 ->m_should_stop_hit_count == 1;
177 ASSERT_TRUE(result);
180 Should not hit ShouldStop if state is not eStateStopped
182 event_data_sp =
183 std::make_shared<DummyProcessEventData>(process_sp, eStateStepping);
184 event_sp = std::make_shared<Event>(0, event_data_sp);
185 event_data_sp->SetUpdateStateOnRemoval(event_sp.get());
186 event_data_sp->DoOnRemoval(event_sp.get());
187 result = static_cast<DummyProcessEventData *>(event_data_sp.get())
188 ->m_should_stop_hit_count == 0;
189 ASSERT_TRUE(result);
191 #endif
193 TEST_F(ProcessEventDataTest, ShouldStop) {
194 ArchSpec arch("x86_64-apple-macosx-");
196 Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch));
198 DebuggerSP debugger_sp = Debugger::CreateInstance();
199 ASSERT_TRUE(debugger_sp);
201 TargetSP target_sp = CreateTarget(debugger_sp, arch);
202 ASSERT_TRUE(target_sp);
204 ListenerSP listener_sp(Listener::MakeListener("dummy"));
205 ProcessSP process_sp = std::make_shared<DummyProcess>(target_sp, listener_sp);
206 ASSERT_TRUE(process_sp);
208 // wants to stop and has valid StopInfo
209 ThreadSP thread_sp = CreateThread(process_sp, true, true);
211 ProcessEventDataSP event_data_sp =
212 std::make_shared<Process::ProcessEventData>(process_sp, eStateStopped);
213 EventSP event_sp = std::make_shared<Event>(0, event_data_sp);
215 Should stop if thread has valid StopInfo and not suspended
217 bool found_valid_stopinfo = false;
218 bool should_stop =
219 event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo);
220 ASSERT_TRUE(should_stop == true && found_valid_stopinfo == true);
223 Should not stop if thread has valid StopInfo but was suspended
225 found_valid_stopinfo = false;
226 thread_sp->SetResumeState(eStateSuspended);
227 should_stop = event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo);
228 ASSERT_TRUE(should_stop == false && found_valid_stopinfo == false);
231 Should not stop, thread-reason of stop does not want to stop in its
232 callback and suspended thread who wants to (from previous stop)
233 must be ignored.
235 event_data_sp =
236 std::make_shared<Process::ProcessEventData>(process_sp, eStateStopped);
237 event_sp = std::make_shared<Event>(0, event_data_sp);
238 process_sp->GetThreadList().Clear();
240 for (int i = 0; i < 6; i++) {
241 if (i == 2) {
242 // Does not want to stop but has valid StopInfo
243 thread_sp = CreateThread(process_sp, false, true);
244 } else if (i == 5) {
245 // Wants to stop and has valid StopInfo
246 thread_sp = CreateThread(process_sp, true, true);
247 thread_sp->SetResumeState(eStateSuspended);
248 } else {
249 // Thread has no StopInfo i.e is not the reason of stop
250 thread_sp = CreateThread(process_sp, false, false);
253 ASSERT_TRUE(process_sp->GetThreadList().GetSize() == 6);
255 found_valid_stopinfo = false;
256 should_stop = event_data_sp->ShouldStop(event_sp.get(), found_valid_stopinfo);
257 ASSERT_TRUE(should_stop == false && found_valid_stopinfo == true);