feat: graceful shutdown

This commit is contained in:
xinyangli 2024-07-16 11:16:11 +08:00
parent 6501c55e30
commit 7db988bdee
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
4 changed files with 27 additions and 33 deletions

View file

@ -17,6 +17,8 @@ private:
// target used for read_reg, write_reg, read_mem, write_mem // target used for read_reg, write_reg, read_mem, write_mem
Target *current_target = &dut; Target *current_target = &dut;
bool exec(size_t n, gdb_action_t *ret);
public: public:
Difftest(Target &&dut, std::vector<Target> &&refs); Difftest(Target &&dut, std::vector<Target> &&refs);
@ -32,12 +34,13 @@ public:
bool set_bp(size_t addr, bp_type_t type); bool set_bp(size_t addr, bp_type_t type);
bool del_bp(size_t addr, bp_type_t type); bool del_bp(size_t addr, bp_type_t type);
bool check_all();
arch_info_t get_arch() const { arch_info_t get_arch() const {
std::cout << dut.arch.reg_num << std::endl; std::cout << dut.arch.reg_num << std::endl;
return dut.arch; return dut.arch;
} }
// Other APi
static bool check(Target &dut, Target &ref) { static bool check(Target &dut, Target &ref) {
for (int r = 0; r < dut.arch.reg_num; r++) { for (int r = 0; r < dut.arch.reg_num; r++) {
size_t regdut = 0, regref = 0; size_t regdut = 0, regref = 0;
@ -51,7 +54,6 @@ public:
} }
return true; return true;
}; };
bool check_all();
class Iterator { class Iterator {
private: private:

View file

@ -1,6 +1,7 @@
#include "api.hpp" #include "api.hpp"
#include <difftest.hpp> #include <difftest.hpp>
#include <fstream> #include <fstream>
#include <gdbstub.h>
#include <stdexcept> #include <stdexcept>
#include <cstdio> #include <cstdio>
@ -49,9 +50,9 @@ bool Difftest::check_all() {
return true; return true;
} }
gdb_action_t Difftest::stepi() { bool Difftest::exec(size_t n, gdb_action_t *ret) {
bool breakflag = false; bool breakflag = false;
Target *pbreak; Target *pbreak = &(*(this->begin()));
for (auto it = this->begin(); it != this->end(); ++it) { for (auto it = this->begin(); it != this->end(); ++it) {
auto &target = *it; auto &target = *it;
target.ops.stepi(target.args.data(), &target.last_res); target.ops.stepi(target.args.data(), &target.last_res);
@ -62,37 +63,26 @@ gdb_action_t Difftest::stepi() {
} }
if (breakflag) { if (breakflag) {
gdb_action_t ret = {.reason = gdb_action_t::ACT_BREAKPOINT}; ret->reason = pbreak->last_res.reason;
pbreak->ops.read_reg(pbreak->args.data(), 32, &ret.data); ret->data = pbreak->last_res.data;
return ret; return false;
} }
return {gdb_action_t::ACT_NONE, 0}; return true;
}
gdb_action_t Difftest::stepi() {
gdb_action_t ret = {.reason = gdb_action_t::ACT_NONE};
exec(1, &ret);
check_all();
return ret;
} }
gdb_action_t Difftest::cont() { gdb_action_t Difftest::cont() {
bool breakflag = false; gdb_action_t ret = {.reason = gdb_action_t::ACT_NONE};
Target *pbreak; while (exec(1, &ret)) {
while (true) {
// for(auto &target : *this) {
for (auto it = this->begin(); it != this->end(); ++it) {
auto &target = *it;
target.ops.stepi(target.args.data(), &target.last_res);
if (target.is_on_breakpoint()) {
breakflag = true;
pbreak = &target;
}
}
check_all(); check_all();
};
if (breakflag) { return ret;
gdb_action_t ret = {.reason = gdb_action_t::ACT_BREAKPOINT};
pbreak->ops.read_reg(pbreak->args.data(), 32, &ret.data);
return ret;
}
}
return {gdb_action_t::ACT_NONE, 0};
} }
int Difftest::read_reg(int regno, size_t *value) { int Difftest::read_reg(int regno, size_t *value) {

View file

@ -1,6 +1,7 @@
#include "api.hpp" #include "api.hpp"
#include <cstdint> #include <cstdint>
#include <dlfcn.h> #include <dlfcn.h>
#include <gdbstub.h>
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
@ -70,7 +71,8 @@ bool Target::is_on_breakpoint(const gdb_action_t &res) const {
if (res.reason == gdb_action_t::ACT_BREAKPOINT || if (res.reason == gdb_action_t::ACT_BREAKPOINT ||
res.reason == gdb_action_t::ACT_RWATCH || res.reason == gdb_action_t::ACT_RWATCH ||
res.reason == gdb_action_t::ACT_WATCH || res.reason == gdb_action_t::ACT_WATCH ||
res.reason == gdb_action_t::ACT_WWATCH) { res.reason == gdb_action_t::ACT_WWATCH ||
res.reason == gdb_action_t::ACT_SHUTDOWN) {
return true; return true;
} }
return false; return false;

View file

@ -13,12 +13,12 @@ int main(int argc, char **argv) {
return ret; return ret;
std::vector<Target> refs; std::vector<Target> refs;
Target dut = Target{"dut", "nemu_", config.dut}; Target *dut = new Target{"dut", "nemu_", config.dut};
for (const auto &ref_libpath : config.refs) { for (const auto &ref_libpath : config.refs) {
refs.emplace_back(ref_libpath.string(), "nemu_", ref_libpath); refs.emplace_back(ref_libpath.string(), "nemu_", ref_libpath);
} }
Difftest difftest{std::move(dut), std::move(refs)}; Difftest difftest{std::move(*dut), std::move(refs)};
difftest.setup(config.memory_file); difftest.setup(config.memory_file);