Skip to content

Commit

Permalink
feat: register operator api refine with optional
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Shui <jiashui@hotmail.com>
  • Loading branch information
JasonShui716 committed Dec 8, 2023
1 parent b6a0db0 commit 5c3aeea
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 36 deletions.
47 changes: 47 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"configurations": [

{
"type": "lldb",
"request": "launch",
"name": "LLDB Launch",
"program": "${workspaceFolder}/build/shuidb",
"args": [
"${workspaceFolder}/build/hello_world"
],
"cwd": "${workspaceFolder}"
},
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/shuidb",
"args": [
"${workspaceFolder}/build/hello_world"
],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Test",
"text": "python import sys;sys.path.insert(0, '/usr/share/gcc/python');from libstdcxx.v6.printers import register_libstdcxx_printers;register_libstdcxx_printers(None)",
"ignoreFailures": false
},
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -stdlib=libc++ -std=c++20 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -stdlib=libc++ -Wall")
project(shuidb)

add_library(linenoise external/linenoise/linenoise.c)
Expand Down
3 changes: 3 additions & 0 deletions include/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@

#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>

#include "breakpoint.h"
#include "register_def.h"
#include "type_def.h"

namespace shuidb {
Expand All @@ -37,6 +39,7 @@ class Debugger {
void ContinueExecution();
void SetBreakPointAtAddress(std::intptr_t addr);
std::vector<std::intptr_t> GetBreakPoints() const;
std::optional<std::unordered_map<Register, uint64_t>> GetRegisters() const;
void DumpRegisters() const;
StatusType ReadRegister(const std::string& reg_name) const;
StatusType WriteRegister(const std::string& reg_name, const uint64_t& val);
Expand Down
13 changes: 9 additions & 4 deletions include/register_operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,28 @@

#pragma once

#include <sys/user.h>
#include <unistd.h>

#include <optional>
#include <unordered_map>

#include "register_def.h"

namespace shuidb {

class RegisterOperator {
public:
static uint64_t GetRegisterValue(pid_t pid, Register reg);
static std::optional<std::unordered_map<Register, uint64_t>> GetRegisters(
pid_t pid);
static std::optional<uint64_t> GetRegisterValue(pid_t pid, Register reg);
static uint64_t GetRegisterValue(const user_regs_struct& regs,
const Register reg);
static void SetRegisterValue(pid_t pid, Register reg, uint64_t value);
static uint64_t GetRegisterValueFromDwarfRegister(pid_t pid, int dwarf_r);
static std::optional<uint64_t> GetRegisterValueFromDwarfRegister(pid_t pid,
int dwarf_r);
static std::string GetRegisterName(Register reg);
static std::optional<Register> GetRegisterFromName(const std::string& name);
static void DumpRegisters(pid_t pid);
static bool IsRegisterValid(const std::string& reg_name);
};

} // namespace shuidb
14 changes: 8 additions & 6 deletions scripts/install_env.bash
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/bin/bash
set -x

sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
sudo apt install -y libc++abi-17-dev libc++-17-dev lldb-17 clangd-17
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 100
sudo update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-17 100
sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-17 100
LLVM_VERSION=16

sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -- $LLVM_VERSION all
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$LLVM_VERSION 300
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-$LLVM_VERSION 300
sudo update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-$LLVM_VERSION 300
sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-$LLVM_VERSION 300
clang -v
clang++ -v
22 changes: 19 additions & 3 deletions src/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,26 @@ std::vector<std::intptr_t> Debugger::GetBreakPoints() const {
return bp_addrs;
}

std::optional<std::unordered_map<Register, uint64_t>> Debugger::GetRegisters()
const {
if (!IsRunning()) {
PR(ERROR) << "Process is not running";
return std::nullopt;
}
return RegisterOperator::GetRegisters(pid_);
}

void Debugger::DumpRegisters() const {
if (!IsRunning()) {
PR(ERROR) << "Process is not running";
return;
}

auto registers_map = GetRegisters();
PR(INFO) << "Registers:";
RegisterOperator::DumpRegisters(pid_);
for (const auto& [reg, val] : registers_map.value()) {
PR(RAW) << RegisterOperator::GetRegisterName(reg) << " 0x" << std::hex
<< std::setfill('0') << std::setw(16) << val;
}
}

StatusType Debugger::ReadRegister(const std::string& reg_name) const {
Expand All @@ -140,8 +152,12 @@ StatusType Debugger::ReadRegister(const std::string& reg_name) const {
return StatusType::kUnknownRegister;
}
auto reg_value = RegisterOperator::GetRegisterValue(pid_, reg.value());
if (!reg_value.has_value()) {
PR(ERROR) << "Failed to get register value";
return StatusType::kFailed;
}
PR(INFO) << reg_name << " 0x" << std::setfill('0') << std::setw(16)
<< std::hex << reg_value;
<< std::hex << reg_value.value();

return StatusType::kSuccess;
}
Expand Down
52 changes: 30 additions & 22 deletions src/register_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,39 @@
#include <sys/ptrace.h>
#include <sys/user.h>

#include <iomanip>
#include <cstdint>
#include <unordered_map>

#include "utils/output_utils.hpp"
#include "register_def.h"

namespace shuidb {

uint64_t RegisterOperator::GetRegisterValue(pid_t pid, Register reg) {
std::optional<std::unordered_map<Register, uint64_t>>
RegisterOperator::GetRegisters(pid_t pid) {
user_regs_struct regs;
ptrace(PTRACE_GETREGS, pid, nullptr, &regs);
if (ptrace(PTRACE_GETREGS, pid, nullptr, &regs) == -1) {
return std::nullopt;
}

std::unordered_map<Register, uint64_t> registers;
for (const auto& rd : kRegisterDescriptors) {
registers[rd.reg] = RegisterOperator::GetRegisterValue(pid, rd.reg).value();
}
return registers;
};

std::optional<uint64_t> RegisterOperator::GetRegisterValue(pid_t pid,
Register reg) {
user_regs_struct regs;
if (ptrace(PTRACE_GETREGS, pid, nullptr, &regs) == -1) {
return std::nullopt;
}

return RegisterOperator::GetRegisterValue(regs, reg);
};

uint64_t RegisterOperator::GetRegisterValue(const user_regs_struct& regs,
const Register reg) {
switch (reg) {
case Register::RAX:
return regs.rax;
Expand Down Expand Up @@ -176,8 +200,8 @@ void RegisterOperator::SetRegisterValue(pid_t pid, Register reg,
ptrace(PTRACE_SETREGS, pid, nullptr, &regs);
};

uint64_t RegisterOperator::GetRegisterValueFromDwarfRegister(pid_t pid,
int dwarf_r) {
std::optional<uint64_t> RegisterOperator::GetRegisterValueFromDwarfRegister(
pid_t pid, int dwarf_r) {
auto it = std::find_if(
kRegisterDescriptors.begin(), kRegisterDescriptors.end(),
[dwarf_r](const RegDescriptor& rd) { return rd.dwarf_r == dwarf_r; });
Expand Down Expand Up @@ -214,20 +238,4 @@ std::optional<Register> RegisterOperator::GetRegisterFromName(
return it->reg;
};

void RegisterOperator::DumpRegisters(pid_t pid) {
for (const auto& rd : kRegisterDescriptors) {
auto value = GetRegisterValue(pid, rd.reg);
PR_RAW << rd.name << " 0x" << std::setfill('0') << std::setw(16) << std::hex
<< value;
}
};

bool RegisterOperator::IsRegisterValid(const std::string& reg_name) {
auto it = std::find_if(
kRegisterDescriptors.begin(), kRegisterDescriptors.end(),
[reg_name](const RegDescriptor& rd) { return rd.name == reg_name; });

return it != kRegisterDescriptors.end();
};

} // namespace shuidb
4 changes: 4 additions & 0 deletions test/debugger_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ TEST_F(DebuggerTest, BreakPointTest) {
ASSERT_EQ(debugger_->IsRunning(), true);
}

TEST_F(DebuggerTest, DumpRegistersTest) {
debugger_->DumpRegisters();
}

} // namespace shuidb

0 comments on commit 5c3aeea

Please sign in to comment.