コード例 #1
0
static int ipanic_current_task_info(void *data, unsigned char *buffer, size_t sz_buf)
{
	struct stack_trace trace;
	int i, plen;
	struct task_struct *tsk;
	struct aee_process_info *cur_proc;
	struct pt_regs *regs = (struct pt_regs *)data;

	if (!virt_addr_valid(current_thread_info()))
		return -1;
	tsk = current_thread_info()->task;
	if (!virt_addr_valid(tsk))
		return -1;
	cur_proc = (struct aee_process_info *)ipanic_task_info;
	memset(cur_proc, 0, sizeof(struct aee_process_info));

	/* Grab kernel task stack trace */
	trace.nr_entries = 0;
	trace.max_entries = MAX_STACK_TRACE_DEPTH;
	trace.entries = ipanic_stack_entries;
	trace.skip = 8;
	save_stack_trace_tsk(tsk, &trace);
	/* Skip the entries -  ipanic_save_current_tsk_info/save_stack_trace_tsk */
	for (i = 0; i < trace.nr_entries; i++) {
		int off = strlen(cur_proc->backtrace);
		int plen = AEE_BACKTRACE_LENGTH - off;
		if (plen > 16) {
			snprintf(cur_proc->backtrace + off, plen, "[<%p>] %pS\n",
				 (void *)ipanic_stack_entries[i], (void *)ipanic_stack_entries[i]);
		}
	}
	if (regs) {
		cur_proc->ke_frame.pc = (__u64) regs->reg_pc;
		cur_proc->ke_frame.lr = (__u64) regs->reg_lr;
	} else {
		/* in case panic() is called without die */
		/* Todo: a UT for this */
		cur_proc->ke_frame.pc = ipanic_stack_entries[0];
		cur_proc->ke_frame.lr = ipanic_stack_entries[1];
	}
	snprintf(cur_proc->ke_frame.pc_symbol, AEE_SZ_SYMBOL_S, "[<%p>] %pS",
		 (void *)(unsigned long) cur_proc->ke_frame.pc, (void *)(unsigned long) cur_proc->ke_frame.pc);
	snprintf(cur_proc->ke_frame.lr_symbol, AEE_SZ_SYMBOL_L, "[<%p>] %pS",
		 (void *)(unsigned long) cur_proc->ke_frame.lr, (void *)(unsigned long) cur_proc->ke_frame.lr);
	/* Current panic user tasks */
	plen = 0;
	while (tsk && (tsk->pid != 0) && (tsk->pid != 1)) {
		/* FIXME: Check overflow ? */
		plen += snprintf(cur_proc->process_path + plen, AEE_PROCESS_NAME_LENGTH,
				 "[%s, %d]", tsk->comm, tsk->pid);
		tsk = tsk->real_parent;
	}
	mrdump_mini_add_misc((unsigned long)cur_proc, sizeof(struct aee_process_info), 0, "PROC_CUR_TSK");
	memcpy(buffer, cur_proc, sizeof(struct aee_process_info));
	return sizeof(struct aee_process_info);
}
コード例 #2
0
static inline void store_stacktrace(struct task_struct *tsk,
					struct latency_record *lat)
{
	struct stack_trace trace;

	memset(&trace, 0, sizeof(trace));
	trace.max_entries = LT_BACKTRACEDEPTH;
	trace.entries = &lat->backtrace[0];
	save_stack_trace_tsk(tsk, &trace);
}
コード例 #3
0
ファイル: stacktrace.c プロジェクト: 03199618/linux
void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
{
	struct stack_trace_data trace_data = {
		.trace = trace,
		.skip = trace->skip,
	};
	walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data);
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);

void save_stack_trace(struct stack_trace *trace)
{
	save_stack_trace_tsk(current, trace);
}
コード例 #4
0
// IRQ off monitor
void MT_trace_irq_off(void)
{
    struct sched_stop_event *e;
    struct stack_trace *trace;
    e = & __raw_get_cpu_var(IRQ_disable_mon);

    e->cur_ts = sched_clock();
    /*save timestap*/
    __raw_get_cpu_var(TS_irq_off) = sched_clock();
    trace = &__raw_get_cpu_var(MT_stack_trace);
    /*save backtraces*/
    trace->nr_entries    = 0;
    trace->max_entries   = MAX_STACK_TRACE_DEPTH; //32
    trace->skip      = 0;
    save_stack_trace_tsk(current, trace);

    
}
コード例 #5
0
ファイル: aee-common.c プロジェクト: SelfImp/m75
void aee_get_traces(char *msg)
{
	struct stack_trace trace;
	int i;
	int offset;
	if (trace_entry_ptr == NULL)
		return;
	memset(trace_entry_ptr, 0, MAX_STACK_TRACE_DEPTH * 4);
	trace.entries = trace_entry_ptr;
	/*save backtraces */
	trace.nr_entries = 0;
	trace.max_entries = 32;
	trace.skip = 0;
	save_stack_trace_tsk(current, &trace);
	for (i = 0; i < trace.nr_entries; i++) {
		offset = strlen(msg);
		snprintf(msg + offset, KERNEL_REPORT_LENGTH - offset, "[<%p>] %pS\n",
			 (void *)trace.entries[i], (void *)trace.entries[i]);
	}
}
コード例 #6
0
ファイル: stacktrace.c プロジェクト: avagin/linux
/**
 * stack_trace_save - Save a stack trace into a storage array
 * @store:	Pointer to storage array
 * @size:	Size of the storage array
 * @skipnr:	Number of entries to skip at the start of the stack trace
 *
 * Return: Number of trace entries stored
 */
unsigned int stack_trace_save(unsigned long *store, unsigned int size,
			      unsigned int skipnr)
{
	struct stack_trace trace = {
		.entries	= store,
		.max_entries	= size,
		.skip		= skipnr + 1,
	};

	save_stack_trace(&trace);
	return trace.nr_entries;
}
EXPORT_SYMBOL_GPL(stack_trace_save);

/**
 * stack_trace_save_tsk - Save a task stack trace into a storage array
 * @task:	The task to examine
 * @store:	Pointer to storage array
 * @size:	Size of the storage array
 * @skipnr:	Number of entries to skip at the start of the stack trace
 *
 * Return: Number of trace entries stored
 */
unsigned int stack_trace_save_tsk(struct task_struct *task,
				  unsigned long *store, unsigned int size,
				  unsigned int skipnr)
{
	struct stack_trace trace = {
		.entries	= store,
		.max_entries	= size,
		.skip		= skipnr + 1,
	};

	save_stack_trace_tsk(task, &trace);
	return trace.nr_entries;
}

/**
 * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
 * @regs:	Pointer to pt_regs to examine
 * @store:	Pointer to storage array
 * @size:	Size of the storage array
 * @skipnr:	Number of entries to skip at the start of the stack trace
 *
 * Return: Number of trace entries stored
 */
unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
				   unsigned int size, unsigned int skipnr)
{
	struct stack_trace trace = {
		.entries	= store,
		.max_entries	= size,
		.skip		= skipnr,
	};

	save_stack_trace_regs(regs, &trace);
	return trace.nr_entries;
}

#ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
/**
 * stack_trace_save_tsk_reliable - Save task stack with verification
 * @tsk:	Pointer to the task to examine
 * @store:	Pointer to storage array
 * @size:	Size of the storage array
 *
 * Return:	An error if it detects any unreliable features of the
 *		stack. Otherwise it guarantees that the stack trace is
 *		reliable and returns the number of entries stored.
 *
 * If the task is not 'current', the caller *must* ensure the task is inactive.
 */
int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
				  unsigned int size)
{
	struct stack_trace trace = {
		.entries	= store,
		.max_entries	= size,
	};
	int ret = save_stack_trace_tsk_reliable(tsk, &trace);

	return ret ? ret : trace.nr_entries;
}
#endif

#ifdef CONFIG_USER_STACKTRACE_SUPPORT
/**
 * stack_trace_save_user - Save a user space stack trace into a storage array
 * @store:	Pointer to storage array
 * @size:	Size of the storage array
 *
 * Return: Number of trace entries stored
 */
unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
{
	struct stack_trace trace = {
		.entries	= store,
		.max_entries	= size,
	};

	save_stack_trace_user(&trace);
	return trace.nr_entries;
}
コード例 #7
0
void save_stack_trace(struct stack_trace *trace)
{
	save_stack_trace_tsk(current, trace);
}
コード例 #8
0
ファイル: stack.c プロジェクト: CSCLOG/beaglebone
void save_stack_trace(struct stack_trace *trace)
{
	save_stack_trace_tsk(NULL, trace);
}