示例#1
0
static void
stack_capture(struct stack *st, vm_offset_t frame)
{
	vm_offset_t callpc;

	stack_zero(st);
	if (frame < PAGE_SIZE)
		return;
	while (1) {
		frame = *(vm_offset_t *)frame;
		if (frame < PAGE_SIZE)
			break;

	    #ifdef __powerpc64__
		callpc = *(vm_offset_t *)(frame + 16) - 4;
	    #else
		callpc = *(vm_offset_t *)(frame + 4) - 4;
	    #endif
		if ((callpc & 3) || (callpc < 0x100))
			break;

		/*
		 * Don't bother traversing trap-frames - there should
		 * be enough info down to the frame to work out where
		 * things are going wrong. Plus, prevents this shortened
		 * version of code from accessing user-space frames
		 */
		if (callpc + CALLOFFSET == (vm_offset_t) &trapexit ||
		    callpc + CALLOFFSET == (vm_offset_t) &asttrapexit)
			break;

		if (stack_put(st, callpc) == -1)
			break;
	}
}
示例#2
0
static void
stack_capture(struct stack *st, struct frame *frame)
{
	struct frame *fp;
	vm_offset_t callpc;

	stack_zero(st);
	fp = frame;
	for (;;) {
		if (!INKERNEL((vm_offset_t)fp) ||
		    !ALIGNED_POINTER(fp, uint64_t))
                        break;
		callpc = fp->fr_pc;
		if (!INKERNEL(callpc))
			break;
		/* Don't bother traversing trap frames. */
		if ((callpc > (uint64_t)tl_trap_begin &&
		    callpc < (uint64_t)tl_trap_end) ||
		    (callpc > (uint64_t)tl_text_begin &&
		    callpc < (uint64_t)tl_text_end))
			break;
		if (stack_put(st, callpc) == -1)
			break;
		if (v9next_frame(fp) <= fp ||
		    v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE)
			break;
		fp = v9next_frame(fp);
	}
}
示例#3
0
void
stack_save(struct stack *st)
{
	u_int32_t *frame;

	frame = (u_int32_t *)__builtin_frame_address(0);
	stack_zero(st);
	stack_capture(st, frame);
}
示例#4
0
void
stack_save(struct stack *st)
{

	stack_zero(st);
	/*
	 * Nothing for now.
	 * Is libuwx reentrant?
	 * Can unw_create* sleep?
	 */
}
示例#5
0
void
stack_save_td(struct stack *st, struct thread *td)
{

	if (TD_IS_SWAPPED(td))
		panic("stack_save_td: swapped");
	if (TD_IS_RUNNING(td))
		panic("stack_save_td: running");

	stack_zero(st);
}
示例#6
0
void
stack_save_td(struct stack *st, struct thread *td)
{
	u_int32_t *frame;

	if (TD_IS_SWAPPED(td))
		panic("stack_save_td: swapped");
	if (TD_IS_RUNNING(td))
		panic("stack_save_td: running");

	frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11;
	stack_zero(st);
	stack_capture(st, frame);
}
示例#7
0
static void
stack_capture(struct stack *st, u_int32_t *frame)
{
	vm_offset_t callpc;

	stack_zero(st);
	while (1) {
		if (!INKERNEL(frame))
			break;
		callpc = frame[FR_SCP];
		if (stack_put(st, callpc) == -1)
			break;
		frame = (u_int32_t *)(frame[FR_RFP]);
	}
}
示例#8
0
/*
 * Similar to kdb_backtrace() except that it prints a backtrace of an
 * arbitrary thread rather than the calling thread.
 */
void
kdb_backtrace_thread(struct thread *td)
{

	if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) {
		printf("KDB: stack backtrace of thread %d:\n", td->td_tid);
		kdb_dbbe->dbbe_trace_thread(td);
	}
#ifdef STACK
	else {
		struct stack st;

		printf("KDB: stack backtrace of thread %d:\n", td->td_tid);
		stack_zero(&st);
		stack_save_td(&st, td);
		stack_print_ddb(&st);
	}
#endif
}
示例#9
0
void
kdb_backtrace(void)
{

	if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) {
		printf("KDB: stack backtrace:\n");
		kdb_dbbe->dbbe_trace();
	}
#ifdef STACK
	else {
		struct stack st;

		printf("KDB: stack backtrace:\n");
		stack_zero(&st);
		stack_save(&st);
		stack_print_ddb(&st);
	}
#endif
}
示例#10
0
void
stack_save_td(struct stack *st, struct thread *td)
{
	u_int32_t *frame;

	if (TD_IS_SWAPPED(td))
		panic("stack_save_td: swapped");
	if (TD_IS_RUNNING(td))
		panic("stack_save_td: running");

	/*
	 * This register, the frame pointer, is incorrect for the ARM EABI
	 * as it doesn't have a frame pointer, however it's value is not used
	 * when building for EABI.
	 */
	frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11;
	stack_zero(st);
	stack_capture(st, frame);
}
示例#11
0
文件: debug.c 项目: 2asoft/freebsd
static int
xendebug_filter(void *arg)
{
#if defined(STACK) && defined(DDB)
	struct stack st;
	struct trapframe *frame;

	frame = arg;
	stack_zero(&st);
	stack_save(&st);

	mtx_lock_spin(&lock);
	sbuf_clear(buf);
	xc_printf("Printing stack trace vCPU%d\n", PCPU_GET(vcpu_id));
	stack_sbuf_print_ddb(buf, &st);
	sbuf_finish(buf);
	mtx_unlock_spin(&lock);
#endif

	return (FILTER_HANDLED);
}
示例#12
0
static void
stack_capture(struct stack *st, u_register_t pc, u_register_t sp)
{
	u_register_t  ra = 0, i, stacksize;
	short ra_stack_pos = 0;
	InstFmt insn;

	stack_zero(st);

	for (;;) {
		stacksize = 0;
		if (pc <= (u_register_t)(intptr_t)btext)
			break;
		for (i = pc; i >= (u_register_t)(intptr_t)btext; i -= sizeof (insn)) {
			bcopy((void *)(intptr_t)i, &insn, sizeof insn);
			switch (insn.IType.op) {
			case OP_ADDI:
			case OP_ADDIU:
			case OP_DADDI:
			case OP_DADDIU:
				if (insn.IType.rs != SP || insn.IType.rt != SP)
					break;
				stacksize = -(short)insn.IType.imm;
				break;

			case OP_SW:
			case OP_SD:
				if (insn.IType.rs != SP || insn.IType.rt != RA)
					break;
				ra_stack_pos = (short)insn.IType.imm;
				break;
			default:
				break;
			}

			if (stacksize)
				break;
		}

		if (stack_put(st, pc) == -1)
			break;

		for (i = pc; !ra; i += sizeof (insn)) {
			bcopy((void *)(intptr_t)i, &insn, sizeof insn);

			switch (insn.IType.op) {
			case OP_SPECIAL:
				if((insn.RType.func == OP_JR))
				{
					if (ra >= (u_register_t)(intptr_t)btext)
						break;
					if (insn.RType.rs != RA)
						break;
					ra = stack_register_fetch(sp, 
					    ra_stack_pos);
					if (!ra)
						goto done;
					ra -= 8;
				}
				break;
			default:
				break;
			}
			/* eret */
			if (insn.word == 0x42000018)
				goto done;
		}

		if (pc == ra && stacksize == 0)
			break;

		sp += stacksize;
		pc = ra;
		ra = 0;
	}
done:
	return;
}