- Add support for decoding syscall names. (Brought over from the new alpha

trace code that was brought over from NetBSD.)
- Check for "syscall_with_err_pushed" as the label prior to a syscall trap
  frame rather than "Xlcall_syscall" and "Xint0x80_syscall".  We don't
  have a valid trapframe during the short range of code that those two
  symbols now cover.
- Simplify db_next_frame() to avoid duplicating the code for the different
  trap frame types.
- Don't try to trace a swapped-out process.  (Brought over from NetBSD via
  the new alpha trace code.)
This commit is contained in:
John Baldwin 2001-06-18 19:17:30 +00:00
parent 3128cdd847
commit 0865563a93
2 changed files with 122 additions and 74 deletions

View File

@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <sys/linker_set.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/user.h>
#include <machine/cpu.h>
@ -84,9 +85,10 @@ struct i386_frame {
#define INTERRUPT 2
#define SYSCALL 3
static void db_nextframe __P((struct i386_frame **, db_addr_t *));
static void db_nextframe __P((struct i386_frame **, db_addr_t *, struct proc *));
static int db_numargs __P((struct i386_frame *));
static void db_print_stack_entry __P((const char *, int, char **, int *, db_addr_t));
static void decode_syscall __P((int, struct proc *));
/*
* Figure out how many arguments were passed into the frame at "fp".
@ -141,13 +143,36 @@ db_print_stack_entry(name, narg, argnp, argp, callpc)
db_printf("\n");
}
static void
decode_syscall(number, p)
int number;
struct proc *p;
{
c_db_sym_t sym;
db_expr_t diff;
sy_call_t *f;
const char *symname;
db_printf(" (%d", number);
if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) {
f = p->p_sysent->sv_table[number].sy_call;
sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff);
if (sym != DB_SYM_NULL && diff == 0) {
db_symbol_values(sym, &symname, NULL);
db_printf(", %s, %s", p->p_sysent->sv_name, symname);
}
}
db_printf(")");
}
/*
* Figure out the next frame up in the call stack.
*/
static void
db_nextframe(fp, ip)
db_nextframe(fp, ip, p)
struct i386_frame **fp; /* in/out */
db_addr_t *ip; /* out */
struct proc *p; /* in */
{
struct trapframe *tf;
int frame_type;
@ -171,8 +196,7 @@ db_nextframe(fp, ip)
frame_type = TRAP;
} else if (!strncmp(name, "Xresume", 7)) {
frame_type = INTERRUPT;
} else if (!strcmp(name, "Xlcall_syscall") ||
!strcmp(name, "Xint0x80_syscall")) {
} else if (!strcmp(name, "syscall_with_err_pushed")) {
frame_type = SYSCALL;
}
}
@ -192,40 +216,33 @@ db_nextframe(fp, ip)
* Point to base of trapframe which is just above the
* current frame.
*/
tf = (struct trapframe *) ((int)*fp + 8);
esp = (ISPL(tf->tf_cs) == SEL_UPL) ? tf->tf_esp : (int)&tf->tf_esp;
switch (frame_type) {
case TRAP:
if (INKERNEL((int) tf)) {
eip = tf->tf_eip;
ebp = tf->tf_ebp;
db_printf(
"--- trap %#r, eip = %#r, esp = %#r, ebp = %#r ---\n",
tf->tf_trapno, eip, esp, ebp);
}
break;
case SYSCALL:
if (INKERNEL((int) tf)) {
eip = tf->tf_eip;
ebp = tf->tf_ebp;
db_printf(
"--- syscall %#r, eip = %#r, esp = %#r, ebp = %#r ---\n",
tf->tf_eax, eip, esp, ebp);
}
break;
case INTERRUPT:
if (frame_type == INTERRUPT)
tf = (struct trapframe *)((int)*fp + 12);
if (INKERNEL((int) tf)) {
eip = tf->tf_eip;
ebp = tf->tf_ebp;
db_printf(
"--- interrupt, eip = %#r, esp = %#r, ebp = %#r ---\n",
eip, esp, ebp);
else
tf = (struct trapframe *)((int)*fp + 8);
if (INKERNEL((int) tf)) {
esp = (ISPL(tf->tf_cs) == SEL_UPL) ?
tf->tf_esp : (int)&tf->tf_esp;
eip = tf->tf_eip;
ebp = tf->tf_ebp;
switch (frame_type) {
case TRAP:
db_printf("--- trap %#r", tf->tf_trapno);
break;
case SYSCALL:
db_printf("--- syscall");
decode_syscall(tf->tf_eax, p);
break;
case INTERRUPT:
db_printf("--- interrupt");
break;
default:
panic("The moon has moved again.");
}
break;
default:
break;
db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip,
esp, ebp);
}
*ip = (db_addr_t) eip;
@ -251,6 +268,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
count = 1024;
if (!have_addr) {
p = curproc;
frame = (struct i386_frame *)ddb_regs.tf_ebp;
if (frame == NULL)
frame = (struct i386_frame *)(ddb_regs.tf_esp - 4);
@ -264,6 +282,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
* so fall back to the default case.
*/
if (pid == curproc->p_pid) {
p = curproc;
frame = (struct i386_frame *)ddb_regs.tf_ebp;
if (frame == NULL)
frame = (struct i386_frame *)
@ -281,6 +300,10 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
db_printf("pid %d not found\n", pid);
return;
}
if ((p->p_sflag & PS_INMEM) == 0) {
db_printf("pid %d swapped out\n", pid);
return;
}
pcb = &p->p_addr->u_pcb;
frame = (struct i386_frame *)pcb->pcb_ebp;
if (frame == NULL)
@ -289,6 +312,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
callpc = (db_addr_t)pcb->pcb_eip;
}
} else {
p = NULL;
frame = (struct i386_frame *)addr;
callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
}
@ -372,7 +396,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
continue;
}
db_nextframe(&frame, &callpc);
db_nextframe(&frame, &callpc, p);
if (INKERNEL((int) callpc) && !INKERNEL((int) frame)) {
sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);

View File

@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <sys/linker_set.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/user.h>
#include <machine/cpu.h>
@ -84,9 +85,10 @@ struct i386_frame {
#define INTERRUPT 2
#define SYSCALL 3
static void db_nextframe __P((struct i386_frame **, db_addr_t *));
static void db_nextframe __P((struct i386_frame **, db_addr_t *, struct proc *));
static int db_numargs __P((struct i386_frame *));
static void db_print_stack_entry __P((const char *, int, char **, int *, db_addr_t));
static void decode_syscall __P((int, struct proc *));
/*
* Figure out how many arguments were passed into the frame at "fp".
@ -141,13 +143,36 @@ db_print_stack_entry(name, narg, argnp, argp, callpc)
db_printf("\n");
}
static void
decode_syscall(number, p)
int number;
struct proc *p;
{
c_db_sym_t sym;
db_expr_t diff;
sy_call_t *f;
const char *symname;
db_printf(" (%d", number);
if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) {
f = p->p_sysent->sv_table[number].sy_call;
sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff);
if (sym != DB_SYM_NULL && diff == 0) {
db_symbol_values(sym, &symname, NULL);
db_printf(", %s, %s", p->p_sysent->sv_name, symname);
}
}
db_printf(")");
}
/*
* Figure out the next frame up in the call stack.
*/
static void
db_nextframe(fp, ip)
db_nextframe(fp, ip, p)
struct i386_frame **fp; /* in/out */
db_addr_t *ip; /* out */
struct proc *p; /* in */
{
struct trapframe *tf;
int frame_type;
@ -171,8 +196,7 @@ db_nextframe(fp, ip)
frame_type = TRAP;
} else if (!strncmp(name, "Xresume", 7)) {
frame_type = INTERRUPT;
} else if (!strcmp(name, "Xlcall_syscall") ||
!strcmp(name, "Xint0x80_syscall")) {
} else if (!strcmp(name, "syscall_with_err_pushed")) {
frame_type = SYSCALL;
}
}
@ -192,40 +216,33 @@ db_nextframe(fp, ip)
* Point to base of trapframe which is just above the
* current frame.
*/
tf = (struct trapframe *) ((int)*fp + 8);
esp = (ISPL(tf->tf_cs) == SEL_UPL) ? tf->tf_esp : (int)&tf->tf_esp;
switch (frame_type) {
case TRAP:
if (INKERNEL((int) tf)) {
eip = tf->tf_eip;
ebp = tf->tf_ebp;
db_printf(
"--- trap %#r, eip = %#r, esp = %#r, ebp = %#r ---\n",
tf->tf_trapno, eip, esp, ebp);
}
break;
case SYSCALL:
if (INKERNEL((int) tf)) {
eip = tf->tf_eip;
ebp = tf->tf_ebp;
db_printf(
"--- syscall %#r, eip = %#r, esp = %#r, ebp = %#r ---\n",
tf->tf_eax, eip, esp, ebp);
}
break;
case INTERRUPT:
if (frame_type == INTERRUPT)
tf = (struct trapframe *)((int)*fp + 12);
if (INKERNEL((int) tf)) {
eip = tf->tf_eip;
ebp = tf->tf_ebp;
db_printf(
"--- interrupt, eip = %#r, esp = %#r, ebp = %#r ---\n",
eip, esp, ebp);
else
tf = (struct trapframe *)((int)*fp + 8);
if (INKERNEL((int) tf)) {
esp = (ISPL(tf->tf_cs) == SEL_UPL) ?
tf->tf_esp : (int)&tf->tf_esp;
eip = tf->tf_eip;
ebp = tf->tf_ebp;
switch (frame_type) {
case TRAP:
db_printf("--- trap %#r", tf->tf_trapno);
break;
case SYSCALL:
db_printf("--- syscall");
decode_syscall(tf->tf_eax, p);
break;
case INTERRUPT:
db_printf("--- interrupt");
break;
default:
panic("The moon has moved again.");
}
break;
default:
break;
db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip,
esp, ebp);
}
*ip = (db_addr_t) eip;
@ -251,6 +268,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
count = 1024;
if (!have_addr) {
p = curproc;
frame = (struct i386_frame *)ddb_regs.tf_ebp;
if (frame == NULL)
frame = (struct i386_frame *)(ddb_regs.tf_esp - 4);
@ -264,6 +282,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
* so fall back to the default case.
*/
if (pid == curproc->p_pid) {
p = curproc;
frame = (struct i386_frame *)ddb_regs.tf_ebp;
if (frame == NULL)
frame = (struct i386_frame *)
@ -281,6 +300,10 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
db_printf("pid %d not found\n", pid);
return;
}
if ((p->p_sflag & PS_INMEM) == 0) {
db_printf("pid %d swapped out\n", pid);
return;
}
pcb = &p->p_addr->u_pcb;
frame = (struct i386_frame *)pcb->pcb_ebp;
if (frame == NULL)
@ -289,6 +312,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
callpc = (db_addr_t)pcb->pcb_eip;
}
} else {
p = NULL;
frame = (struct i386_frame *)addr;
callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
}
@ -372,7 +396,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
continue;
}
db_nextframe(&frame, &callpc);
db_nextframe(&frame, &callpc, p);
if (INKERNEL((int) callpc) && !INKERNEL((int) frame)) {
sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);