Example #1
0
void
db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
    const char *modif, void (*pr)(const char *, ...))
{
#ifndef DDB_TRACE
	struct pcb *pcb;
	struct proc *p;
	struct lwp *l;

	if (!have_addr) {
		stacktrace_subr(ddb_regs.f_regs[_R_A0],
				ddb_regs.f_regs[_R_A1],
				ddb_regs.f_regs[_R_A2],
				ddb_regs.f_regs[_R_A3],
				ddb_regs.f_regs[_R_PC],
				ddb_regs.f_regs[_R_SP],
				/* non-virtual frame pointer */
				ddb_regs.f_regs[_R_S8],
				ddb_regs.f_regs[_R_RA],
				pr);
		return;
	}

	/* "trace/t" */
	(*pr)("pid %d ", (int)addr);
	p = p_find(addr, PFIND_LOCKED);
	if (p == NULL) {
		(*pr)("not found\n");
		return;
	}	
	l = LIST_FIRST(&p->p_lwps); /* XXX NJWLWP */
	if (!(l->l_flag & LW_INMEM)) {
		(*pr)("swapped out\n");
		return;
	}

	pcb = &(l->l_addr->u_pcb);
	(*pr)("at %p\n", pcb);

	stacktrace_subr(0,0,0,0,	/* no args known */
			(int)cpu_switchto,
			pcb->pcb_context[8],
			pcb->pcb_context[9],
			pcb->pcb_context[10],
			pr);
#else
/*
 * Incomplete but practically useful stack backtrace.
 */
#define	MIPS_JR_RA	0x03e00008	/* instruction code for jr ra */
#define	MIPS_JR_K0	0x03400008	/* instruction code for jr k0 */
#define	MIPS_ERET	0x42000018	/* instruction code for eret */
	unsigned va, pc, ra, sp, func;
	int insn;
	InstFmt i;
	int stacksize;
	db_addr_t offset;
	const char *name;
	extern char verylocore[];

	pc = ddb_regs.f_regs[_R_PC];
	sp = ddb_regs.f_regs[_R_SP];
	ra = ddb_regs.f_regs[_R_RA];
	do {
		va = pc;
		do {
			va -= sizeof(int);
			insn = *(int *)va;
			if (insn == MIPS_ERET)
				goto mips3_eret;
		} while (insn != MIPS_JR_RA && insn != MIPS_JR_K0);
		va += sizeof(int);
	mips3_eret:
		va += sizeof(int);
		while (*(int *)va == 0x00000000)
			va += sizeof(int);
		func = va;
		stacksize = 0;
		do {
			i.word = *(int *)va;
			if (i.IType.op == OP_SW
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_RA)
				ra = *(int *)(sp + (short)i.IType.imm);
			if (i.IType.op == OP_ADDIU
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_SP)
				stacksize = -(short)i.IType.imm;
			va += sizeof(int);
		} while (va < pc);

		db_find_sym_and_offset(func, &name, &offset);
		if (name == 0)
			name = "?";
		(*pr)("%s()+0x%x, called by %p, stack size %d\n",
			name, pc - func, (void *)ra, stacksize);

		if (ra == pc) {
			(*pr)("-- loop? --\n");
			return;
		}
		sp += stacksize;
		pc = ra;
	} while (pc > (unsigned)verylocore);
	if (pc < 0x80000000)
		(*pr)("-- user process --\n");
	else
		(*pr)("-- kernel entry --\n");
#endif
}
Example #2
0
void
db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
    const char *modif, void (*pr)(const char *, ...))
{
#ifndef DDB_TRACE
	struct pcb *pcb;
	struct proc *p;
	struct lwp *l;
	const char *cp = modif;
	char c;
	bool lwpaddr = false;

	if (!have_addr) {
		struct reg * regs = &ddb_regs;
		stacktrace_subr(regs->r_regs[_R_A0],
				regs->r_regs[_R_A1],
				regs->r_regs[_R_A2],
				regs->r_regs[_R_A3],
				regs->r_regs[_R_PC],
				regs->r_regs[_R_SP],
				/* non-virtual frame pointer */
				regs->r_regs[_R_S8],
				regs->r_regs[_R_RA],
				pr);
		return;
	}

	while ((c = *cp++) != 0) {
		if (c == 'a') {
			lwpaddr = true;
		}
	}

	if (lwpaddr) {
		l = (struct lwp *)(intptr_t)addr;
		(*pr)("pid %d.%d ", l->l_proc->p_pid, l->l_lid);
	} else {
		/* "trace/t" */

		(*pr)("pid %d ", (int)addr);
		p = proc_find_raw(addr);
		if (p == NULL) {
			(*pr)("not found\n");
			return;
		}	
		l = LIST_FIRST(&p->p_lwps); /* XXX NJWLWP */
	}

	pcb = lwp_getpcb(l);
	(*pr)("at %p\n", pcb);

	stacktrace_subr(0,0,0,0,	/* no args known */
			(vaddr_t)cpu_switchto,
			pcb->pcb_context.val[_L_SP],
			pcb->pcb_context.val[_L_S8],
			pcb->pcb_context.val[_L_RA],
			pr);
#else
/*
 * Incomplete but practically useful stack backtrace.
 */
#define	MIPS_JR_RA	0x03e00008	/* instruction code for jr ra */
#define	MIPS_JR_K0	0x03400008	/* instruction code for jr k0 */
#define	MIPS_ERET	0x42000018	/* instruction code for eret */
	register_t va, pc, ra, sp, func;
	int insn;
	InstFmt i;
	int stacksize;
	db_addr_t offset;
	const char *name;
	extern char verylocore[];

	pc = ddb_regs.r_regs[_R_PC];
	sp = ddb_regs.r_regs[_R_SP];
	ra = ddb_regs.r_regs[_R_RA];
	do {
		va = pc;
		do {
			va -= sizeof(int);
			insn = *(int *)(intptr_t)va;
			if (insn == MIPS_ERET)
				goto mips3_eret;
		} while (insn != MIPS_JR_RA && insn != MIPS_JR_K0);
		va += sizeof(int);
	mips3_eret:
		va += sizeof(int);
		while (*(int *)(intptr_t)va == 0x00000000)
			va += sizeof(int);
		func = va;
		stacksize = 0;
		do {
			i.word = *(int *)(intptr_t)va;
			if (((i.IType.op == OP_SW) || (i.IType.op == OP_SD))
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_RA)
				ra = *(int *)(intptr_t)(sp + (short)i.IType.imm);
			if (((i.IType.op == OP_ADDIU) || (i.IType.op == OP_DADDIU))
			    && i.IType.rs == _R_SP
			    && i.IType.rt == _R_SP)
				stacksize = -(short)i.IType.imm;
			va += sizeof(int);
		} while (va < pc);

		db_find_sym_and_offset(func, &name, &offset);
		if (name == 0)
			name = "?";
		(*pr)("%s()+0x%x, called by %p, stack size %d\n",
			name, pc - func, (void *)(intptr_t)ra, stacksize);

		if (ra == pc) {
			(*pr)("-- loop? --\n");
			return;
		}
		sp += stacksize;
		pc = ra;
	} while (pc > (intptr_t)verylocore);
	if (pc < 0x80000000)
		(*pr)("-- user process --\n");
	else
		(*pr)("-- kernel entry --\n");
#endif
}