Remote debugging cleanup and internal debugging support

base/kgdb.h:
    Remove flags that aren't used
base/remote_gdb.cc:
    Better debugging:
    - Give each class a name() function so that the trace infrastructure
    knows the correct object name.
    - Make the remote debugger capable of detach.
    - Split out the RGDB trace flag into a bunch of specific flags.
    Remove dead code
    Add a new trap type
base/remote_gdb.hh:
    Add a name() to the various objects for the trace system
base/trace.hh:
    don't need a using directive
    add DPRINTFNR: debug printf, no flag, raw output
kern/tru64/tru64_system.cc:
    use the INT trap type instead of IF

--HG--
extra : convert_revision : 25e610216c6f43d5d328651bba915f71bade059e
This commit is contained in:
Nathan Binkert 2004-02-03 10:50:04 -05:00
parent 2f369ee5d5
commit b1221a3395
5 changed files with 84 additions and 90 deletions

View file

@ -172,32 +172,4 @@
#define ALPHA_KENTRY_UNA 4 #define ALPHA_KENTRY_UNA 4
#define ALPHA_KENTRY_SYS 5 #define ALPHA_KENTRY_SYS 5
/*
* MMCSR Fault Type Codes. [OSF/1 PALcode Specific]
*/
#define ALPHA_MMCSR_INVALTRANS 0
#define ALPHA_MMCSR_ACCESS 1
#define ALPHA_MMCSR_FOR 2
#define ALPHA_MMCSR_FOE 3
#define ALPHA_MMCSR_FOW 4
/*
* Instruction Fault Type Codes. [OSF/1 PALcode Specific]
*/
#define ALPHA_IF_CODE_BPT 0
#define ALPHA_IF_CODE_BUGCHK 1
#define ALPHA_IF_CODE_GENTRAP 2
#define ALPHA_IF_CODE_FEN 3
#define ALPHA_IF_CODE_OPDEC 4
#define BKPT_INST 0x00000080 // breakpoint instruction
#define BKPT_SIZE (4) // size of breakpoint inst
#define IS_BREAKPOINT_TRAP(type, code) ((type) == ALPHA_KENTRY_IF && \
(code) == ALPHA_IF_CODE_BPT)
#define IS_WATCHPOINT_TRAP(type, code) 0
#endif /* __KGDB_H__ */ #endif /* __KGDB_H__ */

View file

@ -171,11 +171,17 @@ GDBListener::~GDBListener()
delete event; delete event;
} }
string
GDBListener::name()
{
return gdb->name() + ".listener";
}
void void
GDBListener::listen() GDBListener::listen()
{ {
while (!listener.listen(port, true)) { while (!listener.listen(port, true)) {
DPRINTF(RGDB, "GDBListener(listen): Can't bind port %d\n", port); DPRINTF(GDBMisc, "Can't bind port %d\n", port);
port++; port++;
} }
@ -188,7 +194,7 @@ void
GDBListener::accept() GDBListener::accept()
{ {
if (!listener.islistening()) if (!listener.islistening())
panic("GDBListener(accept): cannot accept a connection if we're not listening!"); panic("GDBListener::accept(): cannot accept if we're not listening!");
int sfd = listener.accept(true); int sfd = listener.accept(true);
@ -216,7 +222,12 @@ RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e)
void void
RemoteGDB::Event::process(int revent) RemoteGDB::Event::process(int revent)
{ gdb->trap(ALPHA_KENTRY_IF); } {
if (revent & POLLIN)
gdb->trap(ALPHA_KENTRY_IF);
else if (revent & POLLNVAL)
gdb->detach();
}
RemoteGDB::RemoteGDB(System *_system, ExecContext *c) RemoteGDB::RemoteGDB(System *_system, ExecContext *c)
: event(NULL), fd(-1), active(false), attached(false), : event(NULL), fd(-1), active(false), attached(false),
@ -231,6 +242,12 @@ RemoteGDB::~RemoteGDB()
delete event; delete event;
} }
string
RemoteGDB::name()
{
return system->name() + ".remote_gdb";
}
bool bool
RemoteGDB::isattached() RemoteGDB::isattached()
{ return attached; } { return attached; }
@ -316,17 +333,17 @@ RemoteGDB::acc(Addr va, size_t len)
do { do {
if (va < ALPHA_K0SEG_BASE) { if (va < ALPHA_K0SEG_BASE) {
DPRINTF(RGDB, "RGDB(acc): Mapping is invalid %#x < K0SEG\n", va); DPRINTF(GDBAcc, "acc: Mapping is invalid %#x < K0SEG\n", va);
return false; return false;
} }
if (va < ALPHA_K1SEG_BASE) { if (va < ALPHA_K1SEG_BASE) {
if (va < (ALPHA_K0SEG_BASE + pmem->getSize())) { if (va < (ALPHA_K0SEG_BASE + pmem->getSize())) {
DPRINTF(RGDB, "RGDB(acc): Mapping is valid K0SEG <= " DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
"%#x < K0SEG + size\n", va); "%#x < K0SEG + size\n", va);
return true; return true;
} else { } else {
DPRINTF(RGDB, "RGDB(acc): Mapping is invalid %#x < K0SEG\n", DPRINTF(GDBAcc, "acc: Mapping is invalid %#x < K0SEG\n",
va); va);
return false; return false;
} }
@ -335,13 +352,13 @@ RemoteGDB::acc(Addr va, size_t len)
Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20]; Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20];
pte = kernel_pte_lookup(pmem, ptbr, va); pte = kernel_pte_lookup(pmem, ptbr, va);
if (!pte || !entry_valid(pmem->phys_read_qword(pte))) { if (!pte || !entry_valid(pmem->phys_read_qword(pte))) {
DPRINTF(RGDB, "RGDB(acc): %#x pte is invalid\n", va); DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
return false; return false;
} }
va += ALPHA_PGBYTES; va += ALPHA_PGBYTES;
} while (va < last_va); } while (va < last_va);
DPRINTF(RGDB, "RGDB(acc): %#x mapping is valid\n", va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
return true; return true;
} }
@ -355,6 +372,9 @@ int
RemoteGDB::signal(int type) RemoteGDB::signal(int type)
{ {
switch (type) { switch (type) {
case ALPHA_KENTRY_INT:
return (SIGTRAP);
case ALPHA_KENTRY_UNA: case ALPHA_KENTRY_UNA:
return (SIGBUS); return (SIGBUS);
@ -399,7 +419,8 @@ RemoteGDB::getregs()
void void
RemoteGDB::setregs() RemoteGDB::setregs()
{ {
memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0], 32 * sizeof(uint64_t)); memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0],
32 * sizeof(uint64_t));
#ifdef KGDB_FP_REGS #ifdef KGDB_FP_REGS
memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0], memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0],
32 * sizeof(uint64_t)); 32 * sizeof(uint64_t));
@ -410,7 +431,7 @@ RemoteGDB::setregs()
void void
RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
{ {
DPRINTF(RGDB, "RGDB(setTempBreakpoint): addr=%#x\n", addr); DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr);
bkpt.address = addr; bkpt.address = addr;
insertHardBreak(addr, 4); insertHardBreak(addr, 4);
@ -419,7 +440,7 @@ RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
void void
RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
{ {
DPRINTF(RGDB, "RGDB(setTempBreakpoint): addr=%#x\n", DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n",
bkpt.address); bkpt.address);
@ -430,7 +451,7 @@ RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
void void
RemoteGDB::clearSingleStep() RemoteGDB::clearSingleStep()
{ {
DPRINTF(RGDB, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
takenBkpt.address, notTakenBkpt.address); takenBkpt.address, notTakenBkpt.address);
if (takenBkpt.address != 0) if (takenBkpt.address != 0)
@ -460,7 +481,7 @@ RemoteGDB::setSingleStep()
set_bt = true; set_bt = true;
} }
DPRINTF(RGDB, "setSingleStep bt_addr=%#x nt_addr=%#x\n", DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
takenBkpt.address, notTakenBkpt.address); takenBkpt.address, notTakenBkpt.address);
setTempBreakpoint(notTakenBkpt, npc); setTempBreakpoint(notTakenBkpt, npc);
@ -494,7 +515,7 @@ RemoteGDB::send(const char *bp)
const char *p; const char *p;
uint8_t csum, c; uint8_t csum, c;
// DPRINTF(RGDB, "RGDB(send): %s\n", bp); DPRINTF(GDBSend, "send: %s\n", bp);
do { do {
p = bp; p = bp;
@ -554,7 +575,7 @@ RemoteGDB::recv(char *bp, int maxlen)
putbyte(KGDB_BADP); putbyte(KGDB_BADP);
} while (1); } while (1);
// DPRINTF(RGDB, "RGDB(recv): %s: %s\n", gdb_command(*bp), bp); DPRINTF(GDBRecv, "recv: %s: %s\n", gdb_command(*bp), bp);
return (len); return (len);
} }
@ -569,11 +590,11 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data)
uint8_t *maddr; uint8_t *maddr;
if (vaddr < 10) { if (vaddr < 10) {
DPRINTF(RGDB, "\nRGDB(read): reading memory location zero!\n"); DPRINTF(GDBRead, "read: reading memory location zero!\n");
vaddr = lastaddr + lastsize; vaddr = lastaddr + lastsize;
} }
DPRINTF(RGDB, "RGDB(read): addr=%#x, size=%d", vaddr, size); DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
#if TRACING_ON #if TRACING_ON
char *d = data; char *d = data;
size_t s = size; size_t s = size;
@ -607,10 +628,13 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data)
} }
#if TRACING_ON #if TRACING_ON
if (DTRACE(RGDB)) { if (DTRACE(GDBRead)) {
char buf[1024]; if (DTRACE(GDBExtra)) {
mem2hex(buf, d, s); char buf[1024];
cprintf(": %s\n", buf); mem2hex(buf, d, s);
DPRINTFNR(": %s\n", buf);
} else
DPRINTFNR("\n");
} }
#endif #endif
@ -627,14 +651,18 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
uint8_t *maddr; uint8_t *maddr;
if (vaddr < 10) { if (vaddr < 10) {
DPRINTF(RGDB, "RGDB(write): writing memory location zero!\n"); DPRINTF(GDBWrite, "write: writing memory location zero!\n");
vaddr = lastaddr + lastsize; vaddr = lastaddr + lastsize;
} }
if (DTRACE(RGDB)) { if (DTRACE(GDBWrite)) {
char buf[1024]; DPRINTFN("write: addr=%#x, size=%d", vaddr, size);
mem2hex(buf, data, size); if (DTRACE(GDBExtra)) {
cprintf("RGDB(write): addr=%#x, size=%d: %s\n", vaddr, size, buf); char buf[1024];
mem2hex(buf, data, size);
DPRINTFNR(": %s\n", buf);
} else
DPRINTFNR("\n");
} }
lastaddr = vaddr; lastaddr = vaddr;
@ -682,17 +710,17 @@ RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
: PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
gdb(_gdb), refcount(0) gdb(_gdb), refcount(0)
{ {
DPRINTF(RGDB, "creating hardware breakpoint at %#x\n", evpc); DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
schedule(); schedule();
} }
void void
RemoteGDB::HardBreakpoint::process(ExecContext *xc) RemoteGDB::HardBreakpoint::process(ExecContext *xc)
{ {
DPRINTF(RGDB, "handling hardware breakpoint at %#x\n", pc()); DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
if (xc == gdb->context) if (xc == gdb->context)
gdb->trap(ALPHA_KENTRY_IF); gdb->trap(ALPHA_KENTRY_INT);
} }
bool bool
@ -719,7 +747,7 @@ RemoteGDB::insertHardBreak(Addr addr, size_t len)
if (len != sizeof(MachInst)) if (len != sizeof(MachInst))
panic("invalid length\n"); panic("invalid length\n");
DPRINTF(RGDB, "inserting hardware breakpoint at %#x\n", addr); DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr);
HardBreakpoint *&bkpt = hardBreakMap[addr]; HardBreakpoint *&bkpt = hardBreakMap[addr];
if (bkpt == 0) if (bkpt == 0)
@ -728,19 +756,6 @@ RemoteGDB::insertHardBreak(Addr addr, size_t len)
bkpt->refcount++; bkpt->refcount++;
return true; return true;
#if 0
break_iter_t i = hardBreakMap.find(addr);
if (i == hardBreakMap.end()) {
HardBreakpoint *bkpt = new HardBreakpoint(this, addr);
hardBreakMap[addr] = bkpt;
i = hardBreakMap.insert(make_pair(addr, bkpt));
if (i == hardBreakMap.end())
return false;
}
(*i).second->refcount++;
#endif
} }
bool bool
@ -749,7 +764,7 @@ RemoteGDB::removeHardBreak(Addr addr, size_t len)
if (len != sizeof(MachInst)) if (len != sizeof(MachInst))
panic("invalid length\n"); panic("invalid length\n");
DPRINTF(RGDB, "removing hardware breakpoint at %#x\n", addr); DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr);
break_iter_t i = hardBreakMap.find(addr); break_iter_t i = hardBreakMap.find(addr);
if (i == hardBreakMap.end()) if (i == hardBreakMap.end())
@ -798,7 +813,7 @@ RemoteGDB::trap(int type)
if (!attached) if (!attached)
return false; return false;
DPRINTF(RGDB, "RGDB(trap): PC=%#x NPC=%#x\n", DPRINTF(GDBMisc, "trap: PC=%#x NPC=%#x\n",
context->regs.pc, context->regs.npc); context->regs.pc, context->regs.npc);
clearSingleStep(); clearSingleStep();
@ -813,17 +828,12 @@ RemoteGDB::trap(int type)
* After the debugger is "active" (connected) it will be * After the debugger is "active" (connected) it will be
* waiting for a "signaled" message from us. * waiting for a "signaled" message from us.
*/ */
if (!active) { if (!active)
if (!IS_BREAKPOINT_TRAP(type, 0)) {
// No debugger active -- let trap handle this.
return false;
}
active = true; active = true;
} else { else
// Tell remote host that an exception has occurred. // Tell remote host that an exception has occurred.
sprintf((char *)buffer, "S%02x", signal(type)); sprintf((char *)buffer, "S%02x", signal(type));
send(buffer); send(buffer);
}
// Stick frame regs into our reg cache. // Stick frame regs into our reg cache.
getregs(); getregs();
@ -1000,7 +1010,7 @@ RemoteGDB::trap(int type)
if (*p++ != ',') send("E0D"); if (*p++ != ',') send("E0D");
len = hex2i(&p); len = hex2i(&p);
DPRINTF(RGDB, "kgdb: clear %s, addr=%#x, len=%d\n", DPRINTF(GDBMisc, "clear %s, addr=%#x, len=%d\n",
break_type(subcmd), val, len); break_type(subcmd), val, len);
ret = false; ret = false;
@ -1032,7 +1042,7 @@ RemoteGDB::trap(int type)
if (*p++ != ',') send("E0D"); if (*p++ != ',') send("E0D");
len = hex2i(&p); len = hex2i(&p);
DPRINTF(RGDB, "kgdb: set %s, addr=%#x, len=%d\n", DPRINTF(GDBMisc, "set %s, addr=%#x, len=%d\n",
break_type(subcmd), val, len); break_type(subcmd), val, len);
ret = false; ret = false;
@ -1077,15 +1087,15 @@ RemoteGDB::trap(int type)
case KGDB_TARGET_EXIT: case KGDB_TARGET_EXIT:
case KGDB_BINARY_DLOAD: case KGDB_BINARY_DLOAD:
// Unsupported command // Unsupported command
DPRINTF(RGDB, "kgdb: Unsupported command: %s\n", DPRINTF(GDBMisc, "Unsupported command: %s\n",
gdb_command(command)); gdb_command(command));
DDUMP(RGDB, (uint8_t *)data, datalen); DDUMP(GDBMisc, (uint8_t *)data, datalen);
send(""); send("");
continue; continue;
default: default:
// Unknown command. // Unknown command.
DPRINTF(RGDB, "kgdb: Unknown command: %c(%#x)\n", DPRINTF(GDBMisc, "Unknown command: %c(%#x)\n",
command, command); command, command);
send(""); send("");
continue; continue;

View file

@ -116,9 +116,12 @@ class RemoteGDB
RemoteGDB *gdb; RemoteGDB *gdb;
public: public:
HardBreakpoint(RemoteGDB *_gdb, Addr addr);
int refcount; int refcount;
public:
HardBreakpoint(RemoteGDB *_gdb, Addr addr);
std::string name() { return gdb->name() + ".hwbkpt"; }
virtual void process(ExecContext *xc); virtual void process(ExecContext *xc);
}; };
friend class HardBreakpoint; friend class HardBreakpoint;
@ -145,6 +148,9 @@ class RemoteGDB
void clearTempBreakpoint(TempBreakpoint &bkpt); void clearTempBreakpoint(TempBreakpoint &bkpt);
void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr);
public:
std::string name();
}; };
template <class T> template <class T>
@ -188,6 +194,7 @@ class GDBListener
void accept(); void accept();
void listen(); void listen();
std::string name();
}; };
#endif /* __REMOTE_GDB_H__ */ #endif /* __REMOTE_GDB_H__ */

View file

@ -179,9 +179,8 @@ std::ostream &DebugOut();
#define DDUMP(x, data, count) \ #define DDUMP(x, data, count) \
do { \ do { \
using namespace Trace; \
if (Trace::IsOn(Trace::x)) \ if (Trace::IsOn(Trace::x)) \
rawDump(data, count); \ Trace::rawDump(data, count); \
} while (0) } while (0)
#define __dprintf(cycle, name, format, args...) \ #define __dprintf(cycle, name, format, args...) \
@ -204,6 +203,11 @@ do { \
__dprintf(curTick, name(), args, cp::ArgListNull()); \ __dprintf(curTick, name(), args, cp::ArgListNull()); \
} while (0) } while (0)
#define DPRINTFNR(args...) \
do { \
__dprintf((Tick)-1, string(), args, cp::ArgListNull()); \
} while (0)
#else // !TRACING_ON #else // !TRACING_ON
#define DTRACE(x) (false) #define DTRACE(x) (false)
@ -211,6 +215,7 @@ do { \
#define DPRINTF(x, args...) do {} while (0) #define DPRINTF(x, args...) do {} while (0)
#define DPRINTFR(args...) do {} while (0) #define DPRINTFR(args...) do {} while (0)
#define DPRINTFN(args...) do {} while (0) #define DPRINTFN(args...) do {} while (0)
#define DPRINTFNR(args...) do {} while (0)
#define DDUMP(x, data, count) do {} while (0) #define DDUMP(x, data, count) do {} while (0)
#endif // TRACING_ON #endif // TRACING_ON

View file

@ -601,7 +601,7 @@ Tru64System::replaceExecContext(ExecContext *xc, int xcIndex)
bool bool
Tru64System::breakpoint() Tru64System::breakpoint()
{ {
return remoteGDB[0]->trap(ALPHA_KENTRY_IF); return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
} }
#ifdef FS_MEASURE #ifdef FS_MEASURE