Logo Search packages:      
Sourcecode: linux version File versions

stacktrace.c

/*
 * arch/mips/kernel/stacktrace.c
 *
 * Stack trace management functions
 *
 *  Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
 */
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/module.h>
#include <asm/stacktrace.h>

/*
 * Save stack-backtrace addresses into a stack_trace buffer:
 */
static void save_raw_context_stack(struct stack_trace *trace,
      unsigned long reg29)
{
      unsigned long *sp = (unsigned long *)reg29;
      unsigned long addr;

      while (!kstack_end(sp)) {
            addr = *sp++;
            if (__kernel_text_address(addr)) {
                  if (trace->skip > 0)
                        trace->skip--;
                  else
                        trace->entries[trace->nr_entries++] = addr;
                  if (trace->nr_entries >= trace->max_entries)
                        break;
            }
      }
}

static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
{
      unsigned long sp = regs->regs[29];
#ifdef CONFIG_KALLSYMS
      unsigned long ra = regs->regs[31];
      unsigned long pc = regs->cp0_epc;

      if (raw_show_trace || !__kernel_text_address(pc)) {
            unsigned long stack_page =
                  (unsigned long)task_stack_page(current);
            if (stack_page && sp >= stack_page &&
                sp <= stack_page + THREAD_SIZE - 32)
                  save_raw_context_stack(trace, sp);
            return;
      }
      do {
            if (trace->skip > 0)
                  trace->skip--;
            else
                  trace->entries[trace->nr_entries++] = pc;
            if (trace->nr_entries >= trace->max_entries)
                  break;
            pc = unwind_stack(current, &sp, pc, &ra);
      } while (pc);
#else
      save_raw_context_stack(trace, sp);
#endif
}

/*
 * Save stack-backtrace addresses into a stack_trace buffer.
 */
void save_stack_trace(struct stack_trace *trace)
{
      struct pt_regs dummyregs;
      struct pt_regs *regs = &dummyregs;

      WARN_ON(trace->nr_entries || !trace->max_entries);

      prepare_frametrace(regs);
      save_context_stack(trace, regs);
}
EXPORT_SYMBOL_GPL(save_stack_trace);

Generated by  Doxygen 1.6.0   Back to index