moved stacktrace to sysctl, as vmctl is very privileged so can't
be used outside VM. IS code cleanup. added stacktrace feature to IS.
This commit is contained in:
parent
3cc092ff06
commit
c628f24bc2
12 changed files with 88 additions and 112 deletions
|
@ -590,6 +590,7 @@
|
|||
#define SYSCTL_ARG1 m1_p1
|
||||
#define SYSCTL_ARG2 m1_i2
|
||||
#define SYSCTL_CODE_DIAG 1 /* Print diagnostics. */
|
||||
#define SYSCTL_CODE_STACKTRACE 2 /* Print process stack. */
|
||||
#define DIAG_BUFSIZE (80*25)
|
||||
|
||||
/* Values for SVMCTL_PARAM. */
|
||||
|
@ -600,7 +601,6 @@
|
|||
#define VMCTL_MEMREQ_GET 14
|
||||
#define VMCTL_MEMREQ_REPLY 15
|
||||
#define VMCTL_INCSP 16
|
||||
#define VMCTL_STACKTRACE 17
|
||||
#define VMCTL_NOPAGEZERO 18
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
|
@ -54,13 +54,13 @@ _PROTOTYPE( int sys_vmctl_get_pagefault_i386, (endpoint_t *who, u32_t *cr2, u32_
|
|||
_PROTOTYPE( int sys_vmctl_get_cr3_i386, (endpoint_t who, u32_t *cr3) );
|
||||
_PROTOTYPE( int sys_vmctl_get_memreq, (endpoint_t *who, vir_bytes *mem,
|
||||
vir_bytes *len, int *wrflag) );
|
||||
_PROTOTYPE( int sys_vmctl_stacktrace, (endpoint_t who));
|
||||
|
||||
|
||||
|
||||
_PROTOTYPE( int sys_readbios, (phys_bytes address, void *buf, size_t size));
|
||||
_PROTOTYPE( int sys_stime, (time_t boottime));
|
||||
_PROTOTYPE( int sys_sysctl, (int ctl, char *arg1, int arg2));
|
||||
_PROTOTYPE( int sys_sysctl_stacktrace, (endpoint_t who));
|
||||
|
||||
/* Shorthands for sys_sdevio() system call. */
|
||||
#define sys_insb(port, proc_nr, buffer, count) \
|
||||
|
|
|
@ -174,7 +174,7 @@ PUBLIC void proc_stacktrace(struct proc *proc)
|
|||
|
||||
v_bp = proc->p_reg.fp;
|
||||
|
||||
kprintf("%s / %d pc 0x%lx stack ",
|
||||
kprintf("%8.8s %6d 0x%lx ",
|
||||
proc->p_name, proc->p_endpoint, proc->p_reg.pc);
|
||||
|
||||
while(v_bp) {
|
||||
|
|
|
@ -19,8 +19,8 @@ register message *m_ptr; /* pointer to request message */
|
|||
phys_bytes ph;
|
||||
vir_bytes len, buf;
|
||||
static char mybuf[DIAG_BUFSIZE];
|
||||
struct proc *caller;
|
||||
int s, i;
|
||||
struct proc *caller, *target;
|
||||
int s, i, proc_nr;
|
||||
|
||||
caller = proc_addr(who_p);
|
||||
|
||||
|
@ -45,7 +45,11 @@ register message *m_ptr; /* pointer to request message */
|
|||
kputc(mybuf[i]);
|
||||
kputc(END_OF_KMESS);
|
||||
return OK;
|
||||
break;
|
||||
case SYSCTL_CODE_STACKTRACE:
|
||||
if(!isokendpt(m_ptr->SYSCTL_ARG2, &proc_nr))
|
||||
return EINVAL;
|
||||
proc_stacktrace(proc_addr(proc_nr));
|
||||
return OK;
|
||||
default:
|
||||
kprintf("do_sysctl: invalid request %d\n", m_ptr->SYSCTL_CODE);
|
||||
return(EINVAL);
|
||||
|
|
|
@ -97,10 +97,6 @@ kprintf("SYSTEM: request %d:0x%lx-0x%lx, wrflag %d, failed\n",
|
|||
case VMCTL_NOPAGEZERO:
|
||||
return OK;
|
||||
#endif
|
||||
case VMCTL_STACKTRACE:
|
||||
kprintf("vmctl stacktrace ");
|
||||
proc_stacktrace(p);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Try architecture-specific vmctls. */
|
||||
|
|
|
@ -12,3 +12,9 @@ PUBLIC int sys_sysctl(int code, char *arg1, int arg2)
|
|||
return(_taskcall(SYSTASK, SYS_SYSCTL, &m));
|
||||
|
||||
}
|
||||
|
||||
PUBLIC int sys_sysctl_stacktrace(endpoint_t ep)
|
||||
{
|
||||
return sys_sysctl(SYSCTL_CODE_STACKTRACE, NULL, ep);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,3 @@ PUBLIC int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem,
|
|||
return r;
|
||||
}
|
||||
|
||||
PUBLIC int sys_vmctl_stacktrace(endpoint_t who)
|
||||
{
|
||||
return sys_vmctl(who, VMCTL_STACKTRACE, 0);
|
||||
}
|
||||
|
|
|
@ -9,16 +9,11 @@
|
|||
|
||||
#include "inc.h"
|
||||
|
||||
/* Define hooks for the debugging dumps. This table maps function keys
|
||||
* onto a specific dump and provides a description for it.
|
||||
*/
|
||||
#define NHOOKS 18
|
||||
|
||||
struct hook_entry {
|
||||
int key;
|
||||
void (*function)(void);
|
||||
char *name;
|
||||
} hooks[NHOOKS] = {
|
||||
} hooks[] = {
|
||||
{ F1, proctab_dmp, "Kernel process table" },
|
||||
{ F2, memmap_dmp, "Process memory maps" },
|
||||
{ F3, image_dmp, "System image" },
|
||||
|
@ -36,8 +31,14 @@ struct hook_entry {
|
|||
{ SF5, mapping_dmp, "Print key mappings" },
|
||||
{ SF6, rproc_dmp, "Reincarnation server process table" },
|
||||
{ SF8, data_store_dmp, "Data store contents" },
|
||||
{ SF9, procstack_dmp, "Processes with stack traces" },
|
||||
};
|
||||
|
||||
/* Define hooks for the debugging dumps. This table maps function keys
|
||||
* onto a specific dump and provides a description for it.
|
||||
*/
|
||||
#define NHOOKS (sizeof(hooks)/sizeof(hooks[0]))
|
||||
|
||||
/*===========================================================================*
|
||||
* handle_fkey *
|
||||
*===========================================================================*/
|
||||
|
|
|
@ -15,6 +15,27 @@
|
|||
|
||||
#define LINES 22
|
||||
|
||||
#define PRINTRTS(rp) { \
|
||||
char *procname = ""; \
|
||||
printf(" %s", p_rts_flags_str(rp->p_rts_flags)); \
|
||||
if (rp->p_rts_flags & (SENDING|RECEIVING)) { \
|
||||
procname = proc_name(_ENDPOINT_P(rp->p_getfrom_e)); \
|
||||
} \
|
||||
printf(" %-7.7s", procname); \
|
||||
}
|
||||
|
||||
static int pagelines;
|
||||
|
||||
#define PROCLOOP(rp, oldrp) \
|
||||
pagelines = 0; \
|
||||
for (rp = oldrp; rp < END_PROC_ADDR; rp++) { \
|
||||
oldrp = BEG_PROC_ADDR; \
|
||||
if (isemptyp(rp)) continue; \
|
||||
if (++pagelines > LINES) { oldrp = rp; printf("--more--\n"); break; }\
|
||||
if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp)); \
|
||||
else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp)); \
|
||||
else printf(" %2d ", proc_nr(rp));
|
||||
|
||||
#define click_to_round_k(n) \
|
||||
((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
|
||||
|
||||
|
@ -344,12 +365,7 @@ PUBLIC void privileges_dmp()
|
|||
|
||||
printf("\n--nr-id-name---- -flags- -traps- grants -ipc_to-- -ipc_sr-- -system calls--\n");
|
||||
|
||||
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
|
||||
if (isemptyp(rp)) continue;
|
||||
if (++n > LINES) break;
|
||||
if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
|
||||
else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
|
||||
else printf(" %2d ", proc_nr(rp));
|
||||
PROCLOOP(rp, oldrp)
|
||||
r = -1;
|
||||
for (sp = &priv[0]; sp < &priv[NR_SYS_PROCS]; sp++)
|
||||
if (sp->s_proc_nr == rp->p_nr) { r ++; break; }
|
||||
|
@ -374,58 +390,6 @@ PUBLIC void privileges_dmp()
|
|||
printf("\n");
|
||||
|
||||
}
|
||||
if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
|
||||
oldrp = rp;
|
||||
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* sendmask_dmp *
|
||||
*===========================================================================*/
|
||||
PUBLIC void sendmask_dmp()
|
||||
{
|
||||
register struct proc *rp;
|
||||
static struct proc *oldrp = BEG_PROC_ADDR;
|
||||
int r, i,j, n = 0;
|
||||
|
||||
/* First obtain a fresh copy of the current process table. */
|
||||
if ((r = sys_getproctab(proc)) != OK) {
|
||||
report("IS","warning: couldn't get copy of process table", r);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
printf("Sendmask dump for process table. User processes (*) don't have [].");
|
||||
printf("\n");
|
||||
printf("The rows of bits indicate to which processes each process may send.");
|
||||
printf("\n\n");
|
||||
|
||||
#if DEAD_CODE
|
||||
printf(" ");
|
||||
for (j=proc_nr(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) {
|
||||
printf("%3d", j);
|
||||
}
|
||||
printf(" *\n");
|
||||
|
||||
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
|
||||
if (isemptyp(rp)) continue;
|
||||
if (++n > LINES) break;
|
||||
|
||||
printf("%8s ", rp->p_name);
|
||||
if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
|
||||
else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
|
||||
else printf(" %2d ", proc_nr(rp));
|
||||
|
||||
for (j=proc_nr(BEG_PROC_ADDR); j<INIT_PROC_NR+2; j++) {
|
||||
if (isallowed(rp->p_sendmask, j)) printf(" 1 ");
|
||||
else printf(" 0 ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (rp == END_PROC_ADDR) { printf("\n"); rp = BEG_PROC_ADDR; }
|
||||
else printf("--more--\r");
|
||||
oldrp = rp;
|
||||
#endif
|
||||
}
|
||||
|
||||
PRIVATE char *p_rts_flags_str(int flags)
|
||||
|
@ -464,33 +428,48 @@ PUBLIC void proctab_dmp()
|
|||
|
||||
printf("\n-nr-----gen---endpoint-name--- -prior-quant- -user----sys--rts flags\n");
|
||||
|
||||
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
|
||||
if (isemptyp(rp)) continue;
|
||||
if (++n > LINES) break;
|
||||
PROCLOOP(rp, oldrp)
|
||||
text = rp->p_memmap[T].mem_phys;
|
||||
data = rp->p_memmap[D].mem_phys;
|
||||
size = rp->p_memmap[T].mem_len
|
||||
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data);
|
||||
if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp));
|
||||
else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp));
|
||||
else printf(" %2d ", proc_nr(rp));
|
||||
printf(" %5d %10d ", _ENDPOINT_G(rp->p_endpoint), rp->p_endpoint);
|
||||
printf("%-8.8s %02u/%02u %02d/%02u %6lu %6lu %s",
|
||||
printf("%-8.8s %02u/%02u %02d/%02u %6lu %6lu",
|
||||
rp->p_name,
|
||||
rp->p_priority, rp->p_max_priority,
|
||||
rp->p_ticks_left, rp->p_quantum_size,
|
||||
rp->p_user_time, rp->p_sys_time,
|
||||
p_rts_flags_str(rp->p_rts_flags));
|
||||
if (rp->p_rts_flags & (SENDING|RECEIVING)) {
|
||||
printf(" %-7.7s", proc_name(_ENDPOINT_P(rp->p_getfrom_e)));
|
||||
}
|
||||
rp->p_user_time, rp->p_sys_time);
|
||||
PRINTRTS(rp);
|
||||
printf("\n");
|
||||
}
|
||||
if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
|
||||
oldrp = rp;
|
||||
}
|
||||
#endif /* (CHIP == INTEL) */
|
||||
|
||||
/*===========================================================================*
|
||||
* procstack_dmp *
|
||||
*===========================================================================*/
|
||||
PUBLIC void procstack_dmp()
|
||||
{
|
||||
/* Proc table dump, with stack */
|
||||
|
||||
register struct proc *rp;
|
||||
static struct proc *oldrp = BEG_PROC_ADDR;
|
||||
int r, n = 0;
|
||||
|
||||
/* First obtain a fresh copy of the current process table. */
|
||||
if ((r = sys_getproctab(proc)) != OK) {
|
||||
report("IS","warning: couldn't get copy of process table", r);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\n-nr-rts flags-- --stack--\n");
|
||||
|
||||
PROCLOOP(rp, oldrp)
|
||||
PRINTRTS(rp);
|
||||
sys_sysctl_stacktrace(rp->p_endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* memmap_dmp *
|
||||
*===========================================================================*/
|
||||
|
@ -508,14 +487,11 @@ PUBLIC void memmap_dmp()
|
|||
}
|
||||
|
||||
printf("\n-nr/name--- --pc-- --sp-- -text---- -data---- -stack--- -cr3-\n");
|
||||
for (rp = oldrp; rp < END_PROC_ADDR; rp++) {
|
||||
if (isemptyp(rp)) continue;
|
||||
if (++n > LINES) break;
|
||||
PROCLOOP(rp, oldrp)
|
||||
size = rp->p_memmap[T].mem_len
|
||||
+ ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len)
|
||||
- rp->p_memmap[D].mem_phys);
|
||||
printf("%3d %-7.7s%7lx %8lx %4x %4x %4x %4x %5x %5x %8lx\n",
|
||||
proc_nr(rp),
|
||||
printf("%-7.7s%7lx %8lx %4x %4x %4x %4x %5x %5x %8lx\n",
|
||||
rp->p_name,
|
||||
(unsigned long) rp->p_reg.pc,
|
||||
(unsigned long) rp->p_reg.sp,
|
||||
|
@ -524,9 +500,6 @@ PUBLIC void memmap_dmp()
|
|||
rp->p_memmap[S].mem_phys, rp->p_memmap[S].mem_len,
|
||||
rp->p_seg.p_cr3);
|
||||
}
|
||||
if (rp == END_PROC_ADDR) rp = proc;
|
||||
else printf("--more--\r");
|
||||
oldrp = rp;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -535,12 +508,12 @@ PUBLIC void memmap_dmp()
|
|||
PRIVATE char *proc_name(proc_nr)
|
||||
int proc_nr;
|
||||
{
|
||||
struct proc *p;
|
||||
if (proc_nr == ANY) return "ANY";
|
||||
/*
|
||||
if(proc_nr < 0 || proc_nr >= NR_TASKS+NR_PROCS) {
|
||||
return "BAD";
|
||||
}
|
||||
*/
|
||||
return cproc_addr(proc_nr)->p_name;
|
||||
if (proc_nr == NONE) return "NONE"; /* bogus */
|
||||
if (proc_nr < -NR_TASKS || proc_nr >= NR_PROCS) return "BOGUS";
|
||||
p = cproc_addr(proc_nr);
|
||||
if (isemptyp(p)) return "EMPTY"; /* bogus */
|
||||
return p->p_name;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,10 +91,10 @@ PRIVATE void init_server(int argc, char **argv)
|
|||
if (sigaction(SIGTERM, &sigact, NULL) < 0)
|
||||
report("IS","warning, sigaction() failed", errno);
|
||||
|
||||
/* Set key mappings. IS takes all of F1-F12 and Shift+F1-F6. */
|
||||
/* Set key mappings. IS takes all of F1-F12 and Shift+F1-F10. */
|
||||
fkeys = sfkeys = 0;
|
||||
for (i=1; i<=12; i++) bit_set(fkeys, i);
|
||||
for (i=1; i<= 8; i++) bit_set(sfkeys, i);
|
||||
for (i=1; i<=10; i++) bit_set(sfkeys, i);
|
||||
if ((s=fkey_map(&fkeys, &sfkeys)) != OK)
|
||||
report("IS", "warning, fkey_map failed:", s);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ _PROTOTYPE( void mapping_dmp, (void) );
|
|||
|
||||
/* dmp_kernel.c */
|
||||
_PROTOTYPE( void proctab_dmp, (void) );
|
||||
_PROTOTYPE( void procstack_dmp, (void) );
|
||||
_PROTOTYPE( void memmap_dmp, (void) );
|
||||
_PROTOTYPE( void privileges_dmp, (void) );
|
||||
_PROTOTYPE( void sendmask_dmp, (void) );
|
||||
_PROTOTYPE( void image_dmp, (void) );
|
||||
_PROTOTYPE( void irqtab_dmp, (void) );
|
||||
_PROTOTYPE( void kmessages_dmp, (void) );
|
||||
|
|
|
@ -72,7 +72,7 @@ PUBLIC void handle_pagefaults(void)
|
|||
vm_assert(PFERR_NOPAGE(err));
|
||||
printf("VM: pagefault: SIGSEGV %d bad addr 0x%lx %s\n",
|
||||
ep, arch_map2vir(vmp, addr), pf_errstr(err));
|
||||
sys_vmctl_stacktrace(vmp->vm_endpoint);
|
||||
sys_sysctl_stacktrace(vmp->vm_endpoint);
|
||||
if((s=sys_kill(vmp->vm_endpoint, SIGSEGV)) != OK)
|
||||
vm_panic("sys_kill failed", s);
|
||||
continue;
|
||||
|
@ -87,7 +87,7 @@ PUBLIC void handle_pagefaults(void)
|
|||
if(!(region->flags & VR_WRITABLE) && wr) {
|
||||
printf("VM: pagefault: SIGSEGV %d ro map 0x%lx %s\n",
|
||||
ep, arch_map2vir(vmp, addr), pf_errstr(err));
|
||||
sys_vmctl_stacktrace(vmp->vm_endpoint);
|
||||
sys_sysctl_stacktrace(vmp->vm_endpoint);
|
||||
if((s=sys_kill(vmp->vm_endpoint, SIGSEGV)) != OK)
|
||||
vm_panic("sys_kill failed", s);
|
||||
continue;
|
||||
|
@ -99,7 +99,7 @@ PUBLIC void handle_pagefaults(void)
|
|||
/* Access is allowed; handle it. */
|
||||
if((r=map_pagefault(vmp, region, offset, wr)) != OK) {
|
||||
printf("VM: pagefault: SIGSEGV %d pagefault not handled\n", ep);
|
||||
sys_vmctl_stacktrace(vmp->vm_endpoint);
|
||||
sys_sysctl_stacktrace(vmp->vm_endpoint);
|
||||
if((s=sys_kill(vmp->vm_endpoint, SIGSEGV)) != OK)
|
||||
vm_panic("sys_kill failed", s);
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue