免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5223 | 回复: 4
打印 上一主题 下一主题

fault-common.c 387 实在不解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-21 18:00 |只看该作者 |倒序浏览
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的程序流程大致如下:

  1.                 pacArgv [0] = "/etc/ppp/gprs-start";
  2.                 pacArgv [1] = (CFG_PPP_AUTH_TYPE_CHAP == pstSIM->ucAuth) ? "CHAP" : "PAP";
  3.                 pacArgv [2] = pstSIM->acAPN;
  4.                 pacArgv [3] = pstSIM->acUID;
  5.                 pacArgv [4] = pstSIM->acPWD;
  6.                 pacArgv [5] = pstSIM->acIP;
  7.                 pacArgv [6] = 0;

  8.                ucRet = mod_ppp_script (p_pstPPP, pacArgv [0], pacArgv, 60000, 0x00);
复制代码

mod_ppp_script()函数启动pppd大致如下:

  1.                 stChildPid = vfork ();

  2.                 switch (stChildPid)
  3.                 {
  4.                 case 0:                // Child
  5.                         // Set a new group ID
  6.                         setpgid (stChildPid, stChildPid);  //这里子进程在父进程的进程空间里做什么事,不至于导致堆栈溢出

  7.                         execv (p_pcScript, p_pacArgv);   //调execv后,子进程在自己的进程空间里来执行shell脚本,应该不会影响父进程
  8.                         iRet = (0 != errno) ? errno : 1;
  9.                       ***
  10.                 case -1:
  11.                      ***
  12.                 default:
  13.        ***
  14.               }
复制代码


在/etc/ppp/gprs-start脚本中或做一些解析,并启动pppd

  1. #!/bin/sh                           
  2. #                                    
  3. GPRS_AUTH=$1                        
  4. GPRS_APN=$2                          
  5. GPRS_USERNAME=$3                        
  6. GPRS_PASSWORD=$4                        
  7. GPRS_IP_ADDR=$5                          
  8.                                     
  9. export GPRS_APN                              
  10.                                              
  11. if (test "CHAP" = "$GPRS_AUTH")               
  12. then                                    
  13.         auth="/etc/ppp/gprs-chap"            
  14. else                                          
  15.         auth="/etc/ppp/gprs-pap"              
  16. fi                                                           
  17.                                                             
  18. if (test -n "$GPRS_USERNAME")                                
  19. then                                          
  20.         uid="user $GPRS_USERNAME"                           
  21. else                                                         
  22.         uid="user none"                                      
  23. fi                                

  24. if (test -n "$GPRS_PASSWORD")        
  25. then                                 
  26.         pwd="password $GPRS_PASSWORD"
  27. else                                    
  28.         pwd="password none"              
  29. fi                                       
  30.                                     
  31. if (test -n "$GPRS_IP_ADDR")                  
  32. then                                          
  33.         ip_addr="$GPRS_IP_ADDR:"              
  34. else                                    
  35.         ip_addr=                              
  36. fi                                            
  37.                                              
  38. rm -f /tmp/ppp0.pid                                          
  39. rm -f /tmp/LCK..ttyS1   

  40. if (pppd file $auth $ip_addr $uid $pwd &)   #这里启动pppd来进行拨号上网
  41. then                                    
  42.         while (test 1 -eq 1)            
  43.         do                              
  44.                 if (pgrep -x pppd > /dev/null)
  45.                 then                          
  46.                         sleep 1               
  47.                 else                          
  48.                         exit 1               
  49.                 fi                           
  50.                                              
  51.                 if (ifconfig ppp0 | grep "addr:" > /dev/null)
  52.                 then                                         
  53.                         exit 0                              
  54.                 fi                                          
  55.         done                                                
  56. fi                                                           
  57.                                                             
  58. 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 编辑 ]

论坛徽章:
5
2 [报告]
发表于 2009-03-21 18:00 |只看该作者
LZ, 请把编译选项贴出来. 可能是pic选项的问题.

例:
   # CFLAGS="$CFLAGS -D__PIC__ -fpic -msingle-pic-base"
     CFLAGS="$CFLAGS -D__PIC__ -fno-pic -fno-PIC"

[ 本帖最后由 yidou 于 2009-3-24 11:52 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2009-03-23 09:40 |只看该作者
眼瞅着就又要沉了,没有人知道原因吗,或者是我没把问题阐述清楚?

论坛徽章:
5
4 [报告]
发表于 2009-03-24 11:46 |只看该作者

论坛徽章:
0
5 [报告]
发表于 2009-03-25 12:45 |只看该作者
我想应该不会是程序本身的问题,如果是这样的话,单独运行pppd或netrouter时就会报这个错误。应该是uClinux内存管理上的问题(我也说不清楚)。因为使用page_alloc2内存分配机制并不存在这个问题,可是使用power-of-2程序就挂掉了。

谢谢版主的回复!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP