- 论坛徽章:
- 0
|
20可用积分
在ARM7+uClinux-2.4.20上调我们下面这个应用程序时,经常会报fault-common.c 387这个错误。只有堆栈溢出导致内核抛出fault-common.c 387这个错误吗?如果确实是这样,实在想不通下面这种情况:
我们的一个应用程序netrouter会在函数里调用一个脚本(gprs-start)来运行pppd,进行GPRS拨号上网。
1,如果我只运行netrouter,而不让netrouter启动pppd,系统运行很正常,内核不会报这个error;-> netrouter应该没问题
2,如果不运行netrouter,手动启动pppd,系统运行也很正常;-> pppd从官方下了交叉编译的,这里也没报堆栈溢出错误;
3,如果我使用netrouter来运行pppd,则内核会报fault-common.c 387, 并抛出Oops;
fault-common.c 387
fault-common.c 387
fault-common.c 387
Unhandled fault: alignment exception (13) at 0x00000001
fault-common.c(97): start_code=0x2f00040, start_stack=0x2fffed
Internal error: Oops: 0
CPU: 0
pc : [<000314d4>] lr : [<00ceb040>] Not tainted
sp : 02e67ed4 ip : 65523c20 fp : 02e67ef0
r10: 02e67f64 r9 : 00000066 r8 : 00000000
r7 : 000001f0 r6 : 007ab9a4 r5 : 40000013 r4 : 007ab99c
r3 : 696b6f50 r2 : 9617a0c0 r1 : 000001f0 r0 : 007ab99c
Flags: nzCv IRQs off FIQs on Mode SVC_32 Segment kernel
Control: 0
Process pppd (pid: 99, stackpage=02e67000)
Stack:
02e67ec0: 00ceb040 000314d4 20000093 ffffffff 00000001 00c1a730 00000001
02e67ee0: 001cd364 02e67f0c 02e67ef4 000fb1b4 00031488 001a620c 00c1a730 00000002
02e67f00: 02e67f28 02e67f10 001566a0 000fb1a0 00c1a730 00000004 00000002 02e67f38
02e67f20: 02e67f2c 001567b8 00156674 02e67f60 02e67f3c 000f9910 00156780 00000000
02e67f40: 02f2fa84 00000009 02e66000 00019700 02f38924 02e67f78 02e67f64 000f9988
02e67f60: 000f9898 0000000c 00000000 02e67fac 02e67f7c 000fa574 000f9980 00000000
02e67f80: 00000000 00000001 00000002 00000000 02e66000 00019700 0000005a 00000018
02e67fa0: 00000000 02e67fb0 00019560 000fa4e8 00000018 0001eee0 00000001 02fffe10
02e67fc0: 00000000 00000001 00000018 02f2fa84 00000009 00000002 00000007 00000000
02e67fe0: 02f38924 02fffe0c 02fffe10 02fffdfc 02f29a34 02f2b0cc 20000010 00000001
Backtrace:
netrouter启动pppd的程序流程大致如下:
- pacArgv [0] = "/etc/ppp/gprs-start";
- pacArgv [1] = (CFG_PPP_AUTH_TYPE_CHAP == pstSIM->ucAuth) ? "CHAP" : "PAP";
- pacArgv [2] = pstSIM->acAPN;
- pacArgv [3] = pstSIM->acUID;
- pacArgv [4] = pstSIM->acPWD;
- pacArgv [5] = pstSIM->acIP;
- pacArgv [6] = 0;
-
- ucRet = mod_ppp_script (p_pstPPP, pacArgv [0], pacArgv, 60000, 0x00);
复制代码
mod_ppp_script()函数启动pppd大致如下:
- stChildPid = vfork ();
- switch (stChildPid)
- {
- case 0: // Child
- // Set a new group ID
- setpgid (stChildPid, stChildPid); //这里子进程在父进程的进程空间里做什么事,不至于导致堆栈溢出
- execv (p_pcScript, p_pacArgv); //调execv后,子进程在自己的进程空间里来执行shell脚本,应该不会影响父进程
- iRet = (0 != errno) ? errno : 1;
- ***
- case -1:
- ***
- default:
- ***
- }
复制代码
在/etc/ppp/gprs-start脚本中或做一些解析,并启动pppd
- #!/bin/sh
- #
- GPRS_AUTH=$1
- GPRS_APN=$2
- GPRS_USERNAME=$3
- GPRS_PASSWORD=$4
- GPRS_IP_ADDR=$5
-
- export GPRS_APN
-
- if (test "CHAP" = "$GPRS_AUTH")
- then
- auth="/etc/ppp/gprs-chap"
- else
- auth="/etc/ppp/gprs-pap"
- fi
-
- if (test -n "$GPRS_USERNAME")
- then
- uid="user $GPRS_USERNAME"
- else
- uid="user none"
- fi
- if (test -n "$GPRS_PASSWORD")
- then
- pwd="password $GPRS_PASSWORD"
- else
- pwd="password none"
- fi
-
- if (test -n "$GPRS_IP_ADDR")
- then
- ip_addr="$GPRS_IP_ADDR:"
- else
- ip_addr=
- fi
-
- rm -f /tmp/ppp0.pid
- rm -f /tmp/LCK..ttyS1
- if (pppd file $auth $ip_addr $uid $pwd &) #这里启动pppd来进行拨号上网
- then
- while (test 1 -eq 1)
- do
- if (pgrep -x pppd > /dev/null)
- then
- sleep 1
- else
- exit 1
- fi
-
- if (ifconfig ppp0 | grep "addr:" > /dev/null)
- then
- exit 0
- fi
- done
- fi
-
- exit 1
复制代码
单独运行netrouter没问题;应该可以说明netrouter程序并不存在堆栈溢出;
单独运行pppd没问题,应该可以说明pppd程序也不存在堆栈溢出;
如果用netrouter来启动pppd程序,则内核报了fault-common.c错误,这是由于堆栈溢出引起的吗?如果是的话,那在哪里溢出了?如果不是,那又是什么原因导致fault-common.c错误,并抛出Oops?
PS: 我也用arm-elf-flthdr工具将两个程序(netrouter和pppd)的栈调到256K,512K试过,但都会出现上面这个问题。 |
最佳答案
查看完整内容
LZ, 请把编译选项贴出来. 可能是pic选项的问题.例: # CFLAGS="$CFLAGS -D__PIC__ -fpic -msingle-pic-base" CFLAGS="$CFLAGS -D__PIC__ -fno-pic -fno-PIC"[ 本帖最后由 yidou 于 2009-3-24 11:52 编辑 ]
|