1 //===-- ThreadTest.cpp ------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/Thread.h"
10 #include "Plugins/Platform/Linux/PlatformLinux.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Target/StopInfo.h"
16 #include "lldb/Utility/ArchSpec.h"
17 #include "gtest/gtest.h"
19 using namespace lldb_private
;
20 using namespace lldb_private::repro
;
24 class ThreadTest
: public ::testing::Test
{
26 void SetUp() override
{
27 FileSystem::Initialize();
28 HostInfo::Initialize();
29 platform_linux::PlatformLinux::Initialize();
31 void TearDown() override
{
32 platform_linux::PlatformLinux::Terminate();
33 HostInfo::Terminate();
34 FileSystem::Terminate();
38 class DummyProcess
: public Process
{
40 DummyProcess(lldb::TargetSP target_sp
, lldb::ListenerSP listener_sp
)
41 : Process(target_sp
, listener_sp
) {}
43 bool CanDebug(lldb::TargetSP target
, bool plugin_specified_by_name
) override
{
46 Status
DoDestroy() override
{ return {}; }
47 void RefreshStateAfterStop() override
{}
48 size_t DoReadMemory(lldb::addr_t vm_addr
, void *buf
, size_t size
,
49 Status
&error
) override
{
52 bool DoUpdateThreadList(ThreadList
&old_thread_list
,
53 ThreadList
&new_thread_list
) override
{
56 llvm::StringRef
GetPluginName() override
{ return "Dummy"; }
58 ProcessModID
&GetModIDNonConstRef() { return m_mod_id
; }
61 class DummyThread
: public Thread
{
65 ~DummyThread() override
{ DestroyThread(); }
67 void RefreshStateAfterStop() override
{}
69 lldb::RegisterContextSP
GetRegisterContext() override
{ return nullptr; }
71 lldb::RegisterContextSP
72 CreateRegisterContextForFrame(StackFrame
*frame
) override
{
76 bool CalculateStopInfo() override
{ return false; }
78 bool IsStillAtLastBreakpointHit() override
{ return true; }
82 TargetSP
CreateTarget(DebuggerSP
&debugger_sp
, ArchSpec
&arch
) {
83 PlatformSP platform_sp
;
85 debugger_sp
->GetTargetList().CreateTarget(
86 *debugger_sp
, "", arch
, eLoadDependentsNo
, platform_sp
, target_sp
);
91 TEST_F(ThreadTest
, SetStopInfo
) {
92 ArchSpec
arch("powerpc64-pc-linux");
94 Platform::SetHostPlatform(
95 platform_linux::PlatformLinux::CreateInstance(true, &arch
));
97 DebuggerSP debugger_sp
= Debugger::CreateInstance();
98 ASSERT_TRUE(debugger_sp
);
100 TargetSP target_sp
= CreateTarget(debugger_sp
, arch
);
101 ASSERT_TRUE(target_sp
);
103 ListenerSP
listener_sp(Listener::MakeListener("dummy"));
104 ProcessSP process_sp
= std::make_shared
<DummyProcess
>(target_sp
, listener_sp
);
105 ASSERT_TRUE(process_sp
);
107 DummyProcess
*process
= static_cast<DummyProcess
*>(process_sp
.get());
109 ThreadSP thread_sp
= std::make_shared
<DummyThread
>(*process_sp
.get(), 0);
110 ASSERT_TRUE(thread_sp
);
112 StopInfoSP stopinfo_sp
=
113 StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp
.get(), 0);
114 ASSERT_TRUE(stopinfo_sp
->IsValid() == true);
117 Should make stopinfo valid.
119 process
->GetModIDNonConstRef().BumpStopID();
120 ASSERT_TRUE(stopinfo_sp
->IsValid() == false);
122 thread_sp
->SetStopInfo(stopinfo_sp
);
123 ASSERT_TRUE(stopinfo_sp
->IsValid() == true);
126 TEST_F(ThreadTest
, GetPrivateStopInfo
) {
127 ArchSpec
arch("powerpc64-pc-linux");
129 Platform::SetHostPlatform(
130 platform_linux::PlatformLinux::CreateInstance(true, &arch
));
132 DebuggerSP debugger_sp
= Debugger::CreateInstance();
133 ASSERT_TRUE(debugger_sp
);
135 TargetSP target_sp
= CreateTarget(debugger_sp
, arch
);
136 ASSERT_TRUE(target_sp
);
138 ListenerSP
listener_sp(Listener::MakeListener("dummy"));
139 ProcessSP process_sp
= std::make_shared
<DummyProcess
>(target_sp
, listener_sp
);
140 ASSERT_TRUE(process_sp
);
142 DummyProcess
*process
= static_cast<DummyProcess
*>(process_sp
.get());
144 ThreadSP thread_sp
= std::make_shared
<DummyThread
>(*process_sp
.get(), 0);
145 ASSERT_TRUE(thread_sp
);
147 StopInfoSP stopinfo_sp
=
148 StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp
.get(), 0);
149 ASSERT_TRUE(stopinfo_sp
);
151 thread_sp
->SetStopInfo(stopinfo_sp
);
154 Should make stopinfo valid if thread is at last breakpoint hit.
156 process
->GetModIDNonConstRef().BumpStopID();
157 ASSERT_TRUE(stopinfo_sp
->IsValid() == false);
158 StopInfoSP new_stopinfo_sp
= thread_sp
->GetPrivateStopInfo();
159 ASSERT_TRUE(new_stopinfo_sp
&& stopinfo_sp
->IsValid() == true);