概要设计
031c8d90: 031C8DA0*005335C0 00000000 031C8DA0 .....S5......... 031c8da0: 031C8E60*002D7C4C 00000000 EEEEEEEE ...`.-|L........ 031c8db0: 09000008 00000000 00000000 00000000 ................ 031c8dc0: EEEEEEEE EEEEEEEE EEEEEEEE EEEEEEEE ................ 031c8dd0: EEEEEEEE EEEEEEEE EEEEEEEE EEEEEEEE ................ 031c8de0: EEEEEEEE EEEEEEEE 031C8DF0 EEEEEEEE ................ 031c8df0: 031C8E00 006C103C 031C8E00 002D7BB8 .....l.<.....-{. 031c8e00: 031C8E10 006B30F0 0000B030 002D7BB8 .....k0....0.-{. 031c8e10: 031C8E28 006B1F34 00000000 0000001F ...(.k.4........ 031c8e20: 00000000 002D7BB8 031C8E60 006B1EB8 .....-{....`.k.. 031c8e30: 0053306C 00000000 00000000 EEEEEEEE .S0l............ 031c8e40: 00000000 00000000 031C8E50 EEEEEEEE ...........P.... 031c8e50: 031C8E60 006AC8FC 00000000 002D7BB8 ...`.j.......-{. 031c8e60: 031C8F88*00533F04 031C8E68 002D7BB8 .....S?....h.-{. 031c8e70: FFFFFFFF 33889808 A0140000 95044010 ....3.........@. 031c8e80: 0A020000 00000000 08000000 031C8FE0 ................ 031c8e90: 00000002 00000000 00000000 00000000 ................ 堆栈结构:对于PowerPC体系结构的设备,堆栈含义如下: back chain SP Ptr current LR(主调函数PC) 参数区 局部变量区 寄存器保存区 next back chain SP Ptr previous LR ?? 两个SP之间的内存区称作一个堆栈frame,如上文中蓝色字体的部分就是一个frame。 通过指令地址找到所在的函数:map中只有每个函数(或标号)起始点的地址,所以直接在map中搜索这些PC很难找到;一般来说当PC值位于两个函数起始地址之间,则属于地址小的那个函数:例如PC为0x12345,函数fun1、fun2在map中地址分别为0x12340、0x12350且它们之间没有其它函数,则该PC属于函数fun1。
当前函数指任务TCB中保存的PC值所在的函数。
栈顶frame一般属于当前函数;若该函数没有压栈,则属于它的调用者。若某函数扇出为零并且没有局部变量或局部变量全部可以放在寄存器中时,编译器不会生成压栈代码。判断一个函数是否压栈的方法是将函数反汇编,若第一条指令不是stwu则未压栈。
堆栈frame中第一个字(0x031c8d38指向的字)表示当前上下文上一级堆栈指针;后面一个字则有两种情况:
1、 当本frame是该任务顶级frame时,表示栈顶函数本次执行至此时调用最后一个函数的
调用点地址,根据该地址即可找到栈顶函数,例如006EED58;若栈顶函数本次执行中尚未调用过其它函数,则是无效值,需要通过下一级frame中(LR-4)指向的指令推断当前栈顶函数
2、 当本frame不是栈顶时表示当前函数的主调函数PC指针,例如006BB694等
依此类推可以得到该任务到目前位置的调用函数PC指针列表,通过查找map文件即可得到函数调用序列。对于上例,函数调用PC指针列表为:
273935858.doc Version1.4T (错误!未指定书签。) Page 11 of 27
概要设计
006EED58<-006BB694<-005335C0<-002D7C4C<-00533F04(为了便于说明,我在每个SP Ptr后面打了星号)
3.2.3 与任务有关的日志
%SYS-3-CPUHOG: Task [name] run for [time] ticks(start at [tick])
%SYS-6-CPUHOG_INFO: Task [name] call procedure [pc1]--[pc2]--[pc3]--[pc4]-- 该日志表示系统中名为[name]的任务连续运行了[time]时间而未切出;CPUHOG_INFO表示了该任务被检测到CPU_HOG的时候的调用栈。
当某个任务连续36秒未切出时,系统会认为该任务陷入死循环,并重启整个系统。
%SYS-3-TASK_EXCEPTION_HANDLE: Task [name] suspended, system will reboot after 10 seconds
该日志表示系统中名为[name]的进入挂起状态,鉴于该任务属于系统关键任务,整个系统将在10秒后重启。重启前,系统会尝试把该任务的调用栈打出来以便于收集信息定位问题原因,调用栈输出格式与show break中的格式相同。
%SYS-3-CRITICAL_TASK_DEAD: Critical task [name] hasn't scheduled for [time] secods(lasttime switch [hex1] now [hex2]), maybe deadlock.
%SYS-3-CRITICAL_TASK_DEAD: Critical task [name] was dead, system will reboot in 10 seconds 上述两条日志通常同时出现。它们表示系统中的关键任务长时间未被调度到,可能发生了死锁。其中name是任务名字,time为任务未被调度的时间,hex1、hex2为两个16进制数,分别表示该任务上次切入时的tick值和当前的tick值。 系统将在10秒钟之后重新启动,重启动之前会把该任务的调用栈输出出来以便于收集信息定位问题原因,调用栈输出格式与show task中的格式相同。
%SYS-2-STACK_OVERFLOW: Stack for task [name](tid = [tid], sp = [sp], stack limit = [stklmt]) overflow, system maybe crashed
该日志表示系统中名为[name]的任务出现堆栈溢出的错误,此后任务将会挂起。
%SYS-4-STACK_LOW: Stack for task [name](tid = [tid], sp = [sp], stack limit = [stklmt]) is low 该日志表示系统中名为[name]的任务堆栈使用率超过80%。建议使用show task 0x[tid]查看该任务的调用栈使用情况以便于定位问题。
3.3 任务切换记录
任务切换记录用于记录交换机软件中各个任务切换情况。可以使用命令show task switch-record命令察看实时任务切换轨迹,如下例 Switch#show task switch-record ????(省略部分)????
Task # 14: id 392a948 name : _TM_ switch tick 6b42be entry pt 152610 Task # 15: id 27af510 name : tty0 switch tick 6b42be entry pt 16570c Task # 16: id 392a948 name : _TM_ switch tick 6b42bf entry pt 152610 Task # 17: id 27af510 name : tty0 switch tick 6b42bf entry pt 16570c Task # 18: id 392a948 name : _TM_ switch tick 6b42c0 entry pt 152610 Task # 19: id 27af510 name : tty0 switch tick 6b42c0 entry pt 16570c Task # 20: id 392a948 name : _TM_ switch tick 6b42c1 entry pt 152610
273935858.doc Version1.4T (错误!未指定书签。) Page 12 of 27
概要设计
Task # 21: id 27af510 name : tty0 switch tick 6b42c1 entry pt 16570c 上面的显示中Task #是任务切换记录的序号,id是任务的id,name是任务的名称,switch tick是一个时间单位(0.01秒),表示本行这个任务开始切入的时间,同时也是上一行的任务切出的时间,entry pt表示这个任务的入口函数。例如,上面的例子中第一行表示任务_TM_在系统启动后0x6b42be个tick的时候切入,下一行表示在相同的tick内切出。
如果系统发生异常复位,那么在系统重新启动之后使用show task switch-record命令就可以知道系统重启动时哪个任务在运行(注意系统重新启动后不要断电)。如下例: Switch#reb n Please wait...
System Bootstrap, Version 0.2.3, Serial num:S32000315 SWITCH-S3224 Processor MPC8245 @ 200Mhz The current time: 2004-4-1 10:11:30
SDRAM Fast Test...............................PASS! Flash Fast Test...............................PASS! RTC Test......................................PASS! Switch Internal Loopback Test.................PASS! Loading switch.bin...... Start Decompress switch.bin
######################################################################################################################################################################################################################################################################################################################################################################################################### Decompress 1867675 byte,Please wait system up.. System startup OK
Switch console 0 is now available
Press RETURN to get started
2004-4-1 10:12:03 Switch System started --
2004-4-1 10:12:03 %LINK-5-UPDOWN: Line on Interface VLAN1, changed state to up
Welcome to SWITCH S3224 Ethernet Switch
Switch>ena
Switch#2004-4-1 10:12:12 User DEFAULT enter privilege mode from console 0, level = 15 show task switch-record
Task # 0: id 392a948 name : _TM_ switch tick 4e3109 entry pt 152610
273935858.doc Version1.4T (错误!未指定书签。) Page 13 of 27
概要设计
Task # 1: id 3d2c0b0 name : IDLE switch tick 4e3109 entry pt 1547a0 Task # 2: id 392a948 name : _TM_ switch tick 4e310a entry pt 152610 Task # 3: id 3d2c0b0 name : IDLE switch tick 4e310a entry pt 1547a0 Task # 4: id 392a948 name : _TM_ switch tick 4e310b entry pt 152610 Task # 5: id 3d2c0b0 name : IDLE switch tick 4e310b entry pt 1547a0 Task # 6: id 392a948 name : _TM_ switch tick 4e310c entry pt 152610 Task # 7: id 38a1200 name : GVRP switch tick 4e310c entry pt 5f23c Task # 8: id 3d2c0b0 name : IDLE switch tick 4e310c entry pt 1547a0 Task # 9: id 392a948 name : _TM_ switch tick 4e310d entry pt 152610 Task # 10: id 3d2c0b0 name : IDLE switch tick 4e310d entry pt 1547a0 Task # 11: id 392a948 name : _TM_ switch tick 4e310e entry pt 152610 Task # 12: id 3d2c0b0 name : IDLE switch tick 4e310e entry pt 1547a0 Task # 13: id 392a948 name : _TM_ switch tick 4e310f entry pt 152610 Task # 14: id 3d2c0b0 name : IDLE switch tick 4e310f entry pt 1547a0 Task # 15: id 3d2c0b0 name : IDLE switch tick 4e30dc entry pt 1547a0 Task # 16: id 392a948 name : _TM_ switch tick 4e30dd entry pt 152610 Task # 17: id 3d2c0b0 name : IDLE switch tick 4e30dd entry pt 1547a0 ????(略)????
第14行任务IDLE切入时间是4e310f,下一个任务切换记录第15行切入时间是4e30dc,比上一个切入时间小,说明切换记录14是系统复位前最后一个任务,也就是说在IDLE任务中系统发生了复位。总结:系统复位后的任务切换记录中,如果某一行切换记录的switch tick比上一行的大,说明该行的任务发生异常情况,引起系统复位。
当系统CPU占用率达到阈值(一般是100%)时,也会记录当前的任务切换记录,以便于分析CPU占用率高的原因。系统会保留最近20次系统忙时的任务切换序列,使用命令show task switch-record busy
3.4 热键
当系统console口长时间没有反应,怀疑系统出现异常时,可以使用ctrl+\\键呼叫系统热键功能,此时系统会把所有任务的堆栈信息打印出来,便于错误分析。系统热键的输出为show task以及系统中每一个任务(包括中断)的调用栈,其格式和上文中讲到的相同。其中中断的调用栈有特别的意义,例如下列中断调用栈中(为了便于说明,我在每个SP Ptr后面打了星号): Stack for INTR context(512 bytes), Stack base is a60268 00a60020: 00a60148*00535fb8 03a6e160 00000800 00a60030: 00000002 00a60090 00037284 00009030 00a60040: 00000000 0000013d 034afb08 00a60050 00a60050: 00a60070 0053a7c4 03a6e160 00000800 00a60060: 00000002 00a60090 00a60080 03a6e160 00a60070: 00a600b8 000372b4 00a60090 02598ac0 00a60080: 00a60090 006c32d8 00000000 00000000 00a60090: 00037114 03a6e160 00000000 00000000 00a600a0: 03e0b5d4 000188f8 00009030 03a6e160 00a600b0: 00000801 026c3248 00a600d8 0014c6a4 00a600c0: 00000000 00000000 00000000 007de168 00a600d0: 00a600e8 00000000 00a600f0 006b9980
273935858.doc Version1.4T (错误!未指定书签。) Page 14 of 27
概要设计
00a600e0: 006c5fec 00009030 00a60100 03c6a190 00a600f0: 00a60100 006c32d8 00009030 006bc80c 00a60100: 00a60110 006bc808 000186a0 03c6c7c8 00a60110: 00a60128 006bd3e0 00a60130 006bd3ec 00a60120: 00a60128 007de808 00a60140 006b9980 00a60130: 00a60148 032b0f98 00a60140 10000003 00a60140: 00000000 007c83b4 00a60150*00014c90 00a60150: 00a60158*0068e8c4 00a60170*0068e99c 00a60160: 04e40001 00000000 00a60180 03d1a4b8 00a60170: 00a60180*0001096c 00000000 00000008 00a60180: 00a60198*000109d0 00a60190 00016014 00a60190: 00000000 00534b38 00a601a8*00000518 00a601a0: eeeeeeee eeeeeeee 03d1f020*eeeeeeee ??
00a60250: 00000000 00000000 eeeeeeee eeeeeeee 00a60260: eeeeeeee eeeeeeee 00000000 00000008 Stack for task tExcTask(512 bytes) ??(stacks for task)
大家可以看到,最后一级堆栈指针(3d1f020)与前面的相差比较远,在中断的堆栈中找不到这个地址;实际上它就是被中断的任务的当前堆栈指针;通过它与(后面的)其它任务堆栈指针进行比较,可以知道哪个任务过于繁忙导致系统无法响应其它输入。
273935858.doc Version1.4T (错误!未指定书签。) Page 15 of 27
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库调试方法综述(3)在线全文阅读。
相关推荐: