- 走入IBM小型機世界
- Orian編著
- 185字
- 2018-12-28 23:12:16
2.5 DUMP和DUMP分析
沒有完美無缺的系統,AIX和pSeries小型機盡管穩定可靠,系統也不可避免會出現嚴重的故障,DUMP就是幫助技術人員對系統發生的故障進行分析的專用功能。
2.5.1 DUMP的概念
為了增強故障分析能力,IBM的服務器增加了對設備故障當前環境保存的功能,就是保存一份設備故障時的內存、CPU寄存器、IO等設備的數據和狀態信息,如果系統并沒有停住,只是某個程序死掉,會產生CORE DUMP,在當前目錄下產生一個CORE文件。而如果操作系統死掉,則產生System DUMP或者System Crash,通常會引起機器停機。DUMP將記錄如圖2-9所示。通過這些信息,開發和維護人員可以分析是什么原因導致的系統故障。當發生系統DUMP的時候,機器將會被宕下來。可能的原因包括:系統在進行內核操作時發生了未知的意外或者不能對其進行正常處理,都會引起DUMP。也可以由系統管理員發出命令,強制系統DUMP。

圖2-9 系統和程序DUMP的內容
當系統進行DUMP時,DUMP管理設施自動將內核相關的數據(kernel segment0及其他由內核或者內核擴展程序記錄在主DUMP表中的內存塊)復制到主DUMP設備。可以把DUMP理解為系統當時的一個快照,供以后進行分析,分析DUMP可以在其他機器上進行,但需要復制一份此機器的內核程序,即unix_mp或unix_mp64。沒有對應于DUMP的內核程序(不可以使用其他機器的文件,即使是相同的操作系統版本也不行)是無法進行DUMP分析的。
2.5.2 估計DUMP大小
由于DUMP是內存數據記錄,而內存的使用量依據系統運行情況在改變,所以DUMP大小也隨時改變。了解當前系統DUMP將會有多大可以通過如下命令:
# smit dump_estimate
或者直接執行命令行命令:
# sysdumpdev -e 0453-041 Estimated dump size in bytes: 850395136
了解了DUMP大小后需要創建足夠大的主DUMP設備(一個邏輯卷)用來裝載DUMP。在默認情況下,系統已經生成了DUMP設備,則需要查看DUMP空間是否足夠:
#mklv -y dumplv -t sysdump rootvg 15 →在 rootvg 上創建 15 個 PP 大小的 DUMP 設備dumplv #sysdumpdev -s /dev/dumplv -P →設置主DUMP設備為/dev/dumplv primary /dev/dumplv secondary /dev/sysdumpnull copy directory /var/adm/ras forced copy flag FALSE always allow dump FALSE dump compression OFF
為了防止在主DUMP設備出問題的時候,無法保存DUMP,DUMP管理設施允許使用第二個DUMP設備:
#mklv -y hd7 -t sysdump rootvg 15 → 創建15個pp大小的DUMP設備,名為hd7 #sysdumpdev -s /dev/hd7 -p → 制定此設備為第二個DUMP設備 primary /dev/dumplv secondary /dev/hd7 copy directory /var/adm/ras forced copy flag FALSE always allow dump FALSE dump compression OFF
DUMP管理設施還允許將DUMP出來的數據在系統下一次啟動后,復制到指定目錄。默認目錄地址是/var/adm/ras/為了防止復制的目錄不夠大,不能正確復制DUMP,所以要檢查目錄空間:
#df -k /var Filesystem 1024-blocks Free %Used Iused %Iused Mounted on /dev/hd9var 32768 31268 5% 143 64% /var
在本例里,/var文件系統的空間是32MB,如果想增加文件系統空間,可以執行下面的命令:
# chfs -asize=+240000 /var
設定copy目錄:
# sysdumpdev -PD /var/adm/ras
當系統重新啟動,在啟動腳本文件rc.boot中包含如下內容:
# Mount /var for copycore echo "rc.boot: executing \"fsck -fp var\"" \ →檢查var文件系統 >>/../tmp/boot_log fsck -fp /var echo "rc.boot: executing \"mount /var\"" \ >>/../tmp/boot_log mount /var →mount /var文件系統 [ $? -ne 0 ] && loopled 0x518 # retrieve dump echo "rc.boot: executing \"copycore\"" \ >>/../tmp/boot_log copycore →復制DUMP umount /var
當系統重新啟動的時候,如果設置了force copy標志為TRUE,可以有提示讓你將DUMP復制到外置介質,例如磁帶。這樣磁盤目錄不夠的時候,你也有機會保留(往往DUMP設備與系統交換區共用同一邏輯卷,而系統啟動后,交換區將被覆蓋)一份系統DUMP。
如果設置了另一個“總是允許DUMP”開關(TRUE),當按下服務器reset按鈕或者預先設定的DUMP鍵盤序列的時候,系統自動生成DUMP。下面的命令設置此開關為TRUE:
# sysdumpdev -KP
如果想允許DUMP壓縮存放,則用如下命令:
# sysdumpdev -CP
如果想讓系統DUMP后自動重新啟動(對于管理員遠程管理比較有用,否則必須管理員到現場按開關重新啟動計算機),可以執行下面命令:
# lsattr -El sys0 →顯示是否自動重啟動 SW_dist_intr false Enable SW distribution of interrupts autorestart true Automatically REBOOT system after a crash boottype disk N/A conslogin enable System Console Login cpuguard disable CPU Guard frequency 1097312280 System Bus Frequency fullcore false Enable full CORE dump fwversion IBM,2b304_430 Firmware version and revision levels id_to_partition 0X04514535A2CE4701 Partition ID id_to_system 0X04514535A2CE4700 System ID iostat false Continuously maintain DISK I/O history keylock normal State of system keylock at boot time maxbuf 20 Maximum number of pages in block I/O BUFFER maxmbuf 0 Maximum Kbytes of real memory allowed for MB maxpout 0 HIGH water mark for pending write I/Os per file maxuproc 128 Maximum number of PROCESSES allowed per user minpout 0 LOW water mark for pending write I/Os per file modelname IBM,8842-41X Machine name ncargs 6 ARG/ENV list size in 4K byte blocks pre430core false Use pre-430 style CORE dump pre520tune disable Pre-520 tuning compatibility mode realmem 2031616 Amount of usable physical memory in Kbytes rtasversion 1 Open Firmware RTAS version systemid IBM,0399GCA4N Hardware system identifier # smit chgsys 使用smit進行修改 # chdev -l sys0 -a autorestart='true' 使用命令進行修改
2.5.3 系統DUMP碼分析
如果系統發生了DUMP,則首先機器會停下來,但是并沒有關電源,只是鍵盤、鼠標、網絡、終端(主控臺連接的串口終端除外)沒有任何反應;其次,在機器的液晶顯示屏上不是正常的、沒有任何提示(機器正常運行的時候)或者OK(機器關閉電源的時候),而是類似這樣的一串數字:888 102 205 0c0。
代碼含義簡要說明如下。
第一段數字888:以888開頭的表示都是DUMP。
第二段數字102:狀態碼Message Type。
第三段數字:叫做ABEND(原因)代碼,一般是硬件故障。
000:用戶生成的DUMP或者Surveillance Timeout(STO,看門狗電路監測到超時);
2xx:machine check,參考checkstop名詞的介紹;
3xx:數據訪問越界中斷(DSI,Data Storage Interrupt);
400:指令訪問越界中斷(ISI,Instruction Storage Interrupt)
5xx:外部中斷;
700:程序中斷(指令陷阱或非法指令);
800:浮點異常。
第四段數字0cX:DUMP狀態碼。
Message Type 103,105
通常103,105都是由于硬件故障引起的DUMP,下面是檢查103,105故障位置的步驟(如果你遇到102故障,也可以參考)。
(1)出現888-103-xxx-xxx提示后,按Reset鈕(電源白色按鈕旁邊的黃點)記錄下6位SRN的頭三位。
(2)再次按Reset,記錄下SRN的后3位。
(3)以后每次按Reset,會依次顯示3位FRU位置代碼,當所有的FRU位置代碼都記錄下后,液晶屏會再次顯示888,表示信息結束;而如果顯示的數字不是888而是ccc,則需要再次重復以上過程,繼續接收信息。
(4)根據FRU顯示的位置,按順序查找此硬件是否有故障。
(5)FRU位置代碼可以轉換成8位的具體位置(AB-CD-EF-GH,關于位置代碼的詳細介紹,參考Physical Location Code一節/第四天),每行的每段xx,代表位置代碼AB-CD-EF-GH中一位。
A B C D E F G H 8位的故障設備位置碼
c01 1xx 2xx 3xx 4xx 5xx 6xx 7xx 8xx 第一可能的故障設備
c02 1xx 2xx 3xx 4xx 5xx 6xx 7xx 8xx 第二可能的故障設備
c03 1xx 2xx 3xx 4xx 5xx 6xx 7xx 8xx 第三可能的故障設備
c04 1xx 2xx 3xx 4xx 5xx 6xx 7xx 8xx 第四可能的故障設備
注意
如果沒有按順序顯示c0x,而是ccx(x是2~9的數字),那么這表示是重復上次信息,跟著的位置代碼不會是完整的8段,只會包含變化的內容,即只有不同的才會顯示。例如:
c01 100 200 300 401 500 601 700 800,下一個FRU是:
cc2 602,則表示下一個FRU位置是:
cc2 100 200 300 401 500 602 700 800.(只有一段601,602不同)
位置代碼翻譯如表2-3所示。
表2-3 位置代碼翻譯

(6)如果記錄完DUMP/FRU信息,下面要恢復系統,只有一種方法:將系統電源關閉,再重新開啟。以后可以根據記錄下來的FRU位置信息,進行硬件檢查。
ABEND原因碼
(1)2xx——Machine check
通常是硬件故障導致(例如內存錯誤),不過也有可能來自原軟件原因(例如內核訪問不存在的物理地址)。其中:
200 Machine check because of a memory bus error. 內存總線錯誤。
201 Machine check because of a memory timeout. 內存訪問超時。
202 Machine check because of a memory card failure. 內存卡故障。
203 Machine check because of a out of range address. 內存訪問越界(讀寫不存在的物理地址)。
204 Machine check because of an attempt to write to ROS. 試圖寫只讀的內存地址。
205 Machine check because of an uncorrectable address parity. 不可恢復的地址校驗錯誤(通常2位地址為以上的錯誤)。
206 Machine check because of an uncorrectable ECC error. 不可恢復ECC校驗錯誤。
207 Machine check because of an unidentified error. 未知錯誤類型。
208 Machine check due to an L2 uncorrectable ECC. L2緩存不可恢復的ECC錯誤。
(2)3xx——DSI
當程序訪問的虛擬內存并沒有在物理內存中的時候,就會產生DSI(Data Storage Interrupt數據存儲訪問中斷),被稱為內存頁訪問失敗(page fault),內存頁訪問失敗是正常現象,隨時都可能發生。然而如果內存頁訪問失敗不能被解決(從磁盤交換區將此虛擬內存讀入物理內存),則會導致DSI System Crash,軟件和硬件故障都可能引起DSI Dump。其中:
300 Data storage interrupt from the processor. 更可能是CPU問題
32x Data storage interrupt because of an I/O exception from IOCC.更可能是I/O設備
38x Data storage interrupt because of an I/O exception from SLA.數據地址錯誤
(3)400——ISI
與DSI類似,如果等待執行的指令不在虛擬內存,則產生ISI(Instruct Storage Interrupt指令存儲中斷),ISI沒能夠恢復或者此時禁止了中斷(無法產生中斷,由此磁盤將交換區數據讀入物理內存),則產生ISI Dump。
(4)5xx——外部中斷
這種DUMP來自于外部設備的中斷,例如I/O總線控制器。
500 External interrupt because of a scrub memory bus error. 內存總線故障。
501 External interrupt because of an unidentified error. 未知錯誤。
51x External interrupt because of a DMA memory bus error. DMA內存總線錯誤。
52x External interrupt because of an IOCC channel check. I/O控制通道異常。
53x External interrupt from an IOCC bus timeout; x represents the IOCC number. I/O控制通道使用超時,x位代表I/O控制通道號。
54x External interrupt because of an IOCC keyboard check. 收到I/O控制通道強制檢查請求。
558 There is not enough memory to continue the IPL. 啟動的時候沒有足夠內存。
(5)600——Alignment中斷
600 Alignment Interrupt, If pre-AIX 4.3.3.3: AIX has crashed because the Portability Assist Layer(PAL)for this machine type has detected a problem. 如果是AIX 433以前版本,可能是由于操作系統不支持此硬件設備,或者是微碼問題。
605 AIX has crashed because the Portability Assist Layer (PAL) for this machine type has detected a problem(AIX 4.3.3.3 and above)類似600的故障。
(6)700——程序中斷
此類故障的直接原因是當程序進入內核調用執行的時候,遇到不能解決的問題,就調用內核的一個叫做panic的例程。這個例程進行如下處理:
如果內核debug模式打開,并且串口連接了一個字符終端,則系統進入debug狀態。否則系統掛起,并產生System DUMP。
內核調用panic例程的同時還會產生panic信息,此信息一方面送給debug終端,另一方面送給errlog,如果系統能成功生成DUMP,panic message還會記錄到DUMP中。
(7)800——浮點異常
當MSR(machine status register)標記浮點運算不可用的時候遇到浮點指令。
DUMP狀態碼
0c0——DUMP成功完成。
0c1——DUMP過程中出現I/O問題(空間無法寫入、設備故障等),DUMP失敗。
0c2——由用戶要求的DUMP正在生成。
0c3——DUMP被禁止。
0c4——DUMP設備空間不夠。
0c5——DUMP沒有開始或者失敗。
0c6——由用戶要求,DUMP到第二個DUMP設備。
0c7——DUMP等待從NFS服務器的返回信息(DUMP到NFS服務器)。
0c8——沒有DUMP設備。
0c9——DUMP正在進行中。
0cc——DUMP到主設備失敗,正在向第二個DUMP設備復制DUMP。
簡單DUMP分析
顯示最近一次DUMP狀態:
# sysdumpdev -L 0453-039 Device name: /dev/dumplv →DUMP設備名 Major device number: 10 Minor device number: 2 Size: 8837632 bytes →壓縮后大小 Uncompressed Size: 32900935 bytes →未壓縮大小 Date/Time: Fri Sep 22 13:01:41 PDT 2000 →生成時間 Dump status: 0 dump completed successfully →DUMP正常生成 Dump copy filename: /var/adm/ras/vmcore.0.Z →存在DUMP,文件是vmcore.0.Z
解壓縮DUMP數據:
# cd /var/adm/ras # uncompress vmcore.0.Z
啟動內核debug程序(在同一臺機器分析DUMP):
# kdb /var/adm/ras/vmcore.0 The specified kernel file is a UP kernel vmcore.1 mapped from @ 70000000 to @ 71fdba81 Preserving 880793 bytes of symbol table First symbol __mulh KERNEXT FUNCTION NAME CACHE (90112 bytes) allocated KERNEXT COMMANDS SPACE (4096 bytes) allocated Component Names: 1) dmp_minimal [5 entries] . . . . Dump analysis on CHRP_UP_PCI POWER_PC POWER_604 machine with 1 cpu(s) (32-bit registers) Processing symbol table... .......................done (0)>
啟動內核debug程序(在不同機器分析DUMP):
# kdb -m dump_file -u /usr/lib/boot/unix The specified kernel file is a 64-bit kernel core mapped from @ 700000000000000 to @ 7000000000120a7 Preserving 884137 bytes of symbol table First symbol __mulh KERNEXT FUNCTION NAME CACHE (90112 bytes) allocated KERNEXT COMMANDS SPACE (8192 bytes) allocated Component Dump Table not found. Kernel not included in this dump. dump core corrupted make sure /usr/lib/boot/unix refers to the running kernel
注意
以上錯誤的含義是DUMP所在機器的內核與指定的內核程序(/usr/lib/boot/unix)不一致,無法分析。因此為了在其他機器上進行DUMP分析,不但需要DUMP文件,還需要保留此機器內核文件:/unix(因為/unix一般是一個鏈接文件,要復制其鏈接的源文件而不是鏈接)。
(0)> stat → 顯示DUMP當時系統狀態 SYSTEM_CONFIGURATION: CHRP_UP_PCI POWER_PC POWER_604 machine with 1 cpu(s) (32-bit registers) SYSTEM STATUS: sysname... AIX nodename.. garbagepig release... 1 version... 5 → 操作系統版本 machine... 000931134C00 nid....... 0931134C time of crash: Mon Oct 4 14∶14∶14 2004 →DUMP時間 age of system: 3 min., 11 sec. xmalloc debug: disabled abend code: 300 → DUMP ABEND代碼 csa: 0x2ff3b400 exception struct: dar: 0x00000000 dsisr: 0x00000000: srv: 0x00000000 dar2: 0x0000000 dsirr: 0x00000000: (errno) "Error 0" > t -mk →堆棧跟蹤命令 Skipping first MST MST STACK TRACE: 0x2ff3b400 (excpt=00000018:0a000000:00000000:00000018:00000106) (intpri=3) IAR: .so_pin_more_stack+3c (000a6808): stw r3,0x18(r4) LR: .so_pin_more_stack+38 (000a6804) 2ff3b220: .soaccept+84 (000d75f8) 2ff3b290: .sodequeue+228 (000d7490) 2ff3b300: .accept1+3a8 (000d6fcc) 2ff3b380: .naccept+14 (000db2c0) 2ff3b3c0: .sys_call_ret+0 (00003a90) 00009032: .nbc_min_cache_init+4c (000c7d10) 00008001: .low+0 (00000000) (0) > cpu →顯示可切換的CPU信息 0 1 (0) > cpu 1 →轉到第一顆CPU(原來是由第0顆CPU) (1) > status →顯示正在執行的線程(2顆CPU,兩個線程) CPU TID TSLOT PID PSLOT PROC_NAME 0 205 2 204 2 wait 1 5819 88 2CA0 44 kdb_mp (1) > th * →顯示第一顆CPU處理的全部線程 …… (1) > p * →顯示第一顆CPU處理的全部進程 …… (1) >p * -s ACTIVE → 顯示所有活動進程 SLOT NAME STATE PID PPID ADSPACE CL #THS pvproc+000000 0 swapper ACTIVE 0000000 0000000 0000000000000B00 0 0001 pvproc+000280 1 init ACTIVE 0000001 0000000 000000000000E2FD 0 0001 pvproc+000500 2 wait ACTIVE 0000204 0000000 0000000000001B02 0 0001 pvproc+000780 3 wait ACTIVE 0000306 0000000 0000000000002B04 0 0001 pvproc+000A00 4 lrud ACTIVE 0000408 0000000 0000000000003B06 65 0001 pvproc+000C80 5 xmgc ACTIVE 000050A 0000000 000000000000BB16 65 0001 pvproc+000F00 6 netm ACTIVE 000060C 0000000 000000000000CB18 65 0001 pvproc+001180 7 gil ACTIVE 000070E 0000000 000000000000DB1A 65 0005 (1)> f →顯示堆棧跟蹤 pvthread+004900 STACK: [00034648].panic_trap+000000 () → 推斷原因,系統panic [021DCCC4]Duck+000018 () [021DCCC4]Duck+000018 () [021DCC7C]Daffy+000020 (00000001, 2FF3AB10) [0055E9E8]config_kmod+00016C (??, ??, ??) [0055EDCC]sysconfig+0000F8 (??, ??, ??) [00003A50].sys_call+000000 () →導致系統panic的指令在這個位置 地址 例程 偏移量 [kdb_get_memory] no real storage @ 2FF22B68 (0) > q →退出
如果程序在編譯的時候使用了附加源程序信息,則此時顯示的內容將會提供詳細的例程名,便于查找。但不幸的是幾乎所有的程序(包括AIX系統)都不會在編譯的時候附加源文件,所以要想進一步查看信息只能憑自己的經驗進行反匯編了。
2.5.4 CORE DUMP
CORE DUMP只是某個程序故障,相對比較簡單,可以直接用dbx等底層代碼調試工具進行分析。下面一個小程序可以簡單地對core文件進行分析:
#include <stdio.h> #include <sys/core.h> void main(int argc, char *argv[]) { FILE *corefile; struct core_dumpx c_file; char command[256]; if (argc != 2) { fprintf(stderr, "Usage: %s <corefile>\n", *argv); exit(1); } if ((corefile = fopen(argv[1], "r")) == NULL) { perror(argv[1]); exit(1); } fread(&c_file, sizeof(c_file), 1, corefile); fclose(corefile); sprintf(command, "lquerypv -h %s 6E0 64 | head -1 | awk '{print $6}'", argv[1]); printf("Core created by: \n"); system(command); printf("Signal number and cause of error number: %i\n", c_file. c_signo); printf("Core file type: %i\n", c_file.c_flag); printf("Number of core dump modules: %i\n", c_file.c_entries); printf("Core file format number: %i\n", c_file.c_version); printf("Thread identifier: %i\n", c_file.c_flt.th.ti_tid); printf("Process identifier: %i\n", c_file.c_flt.th.ti_pid); printf("Current effective priority: %i\n", c_file.c_flt.th.ti_pri); printf("Processor Usage: %i\n", c_file.c_flt.th.ti_cpu); printf("Processor bound to: cpu%i\n", c_file.c_flt.th.ti_cpuid); if (c_file.c_flt.th.ti_cpu>1) printf("Last Processor: cpu%i\n", c_file.c_flt.th.ti_affinity); exit(0); }