static int
trace_kernel(struct pt_regs *regs, struct trace_array *tr,
	     struct trace_array_cpu *data)
{
	struct backtrace_info info;
	unsigned long bp;
	char *stack;

	info.tr = tr;
	info.data = data;
	info.pos = 1;

	__trace_special(info.tr, info.data, 1, regs->ip, 0);

	stack = ((char *)regs + sizeof(struct pt_regs));
#ifdef CONFIG_FRAME_POINTER
	bp = regs->bp;
#else
	bp = 0;
#endif

	dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, &info);

	return info.pos;
}
Ejemplo n.º 2
0
static void backtrace_address(void *data, unsigned long addr, int reliable)
{
    struct backtrace_info *info = data;

    if (info->pos < sample_max_depth && reliable) {
        __trace_special(info->tr, info->data, 1, addr, 0);

        info->pos++;
    }
}
Ejemplo n.º 3
0
static int
trace_kernel(struct pt_regs *regs, struct trace_array *tr,
             struct trace_array_cpu *data)
{
    struct backtrace_info info;
    char *stack;

    info.tr = tr;
    info.data = data;
    info.pos = 1;

    __trace_special(info.tr, info.data, 1, regs->ip, 0);
    stack = ((char *)regs + sizeof(struct pt_regs));
    dump_trace(NULL, regs, (void *)stack, &backtrace_ops, &info);

    return info.pos;
}
Ejemplo n.º 4
0
static void timer_notify(struct pt_regs *regs, int cpu)
{
    struct trace_array_cpu *data;
    struct stack_frame_user frame;
    struct trace_array *tr;
    const void __user *fp;
    int is_user;
    int i;

    if (!regs)
        return;

    tr = sysprof_trace;
    data = tr->data[cpu];
    is_user = user_mode(regs);

    if (!current || current->pid == 0)
        return;

    if (is_user && current->state != TASK_RUNNING)
        return;

    __trace_special(tr, data, 0, 0, current->pid);

    if (!is_user)
        i = trace_kernel(regs, tr, data);
    else
        i = 0;

    /*
     * Trace user stack if we are not a kernel thread
     */
    if (current->mm && i < sample_max_depth) {
        regs = (struct pt_regs *)current->thread.sp0 - 1;

        fp = (void __user *)regs->bp;

        __trace_special(tr, data, 2, regs->ip, 0);

        while (i < sample_max_depth) {
            frame.next_fp = NULL;
            frame.return_address = 0;
            if (!copy_stack_frame(fp, &frame))
                break;
            if ((unsigned long)fp < regs->sp)
                break;

            __trace_special(tr, data, 2, frame.return_address,
                            (unsigned long)fp);
            fp = frame.next_fp;

            i++;
        }

    }

    /*
     * Special trace entry if we overflow the max depth:
     */
    if (i == sample_max_depth)
        __trace_special(tr, data, -1, -1, -1);

    __trace_special(tr, data, 3, current->pid, i);
}