/* * bad_mode handles the impossible case in the exception vector. */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); #ifdef CONFIG_MEDIATEK_SOLUTION /* * * reason is defined in entry.S, 3 means BAD_ERROR, * * which would be triggered by async abort */ if ((reason == 3) && async_abort_handler) async_abort_handler(regs, async_abort_priv); #endif pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); __show_regs(regs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - bad mode", regs, &info, 0); }
static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, bool partial) { /* * These on_stack() checks aren't strictly necessary: the unwind code * has already validated the 'regs' pointer. The checks are done for * ordering reasons: if the registers are on the next stack, we don't * want to print them out yet. Otherwise they'll be shown as part of * the wrong stack. Later, when show_trace_log_lvl() switches to the * next stack, this function will be called again with the same regs so * they can be printed in the right context. */ if (!partial && on_stack(info, regs, sizeof(*regs))) { __show_regs(regs, 0); } else if (partial && on_stack(info, (void *)regs + IRET_FRAME_OFFSET, IRET_FRAME_SIZE)) { /* * When an interrupt or exception occurs in entry code, the * full pt_regs might not have been saved yet. In that case * just print the iret frame. */ show_iret_regs(regs); } }
static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) { struct task_struct *tsk = thread->task; static int die_counter; int ret; pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", str, err, ++die_counter); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV); if (ret == NOTIFY_STOP) return ret; print_modules(); __show_regs(regs); pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1); if (!user_mode(regs) || in_interrupt()) { dump_mem(KERN_EMERG, "Stack: ", regs->sp, THREAD_SIZE + (unsigned long)task_stack_page(tsk)); dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); } return ret; }
static int __die(const char *str, int err, struct pt_regs *regs) { struct task_struct *tsk = current; static int die_counter; int ret; pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", str, err, ++die_counter); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV); if (ret == NOTIFY_STOP) return ret; print_modules(); __show_regs(regs); pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); if (!user_mode(regs)) { dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); } return ret; }
/* * f: bit0: show kernel , bit1: dump user. */ int tstack( int pid , int f) { struct pt_regs * preg; struct task_struct *t = FIND_TASK_BY_PID( pid ); if( !t ){ printk("NO task found for pid %d\n" ,pid ); t = current ; } preg = unwind_get_regs( t ); if( f& 1 ) { show_stack( t , NULL ); } if( !preg ) { printk("NO user stack found for task %s(%d)\n" , t->comm , t->pid ); } else { //printk("user stack found for task %s(%d):\n" , t->comm , t->pid ); __show_regs( preg ); if( f & 2 ) { #define SHOW_STACK_SIZE (2*1024) int len; unsigned int *ps = (unsigned int*)kmalloc( SHOW_STACK_SIZE , GFP_KERNEL); if( ps ) { len = access_process_vm( t , preg->ARM_sp , ps , SHOW_STACK_SIZE, 0 ); rk28_printk_mem( ps , len/4 , (unsigned int* )preg->ARM_sp ); kfree( ps ); } } } return pid; }
void kmemcheck_error_recall(void) { static const char *desc[] = { [KMEMCHECK_SHADOW_UNALLOCATED] = "unallocated", [KMEMCHECK_SHADOW_UNINITIALIZED] = "uninitialized", [KMEMCHECK_SHADOW_INITIALIZED] = "initialized", [KMEMCHECK_SHADOW_FREED] = "freed", }; static const char short_desc[] = { [KMEMCHECK_SHADOW_UNALLOCATED] = 'a', [KMEMCHECK_SHADOW_UNINITIALIZED] = 'u', [KMEMCHECK_SHADOW_INITIALIZED] = 'i', [KMEMCHECK_SHADOW_FREED] = 'f', }; struct kmemcheck_error *e; unsigned int i; e = error_next_rd(); if (!e) return; switch (e->type) { case KMEMCHECK_ERROR_INVALID_ACCESS: printk(KERN_ERR "WARNING: kmemcheck: Caught %d-bit read " "from %s memory (%p)\n", 8 * e->size, e->state < ARRAY_SIZE(desc) ? desc[e->state] : "(invalid shadow state)", (void *) e->address); printk(KERN_INFO); for (i = 0; i < SHADOW_COPY_SIZE; ++i) printk("%02x", e->memory_copy[i]); printk("\n"); printk(KERN_INFO); for (i = 0; i < SHADOW_COPY_SIZE; ++i) { if (e->shadow_copy[i] < ARRAY_SIZE(short_desc)) printk(" %c", short_desc[e->shadow_copy[i]]); else printk(" ?"); } printk("\n"); printk(KERN_INFO "%*c\n", 2 + 2 * (int) (e->address & (SHADOW_COPY_SIZE - 1)), '^'); break; case KMEMCHECK_ERROR_BUG: printk(KERN_EMERG "ERROR: kmemcheck: Fatal error\n"); break; } __show_regs(&e->regs, 1); print_stack_trace(&e->trace, 0); }
void show_registers(struct pt_regs *regs) { int i; unsigned long sp; const int cpu = smp_processor_id(); struct task_struct *cur = current; sp = regs->sp; printk("CPU %d ", cpu); print_modules(); __show_regs(regs, 1); printk("Process %s (pid: %d, veid: %d, threadinfo %p, task %p)\n", cur->comm, cur->pid, task_veid(cur), task_thread_info(cur), cur); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; printk(KERN_DEFAULT "Stack:\n"); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, KERN_DEFAULT); printk(KERN_DEFAULT "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { printk(" Bad RIP value."); break; } if (ip == (u8 *)regs->ip) printk("<%02x> ", c); else printk("%02x ", c); } } printk("\n"); }
void show_regs(struct pt_regs *regs) { int i; unsigned long sp; sp = regs->sp; show_regs_print_info(KERN_DEFAULT); __show_regs(regs, 1); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; show_lbrs(); /* called before show_stack_log_lvl() as it could trig page_fault again and reenable LBR */ printk(KERN_DEFAULT "Stack:\n"); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, 0, KERN_DEFAULT); printk(KERN_DEFAULT "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { pr_cont(" Bad RIP value."); break; } if (ip == (u8 *)regs->ip) pr_cont("<%02x> ", c); else pr_cont("%02x ", c); } } pr_cont("\n"); }
void show_registers(struct pt_regs *regs) { int i; print_modules(); __show_regs(regs, 0); printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", TASK_COMM_LEN, current->comm, task_pid_nr(current), current_thread_info(), current, task_thread_info(current)); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode_vm(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; printk(KERN_EMERG "Stack:\n"); show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); printk(KERN_EMERG "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { printk(" Bad EIP value."); break; } if (ip == (u8 *)regs->ip) printk("<%02x> ", c); else printk("%02x ", c); } } printk("\n"); }
/* * bad_mode handles the impossible case in the exception vector. */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); __show_regs(regs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; arm64_notify_die("Oops - bad mode", regs, &info, 0); }
void show_regs(struct pt_regs *regs) { int i; show_regs_print_info(KERN_EMERG); __show_regs(regs, !user_mode(regs)); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; pr_emerg("Stack:\n"); show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); pr_emerg("Code:"); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { pr_cont(" Bad EIP value."); break; } if (ip == (u8 *)regs->ip) pr_cont(" <%02x>", c); else pr_cont(" %02x", c); } } pr_cont("\n"); }
/* * bad_el0_sync handles unexpected, but potentially recoverable synchronous * exceptions taken from EL0. Unlike bad_mode, this returns. */ asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) { siginfo_t info; void __user *pc = (void __user *)instruction_pointer(regs); console_verbose(); pr_crit("Bad EL0 synchronous exception detected on CPU%d, code 0x%08x -- %s\n", smp_processor_id(), esr, esr_get_class_string(esr)); __show_regs(regs); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_ILLOPC; info.si_addr = pc; current->thread.fault_address = 0; current->thread.fault_code = 0; force_sig_info(info.si_signo, &info, current); }
void show_registers(struct pt_regs *regs) { int i; int in_kernel = !user_mode(regs); unsigned long rsp; const int cpu = safe_smp_processor_id(); struct task_struct *cur = cpu_pda[cpu].pcurrent; rsp = regs->rsp; printk("CPU %d ", cpu); __show_regs(regs); printk("Process %s (pid: %d, threadinfo %p, task %p)\n", cur->comm, cur->pid, cur->thread_info, cur); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (in_kernel) { printk("Stack: "); show_stack(NULL, (unsigned long*)rsp); printk("\nCode: "); if(regs->rip < PAGE_OFFSET) goto bad; for(i=0;i<20;i++) { unsigned char c; if(__get_user(c, &((unsigned char*)regs->rip)[i])) { bad: printk(" Bad RIP value."); break; } printk("%02x ", c); } } printk("\n"); }
asmlinkage long do_ni_syscall(struct pt_regs *regs) { #ifdef CONFIG_COMPAT long ret; if (is_compat_task()) { ret = compat_arm_syscall(regs); if (ret != -ENOSYS) return ret; } #endif if (show_unhandled_signals && printk_ratelimit()) { pr_info("%s[%d]: syscall %d\n", current->comm, task_pid_nr(current), (int)regs->syscallno); dump_instr("", regs); if (user_mode(regs)) __show_regs(regs); } return sys_ni_syscall(); }
static void arm64_show_signal(int signo, const char *str) { static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); struct task_struct *tsk = current; unsigned int esr = tsk->thread.fault_code; struct pt_regs *regs = task_pt_regs(tsk); /* Leave if the signal won't be shown */ if (!show_unhandled_signals || !unhandled_signal(tsk, signo) || !__ratelimit(&rs)) return; pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk)); if (esr) pr_cont("%s, ESR 0x%08x, ", esr_get_class_string(esr), esr); pr_cont("%s", str); print_vma_addr(KERN_CONT " in ", regs->pc); pr_cont("\n"); __show_regs(regs); }
void show_regs(struct pt_regs *regs) { __show_regs(regs, 1); show_trace(NULL, regs, ®s->sp, regs->bp); }
void show_regs(struct pt_regs * regs) { __show_regs(regs); dump_backtrace(regs, NULL); }
void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, char *log_lvl) { struct unwind_state state; struct stack_info stack_info = {0}; unsigned long visit_mask = 0; int graph_idx = 0; printk("%sCall Trace:\n", log_lvl); unwind_start(&state, task, regs, stack); stack = stack ? : get_stack_pointer(task, regs); /* * Iterate through the stacks, starting with the current stack pointer. * Each stack has a pointer to the next one. * * x86-64 can have several stacks: * - task stack * - interrupt stack * - HW exception stacks (double fault, nmi, debug, mce) * * x86-32 can have up to three stacks: * - task stack * - softirq stack * - hardirq stack */ for (regs = NULL; stack; stack = stack_info.next_sp) { const char *stack_name; /* * If we overflowed the task stack into a guard page, jump back * to the bottom of the usable stack. */ if (task_stack_page(task) - (void *)stack < PAGE_SIZE) stack = task_stack_page(task); if (get_stack_info(stack, task, &stack_info, &visit_mask)) break; stack_name = stack_type_name(stack_info.type); if (stack_name) printk("%s <%s>\n", log_lvl, stack_name); /* * Scan the stack, printing any text addresses we find. At the * same time, follow proper stack frames with the unwinder. * * Addresses found during the scan which are not reported by * the unwinder are considered to be additional clues which are * sometimes useful for debugging and are prefixed with '?'. * This also serves as a failsafe option in case the unwinder * goes off in the weeds. */ for (; stack < stack_info.end; stack++) { unsigned long real_addr; int reliable = 0; unsigned long addr = READ_ONCE_NOCHECK(*stack); unsigned long *ret_addr_p = unwind_get_return_address_ptr(&state); if (!__kernel_text_address(addr)) continue; /* * Don't print regs->ip again if it was already printed * by __show_regs() below. */ if (regs && stack == ®s->ip) { unwind_next_frame(&state); continue; } if (stack == ret_addr_p) reliable = 1; /* * When function graph tracing is enabled for a * function, its return address on the stack is * replaced with the address of an ftrace handler * (return_to_handler). In that case, before printing * the "real" address, we want to print the handler * address as an "unreliable" hint that function graph * tracing was involved. */ real_addr = ftrace_graph_ret_addr(task, &graph_idx, addr, stack); if (real_addr != addr) printk_stack_address(addr, 0, log_lvl); printk_stack_address(real_addr, reliable, log_lvl); if (!reliable) continue; /* * Get the next frame from the unwinder. No need to * check for an error: if anything goes wrong, the rest * of the addresses will just be printed as unreliable. */ unwind_next_frame(&state); /* if the frame has entry regs, print them */ regs = unwind_get_entry_regs(&state); if (regs) __show_regs(regs, 0); } if (stack_name) printk("%s </%s>\n", log_lvl, stack_name); } }
void show_regs(struct pt_regs *regs) { __show_regs(regs); show_trace(current, (unsigned long *) ®s); }
void show_regs(struct pt_regs * regs) { printk("\n"); __show_regs(regs); }