Currently stack unwinder is a while(1) loop which relies on the dwarf
unwinder to signal termination, which in turn relies on dwarf info to do
so. This in theory could cause an infinite loop if the dwarf info was
somehow messed up or the register contents were etc.
This fix thus detects the excessive looping and breaks the loop.
| Mem: 26184K used, 1009136K free, 0K shrd, 0K buff, 14416K cached
| CPU: 0.0% usr 72.8% sys 0.0% nic 27.1% idle 0.0% io 0.0% irq 0.0% sirq
| Load average: 4.33 2.60 1.11 2/74 139
| PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
| 133 2 root SWN 0 0.0 3 22.9 [rcu_torture_rea]
| 132 2 root SWN 0 0.0 0 22.0 [rcu_torture_rea]
| 131 2 root SWN 0 0.0 3 21.5 [rcu_torture_rea]
| 126 2 root RW 0 0.0 2 5.4 [rcu_torture_wri]
| 129 2 root SWN 0 0.0 0 0.2 [rcu_torture_fak]
| 137 2 root SW 0 0.0 0 0.2 [rcu_torture_cbf]
| 127 2 root SWN 0 0.0 0 0.1 [rcu_torture_fak]
| 138 115 root R 1464 0.1 2 0.1 top
| 130 2 root SWN 0 0.0 0 0.1 [rcu_torture_fak]
| 128 2 root SWN 0 0.0 0 0.1 [rcu_torture_fak]
| 115 1 root S 1472 0.1 1 0.0 -/bin/sh
| 104 1 root S 1464 0.1 0 0.0 inetd
| 1 0 root S 1456 0.1 2 0.0 init
| 78 1 root S 1456 0.1 0 0.0 syslogd -O /var/log/messages
| 134 2 root SW 0 0.0 2 0.0 [rcu_torture_sta]
| 10 2 root IW 0 0.0 1 0.0 [rcu_preempt]
| 88 2 root IW 0 0.0 1 0.0 [kworker/1:1-eve]
| 66 2 root IW 0 0.0 2 0.0 [kworker/2:2-eve]
| 39 2 root IW 0 0.0 2 0.0 [kworker/2:1-eve]
| unwinder looping too long, aborting !
Cc: <stable@vger.kernel.org>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
int (*consumer_fn) (unsigned int, void *), void *arg)
{
#ifdef CONFIG_ARC_DW2_UNWIND
- int ret = 0;
+ int ret = 0, cnt = 0;
unsigned int address;
struct unwind_frame_info frame_info;
break;
frame_info.regs.r63 = frame_info.regs.r31;
+
+ if (cnt++ > 128) {
+ printk("unwinder looping too long, aborting !\n");
+ return 0;
+ }
}
return address; /* return the last address it saw */