1. 程式人生 > >VxWorks作業系統shell命令與除錯方法總結

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

^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

?

   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、 stdoutstderr 到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 | 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中的斷點處停下。

中斷服務程式只能在系統除錯模式下除錯,不能在任務除錯模式下除錯。因為中斷服務程式是作為系統的一部分執行,不是以任務方式執行,因此不需要為它產生任務。

中斷服務程式除錯步驟:

* 用-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