VxWorks操作係統shell命令與調試方法總結
VxWorks下的調試手段
主要介紹在Tornado集成開發環境下的調試方法和利用支撐定位問題的步驟、思路。
1 Tornado的調試工具
嵌入式實時操作係統VxWorks和集成開發環境Tornado的組成結構如下圖1。分為主機和目標機係統。
圖1 集成開發環境結構圖
在Tornado下調試相關操作在Debug菜單下包括
圖2 Debug菜單
簡單解釋各菜單項的功能
1.1 WindShell
1.1.1 簡介
Vxworks的Shell分為兩種hostshell 和 target shell
Tornado提供的WindShell建立了2者間的一個橋梁,從宿主機到目標機之間的一個命令 shell。WindSh 是一種非常受歡迎的開發工具它具有很強的交互性和可操作性允許用戶調用內存中的應用程序模塊或是 VxWorks模塊中的任何例程。它不但具有一般命令語言的功能而且也具有 C 語言的設計特點能夠解釋幾乎任何 C 語言表達式 執行大多數 C 語言算子解析符號表數據。對初用者來說WindSh學習起來比較簡單使用比較方便對熟練用戶而言則有較為高級的手段可以應用。
WindSh是一個駐留在主機內的C語言解釋器通過它可運行下載到目標機上的所有函數包括VxWorks係統調用和應用函數。Tornado外殼還能解釋常規的工具命令語言TCL。
WindSh不僅可以解釋幾乎所有的C語言表達式而且可以實現所有的調試功能。它主要有以下調試功能下載軟件模塊刪除軟件模塊產生任務刪除任務設置斷點刪除斷點運行、單步、繼續執行程序查看內存、寄存器、變量修改內存、寄存器、變量查看任務列表、內存使用情況、CPU利用率查看特定的對象任務、信號量、消息隊列、內存分區、類複位目標機等。
1.1.2 功能鍵
Tab
補齊剩餘部分
Ctrl+D
l 顯示與之匹配的所有符號
-> CurM^D
_CurMaster _CurModule
l 補齊剩餘部分
->CurMo^D
->CurModule
l 顯示命令摘要
->moduleShow ^D
moduleShow() - show the current status for all theloaded modules (WindSh)
STATUS moduleShow
(
char *moduleNameOrId /* name or ID of the module to show */
)
Ctrl+W
鍵入完整的命令後繼續鍵入空格+ [Ctrl+W]。將會顯示html頁幫助信息.
Ctrl+H
刪除一字符
Ctrl+U
刪除一行
CTRL+C
重起shell
CTRL+X
Reboot
CTRL+S
臨時掛起輸出
CTRL+Q
恢複掛起
Esc
在輸入和編輯模式間切換
輸入類似Vi編輯命令, 如[Esc + k]顯示前一次輸入的命令
h←j↓k↑l→
h()設置命令緩衝區長度。->h 500
1.1.3 特殊控製符
?
C和TCL模式轉換符號, 在c模式下敲?進入tcl模式, 在tcl下敲?則進入c模式;
@
在target還是在host上運行, 在指令前加上@則在target上運行, 否則在host上運行
>
指令輸出重定向
<
指令輸入重定向
1.1.4 計算功能
數據轉換鍵入整數或字符後回車可以顯示該整數的十進製及十六進製值。也可以鍵入字符常量或符號地址。
比如
->0x54+64
value = 148 = 0x94
->x = (8 * 6) / 4
x = 0x20ff378: value = 12 = 0xc
->Nom = “Nelson”
new symbol “Nom” added to symbol table.
Nom = 0x23fe798: value = 37742496 = 0x23fe7a0 =
Nom + 0x8
1.1.5 環境變量
使用 shConfig 命令修改環境變量:
SH_GET_TASK_IO
為調用函數設置I/O重定向。ON:重定向到WindSh;OFF:I/O顯示到目標機控製台。
LD_PATH
為模塊設置搜索路徑用“”隔開。 例如ld 命令提交後Shell搜尋模塊的路徑順序為首先在當前目錄然後到LD_PATH設置的路徑。
LD_SEND_MODULES
設置load模式。
以下3個用不到
LD_CALL_XTORS
LD_COMMON_MATCH_ALL
DSM_HEX_MOD
1.1.6 內置指令
1.1.6.1 所有內置指令
tcl> setshellProcList
b bh bd bdall ccret e s so sysResume sysSuspend d l ld lkAddr lkup m mRegs unld agentMode Showbrowse checkStack classShow devs i intVecShow iStrict iosDevShow iosDrvShowiosFdShow memPartShow memShow moduleIdFigure moduleShow mqPxShow mqShowmsgQShow rBuffShow semPxSho w semShow show smMemPartShow smMemShowsysStatusShow taskShow trgShow version wdShow sp sp s taskIdDefaulttaskIdFigure td ti tr ts tt bootChange cd h help ls period printErrno printLogo pwd quit reboot repeat shellHistory shellPromptSet cplusXtorSetcplusStratShow cplus Ctors cplusDtors wvHostInfoShow evtBufferToFile hostShowicmpstatShow ifShow inetstatShow ipstatShow routestatShow taskCreateHookShowtaskDeleteHookShow taskSwitchHookShow taskRegs Show tw w taskWaitShowtcpstatShow tftpInfoShow udpstatShow
1.1.6.2 任務管理
sp
用缺省參數創建一個任務priority=100 返回值為任務ID或錯誤,立刻返回。任務的I/O不被重定向到shell。
如果直接敲例程名回車執行完才返回。I/O被重定向。
sps
與上者不同在於啟動該任務後馬上將其掛起
tr
恢複一個掛起的任務
ts
掛起一個任務
td
刪除一個任務
period
創建一個周期調用函數的任務
period 5testPrn 每隔5秒調用testPrn易於做調試打印。
repeat
創建一個重複調用函數的任務
repeat 10testFunc1 連續執行10次testFunc1函數易於做測試用。
mRegs
修改任務的寄存器變量。比較有用的是修改pc值使程序退回到具體位置再運行。 程序位置可以使用shift+F7(混合匯編方式顯示代碼)
-> mRegs"pc", s1u0
pc : 0499efd7 - 0x499efd1
1.1.6.3 任務狀態信息
i 顯示係統信息:
NAME ENTRY TID PRI STATUS PC SP ERRNO DELAY
---------------------- -------- --- ---------- -------- -------- ------- -----
tExcTask _excTask 4b79170 0 PEND 4276be 4b7908c d0003 0
iStrict 類似於i但隻查詢目標機一次
ti 顯示相應任務的TCB信息:
-> ti tWdbTask
NAME ENTRY TID PRI STATUS PC SP ERRNO DELAY
---------------------- -------- --- ---------- -------- -------- ------- -----
tWdbTask 0x417cc4 4b70c08 3 READY 4276be 4b70ae4 d0003 0
stack: base 0x4b70c08 end 0x4b6ccc8 size 16176 high 3840 margin 12336
options: 0xe
VX_UNBREAKABLE VX_DEALLOC_STACK VX_FP_TASK
edi = ffffffff esi = 4b70fb8 ebp = 4b70aec esp = 4b70ae4
ebx = 0 edx = 4276be ecx = 10101 eax = 0
eflags = 212 pc = 4276be
taskShow
顯示任務TCB信息, 基本同ti
taskCreateHookShow
顯示任務創建調用例程列表
_fppCreateHook 0x177008
_envCreateHook 0x156954
___wdbTaskCreat 0x114718
taskDeleteHookShow
顯示任務刪除調用例程列表
taskSwitchHookShow
顯示任務切換調用例程列表
_dbgTaskSwitch 0x180384
_SwitchHook 0xde7b78
w
顯示所有或者一個掛起任務的信息
-> w s1u1
NAME ENTRY TID STATUS DELAY OBJ_TYPE OBJ_ID OBJ_NAME
-------------------- -------- ---------- ----- ---------- -------- ------------
s1u1 _t2 4b65898 PEND 0 SEM_M 4b7ea48 N/A
tw
顯示某掛起任務的詳細信息。
-> tw s1u1
NAME ENTRY TID STATUS DELAY OBJ_TYPE OBJ_ID OBJ_NAME
---------- ---------- -------- ---------- ----- ---------- --------------------
s1u1 _t2 4b65898 PEND 0 SEM_M 4b7ea48 N/A
Semaphore Id : 0x4b7ea48
Semaphore Type : MUTEX
Task Queueing : FIFO
Pended Tasks : 1
State : Owner=0x4b6c960
taskWaitShow
同tw
taskRegsShow
顯示任務寄存器的內容
->taskRegsShow 0x1c615534
edi = 0 esi = 1dd65514 ebp = 1c61546c esp = 1c615458
ebx = 1 edx = 1dfccac8 ecx = 7 eax = 0
eflags = 246 pc = 119604
CheckStack
顯示一個任務的使用堆棧的情況沒有定義任務時顯示所有
-> checkStack tWdbTask
NAME ENTRY TID SIZE CUR HIGH MARGIN
------------ ------------ -------- ----- ----- -----------
tWdbTask 0x417cc4 4b70c08 16176 292 3840 12336
tt
顯示一個任務的調用狀況,解析堆棧
-> tt tShell
地址 函數名 偏移 被調用函數函數參數
43ad37 _vxTaskEntry +47 : _shell (1, 0,0, 0, 0, 0, 0, 0, 0, 0)
41c414 _shell +13c: 41c438 ([1,0, 0, 0, 41c23c])
41c52e _shell +256: _ledRead(522efb8, 51e45e4, 80)
如果認為被掛起可找出在哪個函數調用時失敗。
taskIdFigure
報告任務的ID,以及名稱
taskIdDefault
設置或者取得缺省的任務id
int taskIdDefault
(
int tid /* user-supplied task ID; if 0,return default */
)
taskPrioritySet
實時改變任務運行的優先級
1.1.6.4 一組調試指令
d
顯示目標機內存, 可以替代內存觀察;
如 d 0x12345, 128, 1 顯示128個字節
d 0x12345, 32, 4 顯示32個DWORD
m 0x12345, 128, 1
m 0x12345, 32, 4
m
修改內存
void m
(
void * adrs, /* address to change */
int width /* width of unit to be modified (1, 2, 4, 8) */
)
lkup
顯示指定符號信息, 和以下指令使用可以找到該變量附近變量, 對於查找變量被更改很有益處
-> lkup "CurModule"
_CurModule 0x01fd3160 comm (down.out)
-> lkup (“^_print”)
_printf 0x00029622 text (vxWorks)
_printErr 0x00029640 text (vxWorks)
_printExc 0x0002965e text (vxWorks)
value = 0 = 0x0
lkAddr
根據指定值搜索符號表顯示的符號地址小於並最接近指定值
-> lkAddr 0x01fd3160
_CurUnit 0x01fd315c comm (down.out)
_CurModule 0x01fd3160 comm (down.out)
_IsFsStarted 0x01fd3164 comm (down.out)
_IntTaskSemaphore 0x01fd3168 comm (down.out)
_gtSemTaskTable 0x01fd316c comm (down.out)
_tR04ModuleReportState 0x01fd3174 comm (down.out)
l
顯示從指定位置開始多少行的匯編
printError
將錯誤號翻譯為具體錯誤信息。前16位錯誤號為module 在vwModNum.h中定義對應不同頭文件。後16位錯誤號為error number在相應的頭文件中定義。
-> printErrno 0x110001
0x110001 = S_memLib_NOT_ENOUGH_MEMORY
ld
加載模塊到係統
[syms[,noAbort][,"name"]]Load stdin, or file, into memory
(syms = add symbols to table: -1 = none, 0 = globals, 1 = all)
unld
卸載模塊
reboot
reset network devices and transfercontrol to boot ROMs 重起, 有些mp板不能執行;
bootChange
修改啟動行參數
boot device : fei
processor number : 0
host name : host
file name : vxWorks
inet on ethernet (e) : 168.2.11.41:ffff0000
inet on backplane (b) :
host inet (h) : 168.2.111.1
gateway inet (g) :
user (u) : x86
ftp password (pw) (blank = use rsh) : x86
flags (f) :
target name (tn) :
startup script (s) :
other (o)
1.1.6.5 係統信息查看
devs
列出目標機係統上的所有設備, host:是指映象文件所在目錄,有些上麵為mars:
-> devs
drv name
0 /null
2 /pcConsole/0
2 /pcConsole/1
7 host:
8 /vio
9 /tgtsvr
4 /HDisk
3 prnpip
iosDevShow
基本同devs
iosDrvShow
顯示係統中的驅動狀態
drv create delete open close read write ioctl
1 421db4 0 421db4 421ddc 42b76c 42b69c 421e08
2 0 0 424fd4 0 425004 425044 425130
3 426e88 426f04 427170 426e34 427228 427254 426ffc
4 415f40 0 415f40 416000 42b76c 42b69c 416074
5 41626c 41642c 416288 416520 4165d0 416670 416710
iosFdShow
顯示係統中的文件標識符
fdname drv
3/tyCo/0 1
4/vio/1 4
5/vio/2 4
6/vio/3 4
intVecShow
查看中斷向量表,
void intVecShow
(
int vector /* interrupt vector number or -1 to display the whole vectortable */
)
moduleShow
顯示係統中所有加載的模塊
MODULENAME MODULE ID GROUP # TEXT START DATA START BSS START
------------------------ -------------------- ---------- ---------- ----------
vxWorks.exe 0x365420 1 0x401000 0x43f000 0x442000
test.o 0xd32888 2 0x499efac 0x499eff4
msgQShow
顯示隊列的使用狀況
Message Queue Id : 0x1c710c0c
Task Queueing : FIFO
Message Byte Len : 8
Messages Max : 4000
Messages Queued : 0
Receivers Blocked : 1
Send Timeouts : 0
Receive Timeouts : 709968
SemShow
顯示信號量的信息
STATUS semShow
(
SEM_ID semId,/* semaphore to display */
int level /* 0 = summary, 1 = details */
)
->semShow NodeSemaphore ,0
Semaphore Id : 0x1c7a443c
Semaphore Type : MUTEX
Task Queueing : FIFO
Pended Tasks : 0
State : NotOwned
SemPxShow
顯示POSIX信號量的信息
wdShow
顯示看門狗的信息
mqPxShow
顯示POSIX消息隊列的信息
memPartShow
顯示分區塊及統計信息
memShow
顯示係統分區上空閑和已分配空間的總數等等
SUMMARY:
status bytes blocks avg block max block
------ ----------------- ---------- ----------
current
free 443257168 140 3166122 442697252
alloc 27726464 517 53629 -
cumulative
alloc 50636892 5873 8621 -
hostShow
顯示host列表
hostname inet address aliases
-------- ------------ -------
vxTarget 168.2.11.9
localhost 127.0.0.1
host 168.2.111.1
arpShow
顯示arp列表
LINK LEVEL ARP TABLE
destination gateway flags Refcnt Use Interface
--------------------------------------------------------------------------
168.2.111.1 00:05:5d:e4:14:3b 405 0 6897 fei0
--------------------------------------------------------------------------
ifShow
顯示網口信息
fei (unit number 0):
Flags:(0x8063) UP BROADCAST RUNNING ARP MULTICAST
Type:ETHERNET_CSMACD
Internetaddress: 168.2.11.9
Broadcastaddress: 168.2.255.255
Netmask0xffff0000 Subnetmask 0xffff0000
Ethernetaddress is 00:d0:d0:10:0b:09
Metric is 0
MaximumTransfer Unit size is 1500
11325 packetsreceived; 6965 packets sent
4374 multicastpackets received
11 multicastpackets sent
0 inputerrors; 0 output errors
0 collisions;0 dropped
lo (unit number 0):
Flags:(0x8069) UP LOOPBACK RUNNING ARP MULTICAST
Type:SOFTWARE_LOOPBACK
Internetaddress: 127.0.0.1
Netmask0xff000000 Subnetmask 0xff000000
Metric is 0
MaximumTransfer Unit size is 32768
0 packetsreceived; 0 packets sent
0 multicastpackets received
0 multicastpackets sent
0 inputerrors; 0 output errors
0 collisions;0 dropped
ipstatShow
顯示ip信息
total 7571
badsum 0
tooshort 0
toosmall 0
badhlen 0
badlen 0
infragments 0
fragdropped 0
fragtimeout 0
forward 0
cantforward 0
redirectsent 0
unknownprotocol 6996
nobuffers 0
reassembled 0
outfragments 0
noroute 0
icmpstatShow
顯示icmp信息
ICMP:
7060 calls toicmp_error
0 error notgenerated because old message was icmp
Outputhistogram:
destinationunreachable: 7060
0 message withbad code fields
0 message <minimum length
0 bad checksum
0 message withbad length
0 messageresponse generated
routestatShow
顯示路由信息
routing:
0 bad routingredirect
0 dynamicallycreated route
0 new gatewaydue to redirects
12 destinationsfound unreachable
0 use of a wildcard route
tcpstatShow
顯示tcp信息
TCP:
11740 packets sent
2840 data packets (137764 bytes)
6 data packets (1867 bytes)retransmitted
5642 ack-only packets (0 delayed)
0 URG only packet
0 window probe packet
0 window update packet
3254 control packets
8485packets received
44 acks (for 2429 bytes)
2801 duplicate acks
0 ack for unsent data
2840 packets (2128 bytes) receivedin-sequence
1 completely duplicate packet (29 bytes)
0 packet with some dup. data (0 byte duped)
2 out-of-order packets (0 byte)
0 packet (0 byte) of data after window
0 window probe
0 window update packet
0 packet received after close
0 discarded for bad checksum
0 discarded for bad header offset field
0 discarded because packet too short
2953 connection requests
0 connection accept
2802 connections established (includingaccepts)
2950 connections closed (including 2798drops)
147 embryonic connections dropped
2846 segments updated rtt (of 5797 attempts)
304 retransmit timeouts
0 connection dropped by rexmit timeout
0 persist timeout
147 keepalive timeouts
0 keepalive probe sent
147connections dropped by keepalive
udpstatShow
顯示udp信息
UDP:
7759 total packets
7757 input packets
2 output packets
0 incomplete header
0 bad data length field
0 bad checksum
581 broadcasts received with no ports
0 full socket
7176 pcb cache lookups failed
7176 pcb hash lookups failed
inetstatShow
顯示連接信息
Active Internetconnections (including servers)
PCB Proto Recv-Q Send-Q Local Address Foreign Address (state)
-------- ----------- ------ ------------------------------------ -------
1de70b94TCP 0 0 0.0.0.0.111 0.0.0.0.0 LISTEN
1de70a08UDP 0 0 0.0.0.0.111 0.0.0.0.0
tftpInfoShow
顯示ftp信息
1.1.6.6 文件操作
注意分清是對target還是host上的文件進行操作, 而相應使用@
cd
改變工作目錄
ls
列出工作目錄下的文件
pwd
顯示當前工作目錄
copy
拷貝文件
copy “host:cnset.cfg”“/HDisk/cnset.cfg”
remove
刪除文件
remove “/HDisk/trace/error.log”
rename
更改文件名稱
usrAtaConfig
將ATA硬盤作為一個dos文件係統加載
STATUS usrAtaConfig
(
int ctrl, /* 0: primary address, 1: secondary address */
int drive, /* drive number of hard disk (0 or 1) */
char * fileName /* mount point */
)
如在MP上配置電子盤和硬盤
usrAtaConfig00“HDISK” 加載硬盤
usrAtaConfig10“FDISK” 加載電子盤
usrTffsConfig
將Flash作為一個dos文件係統加載
usrTffsConfig(int drive, int removable, char * fileName)
如在PPC板上配FLASH
usrTffsConfig00“輸入自己的設備名” 加載Flash盤
tffsDevFormat
格式化flash
STATUS tffsDevFormat
(
int tffsDriveNo, /* TrueFFS drive number (0 - DRIVES-1) */
int arg /* pointer to tffsDevFormatParams structure */
)
例如: tffsDevFormat 0, 0
1.1.6.7 其他
1) shell 本身的一些指令
help Print this list
h Print (or set) shell history
shellHistory 設置或顯示Shell命令
shellPromptSet 改變C解釋器Shell 提示
printLogo 顯示Tornado Shell 登陸
version Print VxWorks version info, andboot line
exit 退出shell
quit 退出shell
2) 幾個係統調試指令
b Display breakpoints
b Set breakpoint
bd Delete breakpoint
bdall Delete all breakpoints
c Continue from breakpoint
s Single step
bh Set hardware breakpoint
sysSuspend Suspend the system
sysResume Resume the system
agentModeShow 顯示代理模式係統模式 或 任務模式
sysStatusShow 顯示係統上下文suspend或 running,係統模式下使用
3) 幾個不常用的指令
smMemShow show the shared memory systempartition blocks and statistics
smMemPartShow show user's shared memory systempartition blocks and statistics
trgShow show trigger information
show 在shell窗口打印特定對象的信息
browse 在Tornado browser 顯示特定的對象
注某些命令隻在TargetServer上執行如lkAddr。
某些需要到Target上執行如period()、repeat()。
1.2 BROWSE
可對係統對象任務、消息隊列、信號量等和存儲器使用情況進行觀察的瀏覽器。可以方便地監視用戶的目標係統。Browser匯總了應用進程內存消耗和一個目標內存的映像。通過Browser用戶可以觀察信號量、消息隊列、內存分配、看門狗計時器、堆棧使用情況、目標 CPU使用率、對象模塊結構和符號表以及每個任務的詳細信息。
可以分析: 內存泄漏、內存碎片、堆棧溢出、優先級反轉
1.2.1 內存查看
Tools條顯示的是歸taget agent管理的內存歸Tornado tools使用
Application條顯示的是歸目標係統內所有任務使用
以上2者獨立分開共同占用目標板的內存
欄內顯示的是所有模塊的所占用內存的信息
1.2.2 模塊信息
可以知道該模塊的地址空間比較有用的是他的符號表
1.2.3 堆棧使用率
可以檢查堆棧狀況
1.2.4 CPU占有率
由於輔助時鍾和目前3gcn內的衝突建議不要使用否則會造成係統紊亂
1.2.5 任務信息
1.2.6 中斷向量表
Std Excep. Handler standard exception handler
Default Trap default trap (Sparc)
Uninit. Int uninitialized interrupt vector
Corrupted Int corrupted interrupt vector
1.2.7 實體查看
可以查看諸如消息隊列、信號量、watchdog、任務、係統內存等的狀況。如
1.3 Debugger
1.3.1 條件斷點
condition 填入條件,變成條件斷點
keep 指一直有效
delete 在斷點到達後將之刪除
disable 先不讓該斷點有效
1.3.2 代碼顯示
Source
以高級語言(c、c++)顯示缺省的顯示方式
Disassembly
以反匯編方式顯示
MixedSource and Disassembly
混合高級和反匯編方式顯示配和修改一些寄存器值如pc來達到控製調試流程。
1.4 Target Server
創建Target Server時需要配置的變量。
1.4.1 使用串口調試
提供了幾種target/host聯係方式
wdbpipe 一般用於vxworks目標模擬
netrom 我們用不著
wdbrpc 用的最多的一種隻要是ip連接的都行需要配置目標機的IP地址
wdbserial 使用串口,填入連接的串口號,及其波特率即可
1.4.2 重定向
RedirectTarget IO
重定向目標機上的全局stdin、 stdout和stderr 到target server。如果沒有創建控製台窗口當有字符從目標機發送過來的時候 WTX 事件被發送給所有的WTX 工具 。
Create Console Window
在target server 所在的主機上創建一個虛擬控製台窗口作為目標機的I/O口。
Redirect Target Shell
創建一個虛擬控製台窗口當前target shell的標準input、output和error被重定向到該窗口。
1.5 WindView
在運行中可以記錄一些重要信息(比如任務調度狀況、信號量、消息隊列、watchdog,、內存、信號)的狀況從而便於對複雜的實時係統運行狀況進行分析。
可以對調度異常、資源掛死、死機等進行分析。
1.5.1 記錄層次
根據需要可以記錄3個層次上數據
- Context Switch Event-Logging Level (CSE Level)
- Task State Transition Event-Logging Level (TST Level)
- Additional Instrumentation Event-Logging Level (AIL Level)
1.5.2 記錄數據存儲方式
可以設定一定大小的內存在target上作為保存數據的緩衝。有這樣幾種方式將該緩衝輸出一般用前兩者
Direct toGraph
直接顯示到屏幕
File via TSFS
送到target server上的一個文件中/tgtsvr/XXX.Wvr文件。Targetserver的路徑如下在TargetServer Configuration 中設置
Socket viaTSFS
通過菜單打開/tgtsvr/TCP:xiaxinguo:6164[其實是創建了個連接]來接收taget的輸出到屏幕
Socket viaTCP/IP
通過菜單打開xiaxinguo:6164[其實是創建了個連接]來接收taget的輸出到屏幕
NFS toFile
保存到文件
1.5.3 傳送方式
Deferred
host取一次taget記一次。
Continuous
target在記到一定程度後傳送到後台繼續記錄連續進行。
Post-Mortem
target將數據記錄到保留內存在異常熱啟動後可再取得相應數據從而可以知道是異常在哪裏。
1.5.4 數據分析
Ø 具體圖形的意義可以參看幫助”Event Dictionary”。
Ø 可以選擇關心的任務關心的實體而將不關心的部分隱藏掉。
Ø 為便於查找可以自己創建幾個實體以便標識比如信號量。在錯誤處操作從而可以很快定位而不用再達海中撈針。
1.6 Trigger
通過設置一些觸發器觸發一些操作主要有以下2個功能
Ø 可以監控變量函數的執行情況特別對變量被修改這種問題有幫助。
Ø 和windview配合使用使記錄可控。
1.7 telnet
telnet功能類似shell不用起tornado而已省卻啟動target server對release比較有用。使用方法如下
在包含了INCLUDE_TELNET 後能使用telnet如果要加上user/pass驗證則需要加上 INCLUDE_SECURITY 。但注意的是下圖中的pass為加密後的密碼可以使用/host/x86-win32/bin/vxencrypt來將密碼加密。
1.8 調試模式
Tornado集成環境提供兩種調試模式任務調試模式和係統調試模式。在任務調試模式下在一個集成環境下一個時間內隻能調試一個任務。調試隻影響當前被調試的任務其它任務正常運行。在係統調試模式下可以同時調試多個任務、中斷服務程序ISR調試影響整個係統。
通過下麵的例子說明調試步驟
/* VxWorks includes */
#include "vxWorks.h"
#include "taskLib.h"
#include "stdio.h"
#include "msgQLib.h"
int g_lTaskATid;
int g_lTaskBTid;
MSG_Q_ID g_MsgQ1id;
MSG_Q_ID g_MsgQ2id;
void MultiTaskTestTaskA(void)
{
char cMsgToTaskB[100];
char cMsgFromTaskB[100];
sprintf(cMsgToTaskB,"To TaskB \n");
printf(" Hello from MultiTaskTestTaskA \n");
taskSuspend(0); /*掛起*/
for(;;)
{
printf(" Hello from MultiTaskTestTaskA \n");
msgQSend(g_MsgQ1id,cMsgToTaskB,sizeof(cMsgToTaskB),WAIT_FOREVER, MSG_PRI_NORMAL);
msgQReceive(g_MsgQ2id,cMsgFromTaskB,100,WAIT_FOREVER);
printf("%s",cMsgFromTaskB);
}
}
void MultiTaskTestTaskB(void)
{
char cMsgToTaskA[100];
char cMsgFromTaskA[100];
sprintf(cMsgToTaskA,"To TaskA \n");
printf(" Hello from MultiTaskTestTaskB \n");
taskSuspend(0);
for(;;)
{
printf(" Hello from MultiTaskTestTaskB \n");
msgQSend(g_MsgQ2id,cMsgToTaskA,sizeof(cMsgToTaskA),WAIT_FOREVER, MSG_PRI_NORMAL);
msgQReceive(g_MsgQ1id,cMsgFromTaskA,100,WAIT_FOREVER);
printf("%s",cMsgFromTaskA);
}
}
void MultiTaskTestInit(void)
{
printf(" Hello from MultiTaskTestInit \n");
g_MsgQ1id=msgQCreate(20,100,MSG_Q_FIFO); /*創建消息隊列*/
if(g_MsgQ1id==NULL)
{
printf(" ERROR: create g_MsgQ1 error \n");
}
g_MsgQ2id=msgQCreate(20,100,MSG_Q_FIFO);
if(g_MsgQ1id==NULL)
{
printf(" ERROR: create g_MsgQ2 error \n");
}
printf(" Spawning a new task called MultiTaskTestTaskA \n\n");
g_lTaskATid=taskSpawn("MultiTaskTestTaskA",100,0,10000, (FUNCPTR)MultiTaskTestTaskA,0,0,0,0,0,0,0,0,0,0);
if(g_lTaskATid == ERROR)
{
printf(" ERROR: task did not spawn \n");
exit(1);
}
printf(" Spawning a new task called MultiTaskTestTaskB \n");
g_lTaskBTid=taskSpawn("MultiTaskTestTaskB",100,0,10000, (FUNCPTR)MultiTaskTestTaskB, 0,0,0,0,0,0,0,0,0,0);
if(g_lTaskBTid == ERROR)
{
printf(" ERROR: task did not spawn \n");
exit(1);
}
exit(0);
}
1.8.1 任務調試模式下的多任務調試
在任務調試模式下在一個集成環境中在一個任務中調試在另一個任務中設置斷點設置的斷點不起作用。這是因為一個調試器隻能處理一個TCB任務控製塊每個任務都有一個TCB因此一個調試器隻能調試一個任務要調試幾個任務就要啟動幾個調試器。一個集成環境隻能啟動一個調試器所以要調試幾個任務就要啟動幾個集成環境。另外需要在被調試的任務的待調試的第一條語句前加入taskSuspend(0)語句掛起該任務否則任務就可能會在調試前被執行。
多任務調試步驟
* 用-g選項編譯源代碼產生目標文件
* 下載產生的目標文件
* 在MultiTaskTestInit函數的開始設置斷點
* 把MultiTaskTestInit設置為調試任務的人口函數
* 單步執行產生MultiTaskTestTaskA任務的語句後可以在串口超級終端上看到字符串Hello from MultiTaskTestTaskA用Browser查看任務可以看到任務MultiTaskTestTaskA出於掛起態suspended表明程序執行了taskSuspend(0)語句。
* 運行另一個Tornado集成環境
* Attach任務MultiTaskTestTaskA
* 在語句msgQReceive(g_MsgQ2id,cMsgFromTaskB,100,WAIT_FOREVER)的下一條語句處設置斷點
* 運行任務MultiTaskTestTaskA。可以看到沒有執行到斷點處用Browser查看任務狀態MultiTaskTestTaskA出於阻塞態pended因為它在等待消息。
* 單步執行MultiTaskTestInit到產生MultiTaskTestTaskB任務的下一條語句可以看到MultiTaskTestTaskB任務處於掛起態
* 再運行另一個Tornado集成環境
* Attach任務MultiTaskTestTaskB
* 在語句msgQReceive(g_MsgQ1id,cMsgFromTaskA,100,WAIT_FOREVER)下一條語句處設置斷點
* 運行任務MultiTaskTestTaskB。可以看到執行到斷點處停下。這是因為MultiTaskTestTaskA任務已經發送一條消息到MultiTaskTestTaskB的接收隊列中。
* 此時可以看到MultiTaskTestTaskA任務也運行到斷點處因為為MultiTaskTestTaskB任務已經發送一條消息到MultiTaskTestTaskA的接收隊列中。
1.8.2 係統調試模式下多任務的調試
Tornado2.0集成環境提供了通過網口進行係統模式調試的功能。係統缺省使用網口通信如果需要使用串口通信需要修改文件C: \ Tornado \ target \ config\ all \ configAll.h的一些宏定義修改為
#define WDB_COMM_TYPE WDB_COMM_SERIAL /*使用串口通信*/
#define WDB_TTY_CHANNEL 0 /*使用第一個串口*/
#define WDB_TTY_BAUD 38400 /*波特率38400bps*/
重新編譯鏈接vxWorks。 在啟動Target server時要選擇串口通信並進行相應配置。
調試使用的源代碼與任務調試模式中使用的代碼相同。但是需要去掉為了能夠在任務調試模式下進行多任務調試的MultiTaskTestTaskA和MultiTaskTestTaskB中的語句taskSuspend(0);。
多任務調試步驟
* 用-g選項編譯源代碼產生目標文件。
* 下載產生的目標文件。
* 在MultiTaskTestInit函數的開始設置斷點。
* 在Debugger命令窗口輸入命令attach system進入係統調試模式。
* 在Shell窗口輸入命令sp MultiTaskTestInit產生一個以MultiTaskTestInit為入口函數的任務因為整個係統都停下了新產生的任務還沒有執行這可以通過在Debugger命令窗口輸入命令info threads顯示當前係統中的任務列表看出來。
* 執行菜單命令Debug | ContinueF5繼續運行程序。
* 係統在設置的斷點處停下。
* 在函數MultiTaskTestTaskA中的語句msgQReceive(g_MsgQ2id,cMsgFromTaskB, 100,WAIT_FOREVER)的下一條語句處設置斷點。
* 在函數MultiTaskTestTaskB中的語句msgQReceive(g_MsgQ1id,cMsgFromTaskA, 100,WAIT_FOREVER)的下一條語句處設置斷點。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序在任務MultiTaskTestTaskB中的斷點處停下為什麼不是在任務MultiTaskTestTaskA中停下請考慮。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序在任務MultiTaskTestTaskA中的斷點處停下。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序又一次在任務MultiTaskTestTaskA中的斷點處停下為什麼停兩次請考慮以後依次增加停的次數。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序在任務MultiTaskTestTaskB中的斷點處停下。
1.8.3 中斷服務程序的調試
中斷服務程序隻能在係統調試模式下調試不能在任務調試模式下調試。因為中斷服務程序是作為係統的一部分運行不是以任務方式運行因此不需要為它產生任務。
中斷服務程序調試步驟
* 用-g選項編譯源代碼產生目標文件。
* 下載產生的目標文件。
* 在MultiTaskTestInit函數的開始設置斷點。
* 在Debugger命令窗口輸入命令attach system進入係統調試模式。
* 執行菜單命令Debug | Continue繼續運行程序。
* 如果產生相應的中斷程序就會在中斷服務程序的斷點處停下。進行需要的調試。
使用logMsg()打印不能用printf()。
2 V2支撐的調試手段
2.1 各模塊提供的函數
R01提供的調試函數需要將MEM_TRACE_ON宏定義打開重新編譯生成目標文件。
VOID r01UBUseStatShow (VOID);
顯示所有內存池的占用信息包括內存池大小, 總共個數, 使用個數, 使用峰值個數, 失敗個數。如果用的個數不變小,可以使用r01UBPoolShow來看是被誰占用;
VOID r01DispCpu (VOID);
打印當前CPU占用情況
BOOL r01PcbShow (WORD16 wPno);
打印進程的運行狀態
BOOL r01UBShowByPno (WORD16 pno)
顯示所有進程占用內存情況
BOOL r01ProcShow (WORD16dwFlag)
顯示當前激活的進程信息包括進程名, 任務號PID, 運行時間pentium為ms,powerpc為10ms, 進程堆棧使用率。DwFlag低四位=1dwRunTickSum字段清零其餘不清零。
BOOL r01TcbShow (WORD16 dwFlag)
功能打印顯示任務情況可以顯示相應任務所用的郵箱(消息隊列)的ID號, 運行時間。
=======================================================
no name mail_box ready block run_times
0 uMonitor 0x1a4d8200 0 0 0
1 uSchTask1 0x1a4c87a0 0 8 3268
2 uSchTask2 0x1a4b8d40 0 42 53638
3 uSchTask3 0x1a4a92e0 0 2 0
4 uSchTask4 0x1a499880 0 11 66
5 uSchTask5 0x1a489e20 0 20 35440
6 uSchTask6 0x1a47a3c0 0 0 0
7 uSchTask7 0x1a46a960 0 2 0
8 uSchTask8 0x1a45af00 0 1 17518
9 uSchTask9 0x1a44b4a0 0 0 0
10 uTimer 0x1a43ba40 0 0 0
BOOL r01UBShowByPno (WORD16pno)
顯示所有進程占用內存情況
WORD16 r01UBPoolPeakGet (WORD16wPool)
顯示某個內存池的UB使用峰值
BOOL r01ProcMsgTrace (WORD16wPno, BYTE byTrace)
打開進程的消息跟蹤生效後收發消息有打印
BOOL r01UBPoolShow (WORD16wPool)
顯示所有某個內存池的當前占用情況
BOOL r03Trace(BYTE m, BYTE u, BYTE trace)
打印與邏輯節點mu間的所以通信消息。
VOID r04node(BYTE md_in, BYTE ut_in, BYTE sut_in)
打印指定節點的信息
VOID r04dogoff()
關閉硬件狗要調試程序需先關閉看門狗否則係統將被複位。
2.2 如何查看error.log文件
典型錯誤page fault
**************************************************
** Schedule Task Page Fault
Date: 2004-08-03 14:38:55
Module: 1, Unit: 0
State: Master
Cpu Percent: 1%
UB: 3998, 4000, 4000, 3988, 3995,4000, 199, 200, 100,
Process Name: M01Mgt
Task No: 3
Process Entry Address: 0x15a1f0
Ret EIP(pEsf->pc): 0x15a813
taskIdCurrent->excInfo.pc:0x15a813
taskIdCurrent->regs.pc: 0x114c2e2
taskIdCurrent->pExcRegSet->pc0x15a813
Stack Size: 8192
Last Run Count: 1
Current Run Count: 2
Send Msg Count: 0
Send Msg Bytes: 0
Syn Wait Flag: 0
MsgNum in Process Queue: 0
Process SP: 0x1d8d4c64
Current Send Event: 0
Current Receiver: 255-255-16383-255-1
Current State: 3
Current Receive Event: 8404
Current Sender: 1-0-97-200-0
Msg:
01 cc 01 03 10 01 cd cd cd
Code:
8a 90 1e 01 00 00 0f b6 c2 83 f8 0274 3f 83 f8 02 7f 0a 83 f8 01 74 15 e9
a0 00 00 00 83 f8 03 74 4b 83 f8 0474 06 e9 91 00 00 00 90 0f b7 45 a2 50
8b 45 94 50 8b 45 08 50 e8 0e 06 0000 83 c4 0c 89 c0 88 45 aa eb 78 8d 74
26 00 0f b7 45 a2 50 8b 45 94 50 8b45 08 50 e8 fe 06 00 00 83 c4 0c 89 c0
88 45 aa eb 58 8d 74 26 00 80 7d 9801 74 0a 80 7d 98 41 74 04 eb 22 8d 36
0f b6 45 98 50 8b 45 08 50 e8 d2 0000 00 83 c4 08 89 c0 88 45 aa eb 22 90
8d b4 26 00 00 00 00 0f b7 45 a2 508b 45 94 50 8b 45 08 50 e8 7e 03 00 00
83 c4 0c 89 c0 88 45 aa eb 08 8d 7426 00 c6 45 aa 04 80 7d aa 46 74 26 83
taskIdCurrent->pStackBase:0x1d7b6070;
pStackLimit:0x1d7b507c;pStackEnd:0x1d7b5070;
taskIdCurrent->wdbInfo.taskSp:0x00000000;
Current call stack:
nargs=10; 0x1157c02 : 0x115f80 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
nargs= 1; 0x115f91 : 0x11c09f (0)
nargs= 1; 0x11c106 : 0x11e89c (0x1d8db07b)
nargs= 1; 0x11e8c5 : 0x11bac8 (0x1d8db07b)
nargs= 0; 0x11bae0 : 0x11e91c ()
nargs= 3; 0x11e947 : 0x15a1f0 (0x1df0c7fb, 0, 0)
nargs= 1; 0x15a2e4 : 0x15a640 (0x1df0c7fb)
Total size: 1924 bytes
分析其記錄的堆棧調用關係可找到發生異常的函數。lkAddr 0x15a640
2.2.1 定位到具體的出錯行
1 使用tornado中view\mixed source and disassembly會將代碼和反匯編混合顯示反匯編中會顯示具體位置比對異常記錄中出錯位置指針就可找到具體代碼行。
2 Error.log會記錄異常發生時該進程的接收消息內容和事件號如果內容比較少的話可找一塊沒有使用的內存將該內容敲進去如果比較多的話可將接收內容放到一全局數組重編版本。在shell中啟動一任務入口是該進程入口並停在該進程入口處修改相關內容指針狀態事件號等跟蹤下去直到出錯的行。
3 最簡便辦法是使用bh硬件斷點一些情況可在前後加上內存頁保護這兩種均能找到具體行如果被修改的有規律可往被修改的地址往上查。
常見錯誤死循環、pagefault、除0錯、越界修改內存、
3 V3支撐的調試手段
1.1. 進程調試
平台的OSS在vxWorks的基礎上創建了一些通信任務、監控任務、485任務、調度任務等等。其中在調度任務下又引入了進程的概念進程的用法見相關設計文檔。
1.2. 查看所有進程信息OSS_DbgGetAllUsePCBInfo
->OSS_DbgGetAllUsePCBInfo
************************UsedProcess Info***************************
WTno | wProcType | MsgCount | ucRunStatus | PCB | ScheCount |
0x0009 | 0x0805 | 0x0000 | 0x03 | 0x038bc390 | 0x000005b2 |
0x0008 | 0x0804 | 0x0000 | 0x03 | 0x038bc498 | 0x000015ef |
0x0008 | 0x0803 | 0x0000 | 0x03 | 0x038bc5a0 | 0x00000001 |
0x0000 | 0x0807 | 0x0000 | 0x03 | 0x038bc6a8 | 0x0000009d |
0x0009 | 0x0401 | 0x0000 | 0x03 | 0x038bcbd0 | 0x00000019 |
0x0009 | 0x0402 | 0x0000 | 0x03 | 0x038bccd8 | 0x000028a7 |
0x0009 | 0x0404 | 0x0000 | 0x03 | 0x038bcde0 | 0x000015e1 |
0x0001 | 0x0411 | 0x0000 | 0x03 | 0x038bcee8 | 0x000003a8 |
0x0008 | 0x0406 | 0x0000 | 0x03 | 0x038bcff0 | 0x00000013 |
0x0008 | 0x0407 | 0x0000 | 0x03 | 0x038bd0f8 | 0x000008e2 |
MsgCount一欄是進程待處理的消息一般為0。PCB這一列是進程控製塊指針可以在GDB中用 p *((T_PCB *)0x38bc390)命令查看詳細信息。ScheCount是進程的運行次數。
1.3. 查看當前運行的進程信息
1.3.1. 進程斷點設置b
如果不設置斷點一般是不會有任何顯示的因為進程的運行時間很短。
在狀態管理中心進程入口設置斷點
-> b SCS_BSMgt
斷點到達
->
Break at 0x06086dac:SCS_BSMgt Task: 0x7e97c40(SCH9)
1.3.2. 當前進程運行信息OSS_DbgGetCurPCBInfo
查看當前運行進程信息就可以看到顯示了狀態管理中心進程
->OSS_DbgGetCurPCBInfo
Current ProcessType 0x402, InstanceNo 0x1 , wTno 0x9,Status 0x2
1.3.3. 當前進程的消息信息OSS_DbgGetCurMsgInfo
查看當前進程的消息可以看到進程消息信息
->OSS_DbgGetCurMsgInfo
Current Msg 0x5dd issent From Pno 0x4020001 ,wUnit 0xffff To Pno 0x4020001 ,wUnit 0xffff
消息號0x5dd十進製為1501可以看出是TIMER1消息。
-> 0x5dd
value = 1501 = 0x5dd
1.3.4. 進程斷點取消bd
取消斷點
è bd SCS_BSMgt
1.3.5. 恢複進程運行tr
再恢複SCH9的運行
-> tr SCH9
這時再看當前進程的消息已經沒有可顯示的了。
->OSS_DbgGetCurMsgInfo
No Running Process,No message!
1.4. 內存觀察
1.4.1. 消息隊列堆積、阻塞觀察tw
任務間通信(包括不同調度任務的進程間)是通過隊列來進行的。因此每個任務都有一個隊列該任務不停地從隊列中取消息進行處理相當於消費者如果隊列為空則任務掛起等待消息。其他任務(如通信任務等)向該任務的隊列發送消息相當於生產者。在一個穩定的係統中消息隊列應該基本不堆積消息。以調度任務9為例用tw命令可以清楚地看到SCH9阻塞在隊列上。
-> tw SCH9
NAME ENTRY TID STATUS DELAY OBJ_TYPE OBJ_ID OBJ_NAME
-------------------- -------- ---------- ----- ---------- -------- ------------
SCH9 0x5fe4110 7e97c40 PEND 0 MSG_Q(R) 7e97e58 N/A
Message QueueId : 0x7e97e58
Task Queueing : FIFO
Message ByteLen : 4
Messages Max : 4000
Messages Queued : 0
ReceiversBlocked : 1
Send Timeouts : 0
ReceiveTimeouts : 0
Receivers Blocked:
NAME TID PRI TIMEOUT
---------- ----------- -------
SCH9 7e97c40 80 0
此外在係統中還有一個統一的內存UB池包括內部UB和用戶UB。生產者發送消息時從UB池中獲取內存發送給消費者消費者處理消息後釋放UB。這一切對上層應用
最後更新:2017-04-03 05:40:07