brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 288729b Raw
184 lines · cpp
1//===-- ThreadElfCoreTest.cpp ------------------------------------*- C++2//-*-===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9#include "Plugins/Process/elf-core/ThreadElfCore.h"10#include "Plugins/Platform/Linux/PlatformLinux.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/Target.h"17#include "lldb/Target/Thread.h"18#include "lldb/Utility/Listener.h"19#include "llvm/TargetParser/Triple.h"20#include "gtest/gtest.h"21 22#include <memory>23#include <mutex>24#include <sys/resource.h>25#include <unistd.h>26 27#ifndef HAVE_GETTID28#include <sys/syscall.h>29pid_t gettid() { return ((pid_t)syscall(SYS_gettid)); }30#endif31 32using namespace lldb_private;33 34namespace {35 36struct ElfCoreTest : public testing::Test {37  static void SetUpTestCase() {38    FileSystem::Initialize();39    HostInfo::Initialize();40    platform_linux::PlatformLinux::Initialize();41    std::call_once(TestUtilities::g_debugger_initialize_flag,42                   []() { Debugger::Initialize(nullptr); });43  }44  static void TearDownTestCase() {45    platform_linux::PlatformLinux::Terminate();46    HostInfo::Terminate();47    FileSystem::Terminate();48  }49};50 51struct DummyProcess : public Process {52  DummyProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)53      : Process(target_sp, listener_sp) {54    SetID(getpid());55  }56 57  bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override {58    return true;59  }60  Status DoDestroy() override { return {}; }61  void RefreshStateAfterStop() override {}62  size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,63                      Status &error) override {64    return 0;65  }66  bool DoUpdateThreadList(ThreadList &old_thread_list,67                          ThreadList &new_thread_list) override {68    return false;69  }70  llvm::StringRef GetPluginName() override { return "Dummy"; }71};72 73struct DummyThread : public Thread {74  using Thread::Thread;75 76  ~DummyThread() override { DestroyThread(); }77 78  void RefreshStateAfterStop() override {}79 80  lldb::RegisterContextSP GetRegisterContext() override { return nullptr; }81 82  lldb::RegisterContextSP83  CreateRegisterContextForFrame(StackFrame *frame) override {84    return nullptr;85  }86 87  bool CalculateStopInfo() override { return false; }88};89 90lldb::TargetSP CreateTarget(lldb::DebuggerSP &debugger_sp, ArchSpec &arch) {91  lldb::PlatformSP platform_sp;92  lldb::TargetSP target_sp;93  debugger_sp->GetTargetList().CreateTarget(94      *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp);95  return target_sp;96}97 98lldb::ThreadSP CreateThread(lldb::ProcessSP &process_sp) {99  lldb::ThreadSP thread_sp =100      std::make_shared<DummyThread>(*process_sp.get(), gettid());101  if (thread_sp == nullptr) {102    return nullptr;103  }104  process_sp->GetThreadList().AddThread(thread_sp);105 106  return thread_sp;107}108 109} // namespace110 111TEST_F(ElfCoreTest, PopulatePrpsInfoTest) {112  ArchSpec arch{HostInfo::GetTargetTriple()};113  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();114  ASSERT_TRUE(debugger_sp);115 116  lldb::TargetSP target_sp = CreateTarget(debugger_sp, arch);117  ASSERT_TRUE(target_sp);118 119  lldb::ListenerSP listener_sp(Listener::MakeListener("dummy"));120  lldb::ProcessSP process_sp =121      std::make_shared<DummyProcess>(target_sp, listener_sp);122  ASSERT_TRUE(process_sp);123  auto prpsinfo_opt = ELFLinuxPrPsInfo::Populate(process_sp);124  ASSERT_TRUE(prpsinfo_opt.has_value());125  ASSERT_EQ(prpsinfo_opt->pr_pid, getpid());126  ASSERT_EQ(prpsinfo_opt->pr_state, 0);127  ASSERT_EQ(prpsinfo_opt->pr_sname, 'R');128  ASSERT_EQ(prpsinfo_opt->pr_zomb, 0);129  int priority = getpriority(PRIO_PROCESS, getpid());130  if (priority == -1)131    ASSERT_EQ(errno, 0);132  ASSERT_EQ(prpsinfo_opt->pr_nice, priority);133  ASSERT_EQ(prpsinfo_opt->pr_flag, 0UL);134  ASSERT_EQ(prpsinfo_opt->pr_uid, getuid());135  ASSERT_EQ(prpsinfo_opt->pr_gid, getgid());136  ASSERT_EQ(prpsinfo_opt->pr_pid, getpid());137  ASSERT_EQ(prpsinfo_opt->pr_ppid, getppid());138  ASSERT_EQ(prpsinfo_opt->pr_pgrp, getpgrp());139  ASSERT_EQ(prpsinfo_opt->pr_sid, getsid(getpid()));140  ASSERT_EQ(std::string{prpsinfo_opt->pr_fname}, "ProcessElfCoreT");141  ASSERT_TRUE(std::string{prpsinfo_opt->pr_psargs}.empty());142  lldb_private::ProcessInstanceInfo info;143  ASSERT_TRUE(process_sp->GetProcessInfo(info));144  const char *args[] = {"a.out", "--foo=bar", "--baz=boo", nullptr};145  info.SetArguments(args, true);146  prpsinfo_opt =147      ELFLinuxPrPsInfo::Populate(info, lldb::StateType::eStateStopped);148  ASSERT_TRUE(prpsinfo_opt.has_value());149  ASSERT_EQ(prpsinfo_opt->pr_pid, getpid());150  ASSERT_EQ(prpsinfo_opt->pr_state, 3);151  ASSERT_EQ(prpsinfo_opt->pr_sname, 'T');152  ASSERT_EQ(std::string{prpsinfo_opt->pr_fname}, "a.out");153  ASSERT_FALSE(std::string{prpsinfo_opt->pr_psargs}.empty());154  ASSERT_EQ(std::string{prpsinfo_opt->pr_psargs}, "a.out --foo=bar --baz=boo");155}156 157TEST_F(ElfCoreTest, PopulatePrStatusTest) {158  ArchSpec arch{HostInfo::GetTargetTriple()};159  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();160  ASSERT_TRUE(debugger_sp);161 162  lldb::TargetSP target_sp = CreateTarget(debugger_sp, arch);163  ASSERT_TRUE(target_sp);164 165  lldb::ListenerSP listener_sp(Listener::MakeListener("dummy"));166  lldb::ProcessSP process_sp =167      std::make_shared<DummyProcess>(target_sp, listener_sp);168  ASSERT_TRUE(process_sp);169  lldb::ThreadSP thread_sp = CreateThread(process_sp);170  ASSERT_TRUE(thread_sp);171  auto prstatus_opt = ELFLinuxPrStatus::Populate(thread_sp);172  ASSERT_TRUE(prstatus_opt.has_value());173  ASSERT_EQ(prstatus_opt->si_signo, 0);174  ASSERT_EQ(prstatus_opt->si_code, 0);175  ASSERT_EQ(prstatus_opt->si_errno, 0);176  ASSERT_EQ(prstatus_opt->pr_cursig, 0);177  ASSERT_EQ(prstatus_opt->pr_sigpend, 0UL);178  ASSERT_EQ(prstatus_opt->pr_sighold, 0UL);179  ASSERT_EQ(prstatus_opt->pr_pid, static_cast<uint32_t>(gettid()));180  ASSERT_EQ(prstatus_opt->pr_ppid, static_cast<uint32_t>(getppid()));181  ASSERT_EQ(prstatus_opt->pr_pgrp, static_cast<uint32_t>(getpgrp()));182  ASSERT_EQ(prstatus_opt->pr_sid, static_cast<uint32_t>(getsid(gettid())));183}184