base,sim: Adding monitor function to GDB
The remote protocol provides a monitor query. This query allows to provide a implementation defined behavior in the stub. I proposed to use this command as a way to quit simulation with a message provided by the GDB client. Thus calling "monitor my_message" in the client will exit the simulation with the exit message "GDB_MONITOR:my_message". This is implemented through a derived class based on GlobalSimLoopExitEvent and a small addition to the based class that adds a clean method that will be called when returning siumation after the Event. Change-Id: Ib5fda569edcf6733cbcc6240ef6d2ec4dc6502ec Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63538 Maintainer: Bobby Bruce <bbruce@ucdavis.edu> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -157,6 +157,7 @@
|
||||
#include "mem/translating_port_proxy.hh"
|
||||
#include "sim/full_system.hh"
|
||||
#include "sim/process.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
namespace gem5
|
||||
@@ -241,7 +242,7 @@ hex2c(char c0,char c1)
|
||||
|
||||
//this function will be used in a future patch
|
||||
//convert a encoded string to a string
|
||||
[[maybe_unused]] std::string
|
||||
std::string
|
||||
hexS2string(std::string hex_in)
|
||||
{
|
||||
std::string out="";
|
||||
@@ -554,7 +555,6 @@ BaseRemoteGDB::trap(ContextID id, GDBSignal sig,const std::string& stopReason)
|
||||
return;
|
||||
|
||||
if (tc->contextId() != id) {
|
||||
|
||||
//prevent thread switch when single stepping
|
||||
if (singleStepEvent.scheduled()){
|
||||
return;
|
||||
@@ -564,11 +564,14 @@ BaseRemoteGDB::trap(ContextID id, GDBSignal sig,const std::string& stopReason)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DPRINTF(GDBMisc, "trap: PC=%s\n", tc->pcState());
|
||||
|
||||
clearSingleStep();
|
||||
|
||||
if (threadSwitching) {
|
||||
if (stopReason=="monitor_return"){
|
||||
//should wnot send any Tpacket here
|
||||
send("OK");
|
||||
}else if (threadSwitching) {
|
||||
threadSwitching = false;
|
||||
// Tell GDB the thread switch has completed.
|
||||
send("OK");
|
||||
@@ -1326,6 +1329,7 @@ splitAt(std::string str, const char * const delim)
|
||||
std::map<std::string, BaseRemoteGDB::QuerySetCommand>
|
||||
BaseRemoteGDB::queryMap = {
|
||||
{ "C", { &BaseRemoteGDB::queryC } },
|
||||
{ "Rcmd", { &BaseRemoteGDB::queryRcmd} },
|
||||
{ "Attached", { &BaseRemoteGDB::queryAttached} },
|
||||
{ "Supported", { &BaseRemoteGDB::querySupported, ";" } },
|
||||
{ "Xfer", { &BaseRemoteGDB::queryXfer } },
|
||||
@@ -1416,6 +1420,38 @@ BaseRemoteGDB::queryAttached(QuerySetCommand::Context &ctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
class MonitorCallEvent : public GlobalSimLoopExitEvent
|
||||
{
|
||||
BaseRemoteGDB& gdb;
|
||||
ContextID id;
|
||||
public:
|
||||
MonitorCallEvent(BaseRemoteGDB& gdb,ContextID id,const std::string &_cause,
|
||||
int code):
|
||||
GlobalSimLoopExitEvent(_cause,code), gdb(gdb),id(id)
|
||||
{};
|
||||
void process() override{
|
||||
GlobalSimLoopExitEvent::process();
|
||||
}
|
||||
void clean() override{
|
||||
//trapping now
|
||||
//this is the only point in time when we can call trap
|
||||
//before any breakpoint triggers
|
||||
gdb.trap(id,GDBSignal::ZERO,"monitor_return");
|
||||
delete this;
|
||||
}
|
||||
~MonitorCallEvent(){
|
||||
DPRINTF(Event,"MonitorCallEvent destructed\n");;
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
BaseRemoteGDB::queryRcmd(QuerySetCommand::Context &ctx){
|
||||
std::string message=hexS2string(ctx.args[0]);
|
||||
DPRINTF(GDBMisc, "Rcmd Query: %s => %s\n", ctx.args[0],message);
|
||||
//Tick when = curTick();
|
||||
new MonitorCallEvent(*this,tc->contextId(),"GDB_MONITOR:"+ message, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseRemoteGDB::queryFThreadInfo(QuerySetCommand::Context &ctx)
|
||||
@@ -1444,7 +1480,7 @@ BaseRemoteGDB::cmdQueryVar(GdbCommand::Context &ctx)
|
||||
{
|
||||
// The query command goes until the first ':', or the end of the string.
|
||||
std::string s(ctx.data, ctx.len);
|
||||
auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":");
|
||||
auto query_split = splitAt({ ctx.data, (size_t)ctx.len }, ":,");
|
||||
const auto &query_str = query_split.first;
|
||||
|
||||
// Look up the query command, and report if it isn't found.
|
||||
|
||||
@@ -433,6 +433,7 @@ class BaseRemoteGDB
|
||||
bool querySupported(QuerySetCommand::Context &ctx);
|
||||
bool queryXfer(QuerySetCommand::Context &ctx);
|
||||
bool querySymbol(QuerySetCommand::Context &ctx);
|
||||
bool queryRcmd(QuerySetCommand::Context &ctx);
|
||||
bool queryAttached(QuerySetCommand::Context &ctx);
|
||||
|
||||
size_t threadInfoIdx = 0;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#include "base/debug.hh"
|
||||
#include "base/flags.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "base/types.hh"
|
||||
#include "base/uncontended_mutex.hh"
|
||||
#include "debug/Event.hh"
|
||||
|
||||
@@ -68,8 +68,11 @@ class GlobalSimLoopExitEvent : public GlobalEvent
|
||||
const std::string getCause() const { return cause; }
|
||||
int getCode() const { return code; }
|
||||
|
||||
void process(); // process event
|
||||
|
||||
virtual void process();// process event
|
||||
virtual void clean(){};//cleaning event
|
||||
~GlobalSimLoopExitEvent (){
|
||||
DPRINTF(Event,"GlobalSimLoopExitEvent destructed\n");
|
||||
};
|
||||
virtual const char *description() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -184,9 +184,12 @@ struct DescheduleDeleter
|
||||
* terminate the loop. Exported to Python.
|
||||
* @return The SimLoopExitEvent that caused the loop to exit.
|
||||
*/
|
||||
GlobalSimLoopExitEvent *global_exit_event= nullptr;
|
||||
GlobalSimLoopExitEvent *
|
||||
simulate(Tick num_cycles)
|
||||
{
|
||||
if (global_exit_event)//cleaning last global exit event
|
||||
global_exit_event->clean();
|
||||
std::unique_ptr<GlobalSyncEvent, DescheduleDeleter> quantum_event;
|
||||
const Tick exit_tick = num_cycles < MaxTick - curTick() ?
|
||||
curTick() + num_cycles : MaxTick;
|
||||
@@ -224,7 +227,7 @@ simulate(Tick num_cycles)
|
||||
BaseGlobalEvent *global_event = local_event->globalEvent();
|
||||
assert(global_event);
|
||||
|
||||
GlobalSimLoopExitEvent *global_exit_event =
|
||||
global_exit_event =
|
||||
dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
|
||||
assert(global_exit_event);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user