“Bad RIP value”含义

debug占用很高system的进程 时,采用 Linux “魔力” 系统请求组合键 SysRq 指令 t dump出进程信息:

echo t > /proc/sysrq-trigger

其中的报错信息

dump_tasks_info
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[Tue Aug 10 17:16:00 2021] Call Trace:
[Tue Aug 10 17:16:00 2021]  ? __schedule+0x3cf/0x660
[Tue Aug 10 17:16:00 2021]  schedule+0x33/0xc0
[Tue Aug 10 17:16:00 2021]  schedule_hrtimeout_range_clock+0xb9/0x1a0
[Tue Aug 10 17:16:00 2021]  ? __hrtimer_init+0xb0/0xb0
[Tue Aug 10 17:16:00 2021]  ep_poll+0x351/0x450
[Tue Aug 10 17:16:00 2021]  ? do_futex+0x2f7/0x590
[Tue Aug 10 17:16:00 2021]  ? wake_up_q+0x70/0x70
[Tue Aug 10 17:16:00 2021]  do_epoll_wait+0xaf/0xd0
[Tue Aug 10 17:16:00 2021]  __x64_sys_epoll_wait+0x1a/0x20
[Tue Aug 10 17:16:00 2021]  do_syscall_64+0x55/0x1a0
[Tue Aug 10 17:16:00 2021]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[Tue Aug 10 17:16:00 2021] RIP: 0033:0x7f4f6a70b4f3
[Tue Aug 10 17:16:00 2021] Code: Bad RIP value.
[Tue Aug 10 17:16:00 2021] RSP: 002b:00007ffc43c43470 EFLAGS: 00000293 ORIG_RAX: 00000000000000e8
[Tue Aug 10 17:16:00 2021] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f4f6a70b4f3
[Tue Aug 10 17:16:00 2021] RDX: 0000000000000040 RSI: 0000564608bb2dc0 RDI: 0000000000000007
[Tue Aug 10 17:16:00 2021] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000004000001
[Tue Aug 10 17:16:00 2021] R10: 000000000000e95f R11: 0000000000000293 R12: 00005646074fce40
[Tue Aug 10 17:16:00 2021] R13: 0000000000000000 R14: 0000000000000000 R15: 00005646074fce40
[Tue Aug 10 17:16:00 2021] auditd          S    0  2101      1 0x00000000
[Tue Aug 10 17:16:00 2021] Call Trace:
[Tue Aug 10 17:16:00 2021]  ? __schedule+0x3cf/0x660
[Tue Aug 10 17:16:00 2021]  ? __ext4_journal_stop+0x36/0xa0 [ext4]
[Tue Aug 10 17:16:00 2021]  schedule+0x33/0xc0
[Tue Aug 10 17:16:00 2021]  futex_wait_queue_me+0xc1/0x120
[Tue Aug 10 17:16:00 2021]  futex_wait+0xf6/0x250
[Tue Aug 10 17:16:00 2021]  do_futex+0x12b/0x590
[Tue Aug 10 17:16:00 2021]  __x64_sys_futex+0x88/0x180
[Tue Aug 10 17:16:00 2021]  do_syscall_64+0x55/0x1a0
[Tue Aug 10 17:16:00 2021]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[Tue Aug 10 17:16:00 2021] RIP: 0033:0x7f4f6b4269b5
[Tue Aug 10 17:16:00 2021] Code: Bad RIP value.
[Tue Aug 10 17:16:00 2021] RSP: 002b:00007f4f68caad20 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca
[Tue Aug 10 17:16:00 2021] RAX: ffffffffffffffda RBX: 00005646074fa220 RCX: 00007f4f6b4269b5
[Tue Aug 10 17:16:00 2021] RDX: 000000000a1ab4e3 RSI: 0000000000000080 RDI: 00005646074fa254
[Tue Aug 10 17:16:00 2021] RBP: 00005646074fa228 R08: 00005646074fa200 R09: 00000000050d5a71
[Tue Aug 10 17:16:00 2021] R10: 0000000000000000 R11: 0000000000000246 R12: 00005646074fa250
[Tue Aug 10 17:16:00 2021] R13: 0000564608bb76c0 R14: 0000000000000000 R15: 00007f4f68cab700
[Tue Aug 10 17:16:00 2021] kworker/107:1H  I    0  2063      2 0x80000000
[Tue Aug 10 17:16:00 2021] Workqueue:            (null) (kblockd)

从上述当前任务的信息可以看出:

  • RIP: 0033:0x7f4f6a70b4f3 对应地址错误 ( Code: Bad RIP value. )

RIP概念

RIP 是CPU的64位指令指针寄存器,这个值决定了CPU将要取出来执行的下一个指令的地址。

在x86架构中,最初16位指令指针被称为 IP (instruction pointer, 指令指针) ;当架构扩展到32位时候,在寄存器名字前面加上了 E 表示是32位访问宽度( EIP );当扩展到64位 x86_64 时候,则使用 R 前缀表示是完全的64位访问宽度( RIP )。

所谓的 Bad RIP value 表示指令指针寄存器指向了一个没有包含可执行内存的地址。通常这个错误表示在没有正确初始化一个函数的指针就开始尝试使用该指针,也有可能是在堆栈中覆盖了一个函数的返回地址,所以 RET 机器码指令就会在尝试返回一个错误地址时终止。