最近查一个问题,看到一份kernellog里有这么一段:
unionpay.kalefu[29653]: syscall 133446
Code: e0861001 e2833002 e3a02000 ef000000 (e1a00008)
CPU : 6 PID: 29653 Comm: unionpay.kalefu Tainted: P W O 3.10.84-perf-g06f6aec#1
task : ffffffc093073ac0 ti: ffffffc0e06fc000 task.ti: ffffffc0e06fc000
PC is at 0xf2ce90c8
LR is at 0xf62d607c
pc : [<00000000f2ce90c8>] lr : [<00000000f62d607c>] pstate: 400e0010
sp : 00000000ffc3da7c
x12: 00000000f6d965dc
x11: 000000000000004d x10 : 00000000f2d3e364
x9 : 0000000000030664 x8 : 00000000f2cc8008
x7 : 0000000000020664 x6 : 00000000f2c73a68
x5 : 00000000f2c943fe x4 : 00000000f62db678
x3 : 00000000000f0002 x2 : 0000000000000000
x1 : 00000000f2ca411c x0 : 00000000f2c73a68
一开始以为是段错误,后来仔细一看没有BUG,也没有打出backtrace,看到有syscall,知道应该跟系统调用有关系,搜索code发现这段log是由do_ni_syscall打印出来的,如下:
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();
}
是中arch/arm64/kernel里的traps.c中定义的,do_ni_syscall函数是当遇到内核无法处理的系统调用时会统一由do_ni_syscall来处理,会把本次无法处理的系统调用发起的进程PID,进程名(comm),系统调用号,以及系统寄存器打出来。从上面的log可以看出这次调用的syscallno是133446,系统式无法处理的。