VxWorks作業系統shell命令與除錯方法總結
VxWorks下的除錯手段
主要介紹在Tornado整合開發環境下的除錯方法,和利用支撐定位問題的步驟、思路。
嵌入式實時作業系統VxWorks和整合開發環境Tornado的組成結構如下圖1。分為主機和目標機系統。
圖1 整合開發環境結構圖
在Tornado下,除錯相關操作在Debug選單下,包括:
圖2 Debug選單
簡單解釋各選單項的功能
Vxworks的Shell分為兩種:hostshell 和 target shell;
Tornado提供的WindShell建立了2者間的一個橋樑,從宿主機到目標機之間的一個命令 shell。WindSh 是一種非常受歡迎的開發工具,它具有很強的互動性和可操作性,允許使用者呼叫記憶體中的應用程式模組或是 VxWorks模組中的任何例程。它不但具有一般命令語言的功能,而且也具有 C 語言的設計特點,能夠解釋幾乎任何 C 語言表示式, 執行大多數 C 語言運算元,解析符號表資料。對初用者來說,WindSh學習起來比較簡單,使用比較方便,對熟練使用者而言,則有較為高階的手段可以應用。
WindSh是一個駐留在主機內的C語言直譯器,通過它可執行下載到目標機上的所有函式,包括VxWorks系統呼叫和應用函式。Tornado外殼還能解釋常規的工具命令語言TCL。
WindSh不僅可以解釋幾乎所有的C語言表示式,而且可以實現所有的除錯功能。它主要有以下除錯功能:下載軟體模組;刪除軟體模組;產生任務;刪除任務;設定斷點;刪除斷點;執行、單步、繼續執行程式;檢視記憶體、暫存器、變數;修改記憶體、暫存器、變數;檢視任務列表、記憶體使用情況、CPU利用率;檢視特定的物件(任務、訊號量、訊息佇列、記憶體分割槽、類);復位目標機等。
Tab
補齊剩餘部分
Ctrl+D
l 顯示與之匹配的所有符號
-> CurM
_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
?
C和TCL模式轉換符號, 在c模式下敲?進入tcl模式, 在tcl下敲?則進入c模式;
@
在target還是在host上執行, 在指令前加上@則在target上執行, 否則在host上執行
>
指令輸出重定向
<
指令輸入重定向
資料轉換:鍵入整數或字元後回車可以顯示該整數的十進位制及十六進位制值。也可以鍵入字元常量或符號地址。
比如:
->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
使用 ?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
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
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
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
實時改變任務執行的優先順序
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)
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資訊
注意分清是對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上配置電子盤和硬碟:
usrAtaConfig(0,0,“HDISK”) 載入硬碟
usrAtaConfig(1,0,“FDISK”) 載入電子盤
usrTffsConfig
將Flash作為一個dos檔案系統載入
usrTffsConfig(int drive, int removable, char * fileName)
如在PPC板上配FLASH:
usrTffsConfig(0,0,“輸入自己的裝置名”) 載入Flash盤
tffsDevFormat
格式化flash:
STATUS tffsDevFormat
(
int tffsDriveNo, /* TrueFFS drive number (0 - DRIVES-1) */
int arg /* pointer to tffsDevFormatParams structure */
)
例如: tffsDevFormat 0, 0
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()。
可對系統物件(任務、訊息佇列、訊號量等)和儲存器使用情況進行觀察的瀏覽器。可以方便地監視使用者的目標系統。Browser彙總了應用程序,記憶體消耗和一個目標記憶體的映像。通過Browser,使用者可以觀察訊號量、訊息佇列、記憶體分配、看門狗計時器、堆疊使用情況、目標 CPU使用率、物件模組結構和符號表以及每個任務的詳細資訊。
可以分析: 記憶體洩漏、記憶體碎片、堆疊溢位、優先順序反轉
Tools條顯示的是歸taget agent管理的記憶體,歸Tornado tools使用;
Application條顯示的是歸目標系統內所有任務使用;
以上2者獨立分開,共同佔用目標板的記憶體;
欄內顯示的是所有模組的所佔用記憶體的資訊;
可以知道該模組的地址空間,比較有用的是他的符號表;
可以檢查堆疊狀況
由於輔助時鐘和目前3gcn內的衝突,建議不要使用,否則會造成系統紊亂;
Std Excep. Handler standard exception handler
Default Trap default trap (Sparc)
Uninit. Int uninitialized interrupt vector
Corrupted Int corrupted interrupt vector
可以檢視諸如訊息佇列、訊號量、watchdog、任務、系統記憶體等的狀況。如:
condition 填入條件,變成條件斷點
keep 指一直有效
delete 在斷點到達後將之刪除
disable 先不讓該斷點有效
Source
以高階語言(c、c++)顯示,預設的顯示方式
Disassembly
以反彙編方式顯示
MixedSource and Disassembly
混合高階和反彙編方式顯示,配和修改一些暫存器值如pc,來達到控制除錯流程。
建立Target Server時需要配置的變數。
提供了幾種target/host聯絡方式:
wdbpipe 一般用於vxworks目標模擬
netrom 我們用不著
wdbrpc 用的最多的一種,只要是ip連線的都行,需要配置目標機的IP地址
wdbserial 使用串列埠,填入連線的串列埠號,及其波特率即可
RedirectTarget IO
重定向目標機上的全域性stdin、 stdout和stderr 到target server。如果沒有建立控制檯視窗,當有字元從目標機發送過來的時候, WTX 事件被髮送給所有的WTX 工具 。
Create Console Window
在target server 所在的主機上建立一個虛擬控制檯視窗作為目標機的I/O口。
Redirect Target Shell
建立一個虛擬控制檯視窗,當前target shell的標準input、output和error被重定向到該視窗。
在執行中可以記錄一些重要資訊(比如:任務排程狀況、訊號量、訊息佇列、watchdog,、記憶體、訊號)的狀況,從而便於對複雜的實時系統執行狀況進行分析。
可以對排程異常、資源掛死、宕機等進行分析。
根據需要,可以記錄3個層次上資料:
- Context Switch Event-Logging Level (CSE Level)
- Task State Transition Event-Logging Level (TST Level)
- Additional Instrumentation Event-Logging Level (AIL Level)
可以設定一定大小的記憶體,在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
儲存到檔案
Deferred
host取一次,taget記一次。
Continuous
target在記到一定程度後,傳送到後臺,繼續記錄,連續進行。
Post-Mortem
target將資料記錄到保留記憶體,在異常熱啟動後可再取得相應資料,從而可以知道是異常在哪裡。
Ø 具體圖形的意義可以參看幫助”Event Dictionary”。
Ø 可以選擇關心的任務,關心的實體,而將不關心的部分隱藏掉。
Ø 為便於查詢,可以自己建立幾個實體以便標識,比如訊號量。在錯誤處操作,從而可以很快定位,而不用再達海中撈針。
通過設定一些觸發器,觸發一些操作,主要有以下2個功能:
Ø 可以監控變數,函式的執行情況,特別對變數被修改這種問題有幫助。
Ø 和windview配合使用,使記錄可控。
telnet功能類似shell,不用起tornado而已,省卻啟動target server,對release比較有用。使用方法如下:
在包含了INCLUDE_TELNET 後能使用telnet;如果要加上user/pass驗證,則需要加上 INCLUDE_SECURITY 。但注意的是,下圖中的pass為加密後的密碼,可以使用/host/x86-win32/bin/vxencrypt來將密碼加密。
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);
}
在任務除錯模式下,在一個整合環境中,在一個任務中除錯,在另一個任務中設定斷點,設定的斷點不起作用。這是因為一個偵錯程式只能處理一個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的接收佇列中。
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 | Continue(F5)繼續執行程式。
* 系統在設定的斷點處停下。
* 在函式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中的斷點處停下。
中斷服務程式只能在系統除錯模式下除錯,不能在任務除錯模式下除錯。因為中斷服務程式是作為系統的一部分執行,不是以任務方式執行,因此不需要為它產生任務。
中斷服務程式除錯步驟:
* 用-g選項編譯原始碼產生目標檔案。
* 下載產生的目標檔案。
* 在MultiTaskTestInit函式的開始設定斷點。
* 在Debugger命令視窗輸入命令attach system進入系統除錯模式。
* 執行選單命令Debug | Continue繼續執行程式。
* 如果產生相應的中斷,程式就會在中斷服務程式的斷點處停下。進行需要的除錯。
使用logMsg()列印,不能用printf()。
2 V2支撐的除錯手段
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低四位=1,dwRunTickSum欄位清零;其餘不清零。
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)
列印與邏輯節點(m,u)間的所以通訊訊息。
VOID r04node(BYTE md_in, BYTE ut_in, BYTE sut_in)
列印指定節點的資訊
VOID r04dogoff()
關閉硬體狗,要除錯程式,需先關閉看門狗,否則系統將被複位。
典型錯誤: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
1) 使用tornado中view\mixed source and disassembly,會將程式碼和反彙編混合顯示,反彙編中會顯示具體位置,比對異常記錄中出錯位置指標就可找到具體程式碼行。
2) Error.log會記錄異常發生時該程序的接收訊息內容和事件號,如果內容比較少的話,可找一塊沒有使用的記憶體,將該內容敲進去;如果比較多的話,可將接收內容放到一全域性陣列,重編版本。在shell中啟動一任務,入口是該程序入口,並停在該程序入口處,修改相關內容指標,狀態,事件號等,跟蹤下去直到出錯的行。
3) 最簡便辦法是使用bh,硬體斷點,一些情況可在前後加上記憶體頁保護;這兩種均能找到具體行,如果被修改的有規律,可往被修改的地址往上查。
常見錯誤:死迴圈、pagefault、除0錯、越界修改記憶體、
3 V3支撐的除錯手段
平臺的OSS在vxWorks的基礎上建立了一些通訊任務、監控任務、485任務、排程任務等等。其中在排程任務下又引入了程序的概念,程序的用法見相關設計文件。
->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是程序的執行次數。
如果不設定斷點,一般是不會有任何顯示的,因為程序的執行時間很短。
在狀態管理中心程序入口設定斷點:
-> b SCS_BSMgt
斷點到達:
->
Break at 0x06086dac:SCS_BSMgt Task: 0x7e97c40(SCH9)
檢視當前執行程序資訊,就可以看到顯示了狀態管理中心程序:
->OSS_DbgGetCurPCBInfo
Current ProcessType 0x402, InstanceNo 0x1 , wTno 0x9,Status 0x2
檢視當前程序的訊息,可以看到程序訊息資訊:
->OSS_DbgGetCurMsgInfo
Current Msg 0x5dd issent From Pno 0x4020001 ,wUnit 0xffff To Pno 0x4020001 ,wUnit 0xffff
訊息號0x5dd,十進位制為1501,可以看出是TIMER1訊息。
-> 0x5dd
value = 1501 = 0x5dd
取消斷點:
è bd SCS_BSMgt
再恢復SCH9的執行
-> tr SCH9
這時再看當前程序的訊息,已經沒有可顯示的了。
->OSS_DbgGetCurMsgInfo
No Running Process,No message!
任務間通訊(包括不同調度任務的程序間)是通過佇列來進行的。因此每個任務都有一個佇列,該任務不停地從佇列中取訊息進行處理,相當於消費者,如果佇列為空,則任務掛起,等待訊息。其他任務(如通訊任務等)向該任務的佇列傳送訊息,相當於生產者。在一個穩定的系統中,訊息佇列應該基本不堆積訊息。以排程任務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。這一切對上層應用而言是透明的。
在狀態管理中心程序入口設定斷點:
-> b SCS_BSMgt
斷點到達,可以看到排程任務9被斷住。
->
Break at 0x06086dac:SCS_BSMgt Task: 0x7e97c40(SCH9)
還可以用msgQNumMsgs(0x7e97e58)看當前訊息個數。
通過OSS_DbgShowQueueCtl除錯函式,可以看出排程任務9地佇列堆積了22個訊息。
->OSS_DbgShowQueueCtl
Display the contentof all used queue control block
QueueName | EntrySize | TotalCount | UsedCount | VxWorksId | ptHead |
CommRudpProto | 4 | 4000 | 0 | 7f43400 | VXWORKS |
SCH0 | 4 | 4000 | 0 | 7f337d8 | VXWORKS |
SCH1 | 4 | 4000 | 0 | 7f22b60 | VXWORKS |
SCH2 | 4 | 4000 | 0 | 7f11ee8 | VXWORKS |
SCH3 | 4 | 4000 | 0 | 7f01270 | VXWORKS |
SCH4 | 4 | 4000 | 0 | 7ef05f8 | VXWORKS |
SCH5 | 4 | 4000 | 0 | 7edf980 | VXWORKS |
SCH6 | 4 | 4000 | 0 | 7eced08 | VXWORKS |
SCH7 | 4 | 4000 | 0 | 7ebe090 | VXWORKS |
SCH8 | 4 | 4000 | 0 | 7ead418 | VXWORKS |
SCH9 | 4 | 4000 | 22 | 7e9c7a0 | VXWORKS |
RS485 | 16 | 4000 | 0 | 7e83e28 | VXWORKS |
USB | 16 | 1 | 0 | 7e7fb98 | VXWORKS |
EXCINT | 16 | 4000 |