Skip to content

Commit 874b20b

Browse files
[lldb] Add unittest for StackID comparisons
While this could, theoretically, be sent upstream, we have unfortunately renamed some of the core APIs downstream ("IsYounger" doesn't exist upstream, nor anything "heap cfa" related).
1 parent 3a04b39 commit 874b20b

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

lldb/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ add_subdirectory(Platform)
7373
add_subdirectory(Process)
7474
add_subdirectory(ScriptInterpreter)
7575
add_subdirectory(Signals)
76+
add_subdirectory(StackID)
7677
add_subdirectory(Symbol)
7778
add_subdirectory(SymbolFile)
7879
add_subdirectory(TypeSystem)

lldb/unittests/StackID/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
add_lldb_unittest(StackIDTests
2+
StackIDTest.cpp
3+
4+
LINK_LIBS
5+
lldbCore
6+
lldbTarget
7+
lldbPluginPlatformMacOSX
8+
)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
2+
#include "lldb/Target/StackID.h"
3+
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
4+
#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h"
5+
#include "lldb/Core/Debugger.h"
6+
#include "lldb/Host/HostInfo.h"
7+
#include "lldb/Target/Process.h"
8+
#include "gtest/gtest.h"
9+
10+
using namespace lldb_private;
11+
using namespace lldb;
12+
13+
static std::once_flag initialize_flag;
14+
15+
// Initialize the bare minimum to enable defining a mock Process class.
16+
class StackIDTest : public ::testing::Test {
17+
public:
18+
void SetUp() override {
19+
std::call_once(initialize_flag, []() {
20+
HostInfo::Initialize();
21+
PlatformMacOSX::Initialize();
22+
FileSystem::Initialize();
23+
});
24+
ArchSpec arch("x86_64-apple-macosx-");
25+
Platform::SetHostPlatform(
26+
PlatformRemoteMacOSX::CreateInstance(true, &arch));
27+
m_debugger_sp = Debugger::CreateInstance();
28+
m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch,
29+
eLoadDependentsNo,
30+
m_platform_sp, m_target_sp);
31+
ASSERT_TRUE(m_target_sp);
32+
ASSERT_TRUE(m_target_sp->GetArchitecture().IsValid());
33+
ASSERT_TRUE(m_platform_sp);
34+
}
35+
36+
PlatformSP m_platform_sp;
37+
TargetSP m_target_sp;
38+
DebuggerSP m_debugger_sp;
39+
};
40+
41+
struct MockProcess : Process {
42+
MockProcess(TargetSP target_sp, ListenerSP listener_sp)
43+
: Process(target_sp, listener_sp) {}
44+
size_t DoReadMemory(addr_t vm_addr, void *buf, size_t size,
45+
Status &error) override {
46+
return 0;
47+
}
48+
size_t ReadMemory(addr_t addr, void *buf, size_t size,
49+
Status &status) override {
50+
return DoReadMemory(addr, buf, size, status);
51+
}
52+
bool CanDebug(TargetSP, bool) override { return true; }
53+
Status DoDestroy() override { return Status(); }
54+
llvm::StringRef GetPluginName() override { return ""; }
55+
void RefreshStateAfterStop() override {}
56+
bool DoUpdateThreadList(ThreadList &, ThreadList &) override { return false; }
57+
};
58+
59+
enum OnStack { Yes, No };
60+
/// Helper class to enable testing StackID::IsYounger.
61+
struct MockStackID : StackID {
62+
MockStackID(addr_t cfa, OnStack on_stack) : StackID() {
63+
SetPC(0);
64+
SetCFA(cfa);
65+
m_cfa_on_stack = on_stack == OnStack::Yes ? LazyBool::eLazyBoolYes
66+
: LazyBool::eLazyBoolNo;
67+
}
68+
};
69+
70+
TEST_F(StackIDTest, StackStackCFAComparison) {
71+
auto process = MockProcess(m_target_sp, Listener::MakeListener("dummy"));
72+
73+
MockStackID small_cfa_on_stack(/*cfa*/ 10, OnStack::Yes);
74+
MockStackID big_cfa_on_stack(/*cfa*/ 100, OnStack::Yes);
75+
76+
EXPECT_TRUE(
77+
StackID::IsYounger(small_cfa_on_stack, big_cfa_on_stack, process));
78+
EXPECT_FALSE(
79+
StackID::IsYounger(big_cfa_on_stack, small_cfa_on_stack, process));
80+
}
81+
82+
TEST_F(StackIDTest, StackHeapCFAComparison) {
83+
auto process = MockProcess(m_target_sp, Listener::MakeListener("dummy"));
84+
85+
MockStackID cfa_on_stack(/*cfa*/ 100, OnStack::Yes);
86+
MockStackID cfa_on_heap(/*cfa*/ 10, OnStack::No);
87+
88+
EXPECT_TRUE(StackID::IsYounger(cfa_on_stack, cfa_on_heap, process));
89+
90+
// FIXME: if the above returned true, swapping the arguments **must** return
91+
// false. And yet it doesn't.
92+
// EXPECT_FALSE(StackID::IsYounger(cfa_on_heap, cfa_on_stack, process));
93+
}

0 commit comments

Comments
 (0)