導航:首頁 > 編程語言 > linux如何定位程序崩潰的問題

linux如何定位程序崩潰的問題

發布時間:2023-07-04 12:45:20

⑴ 分析linux內核崩潰信息

分析kernel比較關鍵的就是看三點:
1) 內核會給出一個崩潰原因的猜測,這內里容是,CPU 0 Unable to handle kernel paging request at virtual address 00000000
2) 看pc指針的值,這里是epc == 00000000
3) 看調用棧Call Trace:[ //可惜後面沒給出來
通常是根據指針加上偏移值跟反匯編代碼對照,找到出問題的指令。
這個panic的原因比較明顯,應該是引用了空指針,試圖執行0x00000000出的代碼。

⑵ linux程序崩潰自動重啟

可能是因為它出現了故障吧,所以它才會重啟。

⑶ linux c 段錯誤如何定位

1. 段錯誤是什麼
一句話來說,段錯誤是指訪問的內存超出了系統給這個程序所設定的內存空間,例如訪問了不存在的內存地址、訪問了系統保護的內存地址、訪問了只讀的內存地址等等情況。這里貼一個對於「段錯誤」的准確定義(參考Answers.com):
A segmentation fault (often shortened to segfault) is a particular error condition that can occur ring the operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (e.g., attempts to write to a read-only location, or to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.
Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, "segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.
On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.
2. 段錯誤產生的原因
2.1 訪問不存在的內存地址
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = NULL;
*ptr = 0;
}
2.2 訪問系統保護的內存地址
#include<stdio.h>
#include<stdlib.h>
void main()
{
int *ptr = (int *)0;
*ptr = 100;
}
2.3 訪問只讀的內存地址
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
char *ptr = "test";
strcpy(ptr, "TEST");
}
2.4 棧溢出
#include<stdio.h>
#include<stdlib.h>
void main()
{
main();
}
等等其他原因。
3. 段錯誤信息的獲取
程序發生段錯誤時,提示信息很少,下面有幾種查看段錯誤的發生信息的途徑。
3.1 dmesg
dmesg可以在應用程序crash掉時,顯示內核中保存的相關信息。如下所示,通過dmesg命令可以查看發生段錯誤的程序名稱、引起段錯誤發生的內存地址、指令指針地址、堆棧指針地址、錯誤代碼、錯誤原因等。以程序2.3為例:
panfeng@ubuntu:~/segfault$ dmesg
[ 2329.479037] segfault3[2700]: segfault at 80484e0 ip 00d2906a sp bfbbec3c error 7 in libc-2.10.1.so[cb4000+13e000]
3.2 -g
使用gcc編譯程序的源碼時,加上-g參數,這樣可以使得生成的二進制文件中加入可以用於gdb調試的有用信息。以程序2.3為例:
panfeng@ubuntu:~/segfault$ gcc -g -o segfault3 segfault3.c
3.3 nm
使用nm命令列出二進制文件中的符號表,包括符號地址、符號類型、符號名等,這樣可以幫助定位在哪裡發生了段錯誤。以程序2.3為例:
panfeng@ubuntu:~/segfault$ nm segfault3
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484dc R _IO_stdin_used
w _Jv_RegisterClasses
08049f10 d __CTOR_END__
08049f0c d __CTOR_LIST__
08049f18 D __DTOR_END__
08049f14 d __DTOR_LIST__
080484ec r __FRAME_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
0804a014 A __bss_start
0804a00c D __data_start
08048490 t __do_global_ctors_aux
08048360 t __do_global_dtors_aux
0804a010 D __dso_handle
w __gmon_start__
0804848a T __i686.get_pc_thunk.bx
08049f0c d __init_array_end
08049f0c d __init_array_start
08048420 T __libc_csu_fini
08048430 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804a014 A _edata
0804a01c A _end
080484bc T _fini
080484d8 R _fp_hw
080482bc T _init
08048330 T _start
0804a014 b completed.6990
0804a00c W data_start
0804a018 b dtor_idx.6992
080483c0 t frame_mmy
080483e4 T main
U memcpy@@GLIBC_2.0
3.4 ldd
使用ldd命令查看二進製程序的共享鏈接庫依賴,包括庫的名稱、起始地址,這樣可以確定段錯誤到底是發生在了自己的程序中還是依賴的共享庫中。以程序2.3為例:
panfeng@ubuntu:~/segfault$ ldd ./segfault3
linux-gate.so.1 => (0x00e08000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00675000)
/lib/ld-linux.so.2 (0x00482000)

⑷ linux進程掛死應該如何定位

kill -11 發一個段錯誤信號給它,生成一個coremp文件,然後用gdb分析調用棧
對了,希望你沒有屏蔽signal 11,同時要啟用coremp。

⑸ 如何查找Linux死機原因

因為 Linux 廣泛用於生產環境,所以每一次宕機都會引起相當大的損失。它 Uptime 達到上百天也許你習以為常,但是只要 Down 十幾秒,就會立即急的滿頭大汗。真的很難以想像證交所宕機會怎麼樣,也許全國股民會鬧翻天。所以我們需要一些小技巧來查找死機的原因,從而避免死機或者內核崩潰。(話說 windows 天天藍屏也沒感覺呀 :-o 難道已經麻木了 :oops: ) 請注意:以下方法可能不適用於 Server,因為桌面環境和 Server 還是有很大區別的。 X Crash 事實上 Linux 內核很少出錯,平常我們所遇到的「死機」都是 X 無響應造成的錯覺。那 X 沒響應了應該怎麼處理呢? 通常套路是 Ctrl + Alt +F7 (F8) 切換到某個 tty,然後用 root 登陸,執行 top 查看吃資源最多的程序,然後使用 pkill/kill/killall 等命令殺死該程序。或使用組合鍵 Ctrl + Alt + Backspace重啟 X (黑日白月註:這個快捷鍵組合在最新的 Ubuntu 和 Fedora 中關閉)。 如果偶遇切換 tty 失敗或者沒響應,鋒孝可以試著使用 SSH 登陸此電腦,然後再殺死程序。也許只是 X 不響應,而內核和 SSH daemon 仍然工作,故此可以實施此法。 arch 配置 SSH daemon 萬一X 不給力,各種方法試了無效,又沒有辦法通過 SSH 登陸到此 pc,那怎麼辦呢?別著急,我們還有萬能的 「reisub」 大法。不過在啟用前先要激活內核 sysrq 功能 (via) 。系統啟動時執行:echo 「1」 > /proc/sys/Kernel/sysrq 或者修改 /etc/sysctl.conf 文件,設置 Kernel.sysrq = 1。系統異常時依次按下 Alt+sysrq+{reisub} ,然後系統會自動重啟。(有關 sysrq 請看:Linux 死機了怎麼辦?) 不建議長按 Power 按鍵強制關機,有可能損壞硬體或者丟失數據,甚至導致磁碟壞道! X 崩潰而內核完好 常見的症狀有:程序無響應,花屏,滑鼠移動指針無動作,鍵盤輸入沒有識別等。但後台的音樂可以正常播放,或者鍵盤 Caps Lock/Num Lock/Scroll Lock 按鍵按後對應 LED 可以正常亮滅。遇到此種情況可以使用上述方法重啟 X 或者電腦即可悄基橘恢復正常。 Application Crash 這個比較常見,但是也是相當難解決的。因為 Linux 上的應用軟體大部分都是開源的,所以可能沒有超高的穩定性。也許由於庫的缺少或者版本錯誤,或啟團者代碼的 Bug,都有可能導致程序出現異常。 一般遇到這種問題,建議檢查配置文件是否正確,對配置文件的錯誤修改可能導致程序的運行失敗。如果您確信配置文件沒有錯誤但是程序仍然異常,可以嘗試把配置文件刪除(注意備份!),然後再次打開軟體嘗試。

⑹ 如何分析linux crash

如前文所述,當 linux 系統內核發生崩潰的時候,可以通過 kmp 等方式收集內核崩潰之前的內存,生成一個轉儲文件 vmcore。內核開發者通過分析該 vmcore 文件就可以診斷出內核崩潰的原因,從而進行操作系統的代碼改進。那麼 crash 就是一個被廣泛使用的內核崩潰轉儲文件分析工具,掌握 crash 的使用技巧,對於定位問題有著十分重要的作用。
使用 crash 的先決條件
由於 crash 用於調試內核崩潰的轉儲文件,因此使用 crash 需要依賴如下條件:
1. kernel 映像文件 vmlinux 在編譯的時候必須指定了 -g 參數,即帶有調試信息。
2. 需要有一個內存崩潰轉儲文件(例如 vmcore),或者可以通過 /dev/mem 或 /dev/crash 訪問的實時系統內存。如果 crash 命令行沒有指定轉儲文件,則 crash 默認使用實時系統內存,這時需要 root 許可權。
3. crash 支持的平台處理器包括:x86, x86_64, ia64, ppc64, arm, s390, s390x ( 也有部分 crash 版本支持 Alpha 和 32-bit PowerPC,但是對於這兩種平台的支持不保證長期維護 )。
4. crash 支持 2.2.5-15(含)以後的 Linux 內核版本。隨著 Linux 內核的更新,crash 也在不斷升級以適應新的內核。
crash 安裝指南
要想使用 crash 調試內核轉儲文件,需要安裝 crash 工具和內核調試信息包。不同的發行版安裝包名稱略有差異,這里僅列出 RHEL 和 SLES 發行版對應的安裝包名稱如下:
表 1. crash 工具和內核調試包系統版本crash 工具名稱
內核調試信息包RHEL6.2
crashkernel-debuginfo-common
kernel-debuginfoSLES11SP2crashkernel-default-debuginfo
kernel-ppc64-debuginfo
以 RHEL 為例,安裝 crash 及內核調試信息包的步驟如下:
rpm -ivh crash-5.1.8-1.el6.ppc64.rpm
rpm -ivh kernel-debuginfo-common-ppc64-2.6.32-220.el6.ppc64.rpm
rpm -ivh kernel-debuginfo-2.6.32-220.el6.ppc64.rpm啟動 crash啟動參數說明
使用 crash 調試轉儲文件,需要在命令行輸入兩個參數:debug kernel 和 mp file,其中 mp file 是內核轉儲文件的名稱,debug kernel 是由內核調試信息包安裝的,不同的發行版名稱略有不同,以 RHEL 和 SLES 為例:
RHEL6.2:/usr/lib/debug/lib/moles/2.6.32-220.el6.ppc64/vmlinux
SLES11SP2:/usr/lib/debug/boot/vmlinux-3.0.13-0.27-ppc64.debug
使用 crash -h 或 man crash 可以查看 crash 支持的一系列選項,這里僅以常用的選項為例說明如下:
-h:列印幫助信息
-d:設置調試級別
-S:使用 /boot/System.map 作為默認的映射文件
-s:不顯示版本、初始調試信息等,直接進入命令行
-i file:啟動之後自動運行 file 中的命令,再接受用戶輸入

⑺ Linux操作系統死機處理方法有哪些

Linux 中,有如下幾種方法來獲取各種崩潰時產生的信息。

1.Core mp

Core mp 通常用來調試應用程序錯誤,當某些應用程序運行出現異常崩潰時,可以開啟系統的 core mp 功能,來得到一個程序崩潰時的內存信息,用來分析崩潰原因:

在/etc/profile里加上(或者修改)一條:

ulimit -c 0

運行命令:sysctl -w "kernel.core_name_format=/coremp/%n.core"

該命令意思是指core文件放在/coremp目錄下,文件名是進程名+.core

2.Diskmp

diskmp工具提供了在單機上創建和採集vmcore(kernel mp)的能力,而無須使用網路。當內核本身出現崩潰的時候,當前的內存和CPU狀態以及相關的信息都會被保存到一個支持diskmp的磁碟上的保留分區上。在下一次重新啟動的時候,當系統重新啟動,diskmp的初始化腳本會從保留分區中讀取保存的信息並創建一個vcore文件,然後這個文件被再次存放到/var/crash/目錄下,文件名為127.0.0.1-

如下是一個配置 HP SCSI 設備上啟用 diskmp 的過程,如果不是 HP SCSI 設備(即設備名為 /dev/sdX的形式),則無須執行第三、四兩個步驟。但需要在第一步前先執行命令: modprobe

diskmp

第一步:編輯 /etc/sysconfig/diskmp文件,將一個空白分區的設備名填入後保存退出,例如:

DEVICE=/dev/cciss/c0d0p2

第二步:初使化 mp 設備

#service diskmp initialformat

警告:該分區的所以數據會丟失。

第三步:使用 cciss_mp 模塊替換當前的 cciss 模塊:

在 /etc/modprobe.conf 找到如下行:

alias scsi_hostadapter cciss

修改為:

alias scsi_hostadapter cciss_mp

再增加一行:

options cciss_mp mp_drive=1

註:假設diskmp文件中配置的為 /dev/cciss/c0d[#a]p[#b], 請設置為: options cciss_mp mp_drive=[#a]

第四步:重建 initrd 文件:

#mv /boot/initrd-`uname -r`.img /boot/initrd-`uname -r`.img.old

#mkinitrd /boot/initrd-`uname -r`.img `uname -r`

第五步:設置 diskmp 服務能夠開機自啟動:

# chkconfig diskmp on

3.Netmp

如果使用紅旗DC4.0 或 3.0 版本系統,是不能支持 diskmp 的,可以利用netmp 來達到輸出vmcore 的目的。但是Netmp要求至少有一個伺服器以及任意數目的客戶端。伺服器用來接收客戶端死機時的信息,客戶端是經常死機的機器。

(一)伺服器配置:

(1).檢驗netmp伺服器是否安裝完畢:

rpm -q netmp-server

如果未安裝,請在光碟 RedFlag/RPMS/ 目錄中找到 netmp-server 打頭的軟體包,執行命令:

rpm -ivh netmp-server-x.x.x.rpm (x為版本號)

進行安裝。

(2).伺服器包安裝後,用命令:

passwd netmp

更改用戶的密碼.

(3).打開服務:

chkconfig netmp-server on

(4).運行伺服器:

service netmp-server start

(二)客戶端配置:

(1).校驗客戶端是否已安裝

rpm -q netmp

如果未安裝,在光碟 RedFlag/RPMS/ 目錄中找到 netm 打頭的軟體包,執行命令:

rpm -ivh netmp-x.x.x.rpm (x為版本號)

安裝.

(2).編輯文件/etc/sysconfig/netmp,添加如下行:

DEV=eth0

NETDUMPADDR=172.16.81.182

NETDUMPMACADDR=00:0C:29:79:F4:E0

172.16.81.182指 netmp 伺服器地址。

(3).運行下面的命令,出現提示符時輸入密碼:

service netmp propagate

(4).打開客戶端:

chkconfig netmp on

(5).運行客戶端:

service netmp start

(6).測試

為了測試netmp的配置是否正確,在netmp客戶機上做下面操作:

cp /usr/share/doc/netmp-xxxxxx/crash.c .

gcc -DKERNEL -DMODULE -I/lib/moles/$(uname -r)/build/include -c crash.c

insmod ./crash.o

這會造成系統崩潰,會在netmp伺服器的/var/crash/<客戶端IP>/目錄下,看到一個核心轉儲。當客戶機正在轉儲數據到伺服器的時候,你會看到一個名叫「vmcore-incomplete"的文件。當轉儲結束後,該文件會改名成 "vmcore"。"vmcore"文件的大小會變化,可能達到幾個GB.在一個內存是512M的系統上,上面的測試會產生大約510M的vmcore文件。

⑻ 程序有幾萬行代碼,編譯通過了,運行的時候崩潰了,怎麼定位錯誤面試題。。求解

呵呵,這個我最復在行啦,制說實話,調試的過程中,不怕崩掉,就怕什麼錯誤信息都沒有。
首先,既然down掉了,那麼肯定會有錯誤信息,這個通常是出在調試環境的console或log文件中,根據錯誤信息的內容初步判斷錯誤類型,如果是編譯後的初次調試,大部分情況下是空指針(空內存)訪問錯誤,即實際為null的內存被使用,當然也可能是其他錯誤。無論怎樣,在這個位置加入斷點,即在這行代碼不出錯,一旦執行該行,程序即崩潰(無法調試的環境下則加入充分的debug信息),再次運行程序,在這一點上監視各個變數,找到導致崩潰的變數值,向上追溯,找到給該變數賦值的邏輯,如果是通過其他變數傳遞過來的,則逐層向上逆向追蹤,通過斷點來找到函數的呼出元,當找到賦值操作的根源時,錯誤的原因也就找到了,接下來就是分析原因,討論對策,查找影響范圍了。。。。
down掉的程序不可怕,可怕的是沒有任何錯誤信息得bug(加上這句可以提高印象分哦O(∩_∩)O~)

⑼ 如何快速定位Linux Panic出錯的代碼行

內核Panic時,一般會列印回調,並列印出當前出錯的地址:
kernel/panic.c:panic():

#ifdef CONFIG_DEBUG_BUGVERBOSE
/*
* Avoid nested stack-mping if a panic occurs ring oops processing
*/
if (!test_taint(TAINT_DIE) && oops_in_progress <= 1)
mp_stack();
#endif

而mp_stack()調用關系如下:

mp_stack() --> __mp_stack() --> show_stack() --> mp_backtrace()

mp_backtrace()會列印整個回調,例如:

[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)

通常,上面的回調會列印出出錯的地址。
解決方案
通過分析,要快速定位出錯的代碼行,其實就是快速查找到出錯的地址對應的代碼?
相應的工具有addr2line, gdb, objmp等,這幾個工具在How to read a Linux kernel panic?都有介紹,我們將針對上面的實例做更具體的分析。
需要提到的是,代碼的實際運行是不需要符號的,只需要地址就行。所以如果要調試代碼,必須確保調試符號已經編譯到內核中,不然,回調里頭列印的是一堆地址,根本看不到符號,那麼對於上面提到的情況二而言,將無法准確定位問題。
情況一
在代碼編譯連接時,每個函數都有起始地址和長度,這個地址是程序運行時的地址,而函數內部,每條指令相對於函數開始地址會有偏移。那麼有了地址以後,就可以定位到該地址落在哪個函數的區間內,然後找到該函數,進而通過計算偏移,定位到代碼行。
情況二
但是,如果拿到的日誌文件所在的系統版本跟當前的代碼版本不一致,那麼編譯後的地址就會有差異。那麼簡單地直接通過地址就可能找不到原來的位置,這個就可能需要回調里頭的函數名信息。先通過函數名定位到所在函數,然後通過偏移定位到代碼行。

閱讀全文

與linux如何定位程序崩潰的問題相關的資料

熱點內容
逍遙安卓微信驗證 瀏覽:579
5g網路什麼時候普及河北邢台 瀏覽:709
編程和運營哪個更適合創業 瀏覽:893
尤里x怎麼升級 瀏覽:399
做業務績效考核需要哪些數據 瀏覽:433
dnf85版本劍魔刷圖加點 瀏覽:407
手機硬碟測試架可以讀取哪些數據 瀏覽:704
ug前後處理結算結果找不到文件 瀏覽:769
網頁框架拆分代碼 瀏覽:382
未來十年網路安全有什麼影響 瀏覽:362
win10更新後進不了劍靈 瀏覽:243
iphone471激活出錯 瀏覽:648
怎麼把文件拷到u盤 瀏覽:620
中伊簽署文件視頻 瀏覽:661
電信光寬頻網路不穩定 瀏覽:504
網路崗軟路由 瀏覽:995
黑莓z10在哪裡下載app 瀏覽:310
net批量下載文件 瀏覽:696
怎麼把蘋果一體機文件拷貝 瀏覽:117
sql文件怎麼寫 瀏覽:9

友情鏈接