sim: Trap into GDB instead of panicking on SEGV

When a segfault happens in the guest, report a SEGV trap to GDB (if
there is one attached) instead of bailing out immediately.

The obvious use-case for this, is the ability to debug guest crashes
in GDB in the standard manner.

The less-trivial use-case is for development of software in an
incomplete software stack (cf. Aarno-Engblom's "Virtual Platforms"
pp.105 et seq.)  One particular example is Ingalls-Miranda simulation of
JIT compilers, where the VM's address space may be split between the
simulated and the real machine: in this case, GDB traps facilitate the
transparent illusion of an unbroken address space.

Change-Id: I9072ed5f6474e05e9a99dc42ae5754be28121355
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/44685
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Boris Shingarov
2021-04-20 09:42:35 -04:00
committed by Boris Shingarov
parent a2c9213a31
commit ee58010f0d
4 changed files with 21 additions and 4 deletions

View File

@@ -47,6 +47,7 @@ class BaseRemoteGDB
bool breakpoint() { return false; }
void replaceThreadContext(ThreadContext *tc) {}
bool trap(int type) { return true; }
virtual ~BaseRemoteGDB() {}
};

View File

@@ -40,6 +40,8 @@
#include "sim/faults.hh"
#include <csignal>
#include "arch/decoder.hh"
#include "arch/locked_mem.hh"
#include "base/logging.hh"
@@ -94,15 +96,16 @@ GenericPageTableFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
Process *p = tc->getProcessPtr();
handled = p->fixupFault(vaddr);
}
panic_if(!handled, "Page table fault when accessing virtual address %#x",
vaddr);
panic_if(!handled &&
!tc->getSystemPtr()->trapToGdb(SIGSEGV, tc->contextId()),
"Page table fault when accessing virtual address %#x\n", vaddr);
}
void
GenericAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
panic("Alignment fault when accessing virtual address %#x\n", vaddr);
panic_if(!tc->getSystemPtr()->trapToGdb(SIGSEGV, tc->contextId()),
"Alignment fault when accessing virtual address %#x\n", vaddr);
}
void GenericHtmFailureFault::invoke(ThreadContext *tc,

View File

@@ -495,6 +495,16 @@ System::workItemEnd(uint32_t tid, uint32_t workid)
lastWorkItemStarted.erase(p);
}
bool
System::trapToGdb(int signal, ContextID ctx_id) const
{
auto *gdb = threads.thread(ctx_id).gdb;
if (!gdb)
return false;
gdb->trap(signal);
return true;
}
void
System::printSystems()
{

View File

@@ -561,6 +561,9 @@ class System : public SimObject, public PCEventScope
void workItemEnd(uint32_t tid, uint32_t workid);
/* Returns whether we successfully trapped into GDB. */
bool trapToGdb(int signal, ContextID ctx_id) const;
protected:
/**
* Range for memory-mapped m5 pseudo ops. The range will be