亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 809 | 回復(fù): 0
打印 上一主題 下一主題

內(nèi)核 System.map文件的作用 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-12-04 18:41 |只看該作者 |倒序?yàn)g覽
有關(guān)System.map文件的信息好象很缺乏。其實(shí)它一點(diǎn)也不神秘,并且在整個(gè)事情當(dāng)中它并不象看上去那么得重要。但是由于缺乏必要的文檔說(shuō)明,使其顯得比較神秘。它就象耳垂,我們每個(gè)人都有,但卻不知道是干什么用的。本網(wǎng)頁(yè)就是用來(lái)說(shuō)明這個(gè)問(wèn)題的。
注意,我并不會(huì)是百分之一百正確的。例如,一個(gè)系統(tǒng)很可能沒(méi)有/proc文件系統(tǒng)支持,但是大多數(shù)系統(tǒng)肯定有。這里我假定你是“隨大流的”,并有一個(gè)典型配置的系統(tǒng)。
某些有關(guān)內(nèi)核出錯(cuò)(oops)的闡述來(lái)自于Alessandro Rubini的“Linux設(shè)備驅(qū)動(dòng)程序” 一書,我是從其中學(xué)到大部分內(nèi)核編程知識(shí)的。
什么是符號(hào)(Symbols)?
在編程中,一個(gè)符號(hào)(symbol)是一個(gè)程序的創(chuàng)建塊:它是一個(gè)變量名或一個(gè)函數(shù)名。 正如你自己編制的程序一樣,內(nèi)核具有各種符號(hào)也是不應(yīng)該感到驚奇的。當(dāng)然,區(qū)別在 于內(nèi)核是一非常復(fù)雜的代碼塊,并且含有許多、許多的全局符號(hào)。
內(nèi)核符號(hào)表(Kernel Symbol Table)是什么東西?
內(nèi)核并不使用符號(hào)名。它是通過(guò)變量或函數(shù)的地址(指針)來(lái)使用變量或函數(shù)的,而 不是使用size_t BytesRead,內(nèi)核更喜歡使用(例如)c0343f20來(lái)引用 這個(gè)變量。
而另一方面,人們并不喜歡象c0343f20這樣的名字。我們跟喜歡使用象 size_t BytesRead這樣的表示。通常,這并不會(huì)帶來(lái)什么問(wèn)題。內(nèi)核主要 是用C語(yǔ)言寫成的,所以在我們編程時(shí)編譯器/連接程序允許我們使用符號(hào)名,并且使 內(nèi)核在運(yùn)行時(shí)使用地址表示。這樣大家都滿意了。
然而,存在一種情況,此時(shí)我們需要知道一個(gè)符號(hào)的地址(或者一個(gè)地址對(duì)應(yīng)的 符號(hào))。這是通過(guò)符號(hào)表來(lái)做到的,與gdb能夠從一個(gè)地址給出函數(shù)名(或者給出一個(gè) 函數(shù)名的地址)的情況很相似。符號(hào)表是所有符號(hào)及其對(duì)應(yīng)地址的一個(gè)列表。這里是 一個(gè)符號(hào)表例子:
   c03441a0 B dmi_broken   c03441a4 B is_sony_vaio_laptop   c03441c0 b dmi_ident   c0344200 b pci_bios_present   c0344204 b pirq_table   c0344208 b pirq_router   c034420c b pirq_router_dev   c0344220 b ascii_buffer   c0344224 b ascii_buf_bytes   
你可以看出名稱為dmi_broken的變量位于內(nèi)核地址c03441a0處。
什么是System.map文件?
有兩個(gè)文件是用作符號(hào)表的:
/proc/ksyms
System.map
這里,你現(xiàn)在可以知道System.map文件是干什么用的了。
每當(dāng)你編譯一個(gè)新內(nèi)核時(shí),各種符號(hào)名的地址定會(huì)變化。
/proc/ksyms 是一個(gè) "proc文件" 并且是在內(nèi)核啟動(dòng)時(shí)創(chuàng)建的。實(shí)際上 它不是一個(gè)真實(shí)的文件;它只是內(nèi)核數(shù)據(jù)的簡(jiǎn)單表示形式,呈現(xiàn)出象一個(gè)磁盤文件似 的。如果你不相信我,那么就試試找出/proc/ksyms的文件大小來(lái)。因此, 對(duì)于當(dāng)前運(yùn)行的內(nèi)核來(lái)說(shuō),它總是正確的..
然而,System.map卻是文件系統(tǒng)上的一個(gè)真實(shí)文件。當(dāng)你編譯一個(gè)新內(nèi)核時(shí),你原 來(lái)的System.map中的符號(hào)信息就不正確了。隨著每次內(nèi)核的編譯,就會(huì)產(chǎn)生一個(gè)新的 System.map文件,并且需要用該文件取代原來(lái)的文件。
什么是一個(gè)Oops?
在自己編制的程序中最常見(jiàn)的出錯(cuò)情況是什么?是段出錯(cuò)(segfault),信號(hào)11。
Linux內(nèi)核中最常見(jiàn)的bug是什么?也是段出錯(cuò)。除此,正如你想象的那樣,段出 錯(cuò)的問(wèn)題是非常復(fù)雜的,而且也是非常嚴(yán)重的。當(dāng)內(nèi)核引用了一個(gè)無(wú)效指針時(shí),并不 稱其為段出錯(cuò) -- 而被稱為"oops"。一個(gè)oops表明內(nèi)核存在一個(gè)bug,應(yīng)該總是提出 報(bào)告并修正該bug。
請(qǐng)注意,一個(gè)oops與一個(gè)段出錯(cuò)并不是一回事。你的程序并不能從段出錯(cuò)中恢復(fù) 過(guò)來(lái),當(dāng)出現(xiàn)一個(gè)oops時(shí),并不意味著內(nèi)核肯定處于不穩(wěn)定的狀態(tài)。Linux內(nèi)核是非常 健壯的;一個(gè)oops可能僅殺死了當(dāng)前進(jìn)程,并使余下的內(nèi)核處于一個(gè)良好的、穩(wěn)定的 狀態(tài)。
一個(gè)oops并非是內(nèi)核死循環(huán)(panic)。在內(nèi)核調(diào)用了panic()函數(shù)后,內(nèi)核就不能 繼續(xù)運(yùn)行了;此時(shí)系統(tǒng)就處于停頓狀態(tài)并且必須重啟。如果系統(tǒng)中關(guān)鍵部分遭到破壞 那么一個(gè)oops也可能會(huì)導(dǎo)致內(nèi)核進(jìn)入死循環(huán)(panic)。例如,設(shè)備驅(qū)動(dòng)程序中 出現(xiàn)的oops就幾乎不會(huì)導(dǎo)致系統(tǒng)進(jìn)行死循環(huán)。
當(dāng)出現(xiàn)一個(gè)oops時(shí),系統(tǒng)就會(huì)顯示出用于調(diào)試問(wèn)題的相關(guān)信息,比如所有CPU寄存器 中的內(nèi)容以及頁(yè)描述符表的位置等,尤其會(huì)象下面那樣打印出EIP(指令指針)的內(nèi)容:
  EIP: 0010:[]   Call Trace: []   
一個(gè)Oops與System.map文件有什么關(guān)系呢?
我想你也會(huì)認(rèn)為EIP和Call Trace所給出的信息并不多,但是重要 的是,對(duì)于內(nèi)核開發(fā)人員來(lái)說(shuō)這些信息也是不夠的。由于一個(gè)符號(hào)并沒(méi)有固定的地址, c010b860可以指向任何地方。
為了幫助我們使用oops含糊的輸出,Linux使用了一個(gè)稱為klogd(內(nèi)核日志后臺(tái)程序)的 后臺(tái)程序,klogd會(huì)截取內(nèi)核oops并且使用syslogd將其記錄下來(lái),并將某些象c010b860 的信息轉(zhuǎn)換成我們可以識(shí)別和使用的信息。換句話說(shuō),klogd是一個(gè)內(nèi)核消息記錄器(logger), 它可以進(jìn)行名字-地址之間的解析。一旦klogd開始轉(zhuǎn)換內(nèi)核消息,它就使用手頭的記錄器, 將整個(gè)系統(tǒng)的消息記錄下來(lái),通常是使用syslogd記錄器。
為了進(jìn)行名字-地址解析,klogd就要用到System.map文件。我想你現(xiàn)在 知道一個(gè)oops與System.map的關(guān)系了。
深入說(shuō)明: 其實(shí)klogd會(huì)執(zhí)行兩類地址解析活動(dòng)。
靜態(tài)轉(zhuǎn)換,將使用System.map文件。
動(dòng)態(tài)轉(zhuǎn)換,該方式用于可加載模塊,不使用System.map,因此與本討論沒(méi)有關(guān)系,但我仍然對(duì)其加以簡(jiǎn)單說(shuō)明。
Klogd動(dòng)態(tài)轉(zhuǎn)換
假設(shè)你加載了一個(gè)產(chǎn)生oops的內(nèi)核模塊。于是就會(huì)產(chǎn)生一個(gè)oops消息,klogd就會(huì)截獲它,并發(fā)現(xiàn)該oops發(fā)生在d00cf810處。由于該地址屬于動(dòng)態(tài)加載模塊,因此在System.map文件中沒(méi)有對(duì)應(yīng)條目。klogd將會(huì)在其中尋找并會(huì)毫無(wú)所獲,于是斷定是一個(gè)可加載模塊產(chǎn)生了oops。此時(shí)klogd就會(huì)向內(nèi)核查詢?cè)摽杉虞d模塊輸出的符號(hào)。即使該模塊的編制者沒(méi)有輸出其符號(hào),klogd也起碼會(huì)知道是哪個(gè)模塊產(chǎn)生了oops,這總比對(duì)一個(gè)oops一無(wú)所知要好。
還有其它的軟件會(huì)使用System.map,我將在后面作一說(shuō)明。
System.map應(yīng)該位于什么地方?
System.map應(yīng)該位于使用它的軟件能夠?qū)ふ业降牡胤剑簿褪钦f(shuō),klogd會(huì)在什么地方尋找它。在系統(tǒng)啟動(dòng)時(shí),如果沒(méi)有以一個(gè)參數(shù)的形式為klogd給出System.map的位置,則klogd將會(huì)在三個(gè)地方搜尋System.map。依次為:
/boot/System.map
/System.map
/usr/src/linux/System.map
System.map 同樣也含有版本信息,并且klogd能夠智能化地搜索正確的map文件。例如,假設(shè)你正在運(yùn)行內(nèi)核2.4.18并且相應(yīng)的map文件位于/boot/System.map,F(xiàn)在你在目錄/usr/src/linux中編譯一個(gè)新內(nèi)核2.5.1。在編譯期間,文件 /usr/src/linux/System.map就會(huì)被創(chuàng)建。當(dāng)你啟動(dòng)該新內(nèi)核時(shí),klogd將首先查詢 /boot/System.map,確認(rèn)它不是啟動(dòng)內(nèi)核正確的map文件,就會(huì)查詢 /usr/src/linux/System.map, 確定該文件是啟動(dòng)內(nèi)核正確的map文件并開始讀取其中的符號(hào)信息。
幾個(gè)注意點(diǎn):
在2.5.x系列內(nèi)核的某個(gè)版本,Linux內(nèi)核會(huì)開始untar成linux-version,而非只是linux (請(qǐng)舉手表決 -- 有多少人一直等待著這樣做?)。我不知道klogd是否已經(jīng)修改為在/usr/src/linux-version/System.map中搜索。TODO:查看klogd源代碼。
在線手冊(cè)上對(duì)此也沒(méi)有完整描述,請(qǐng)看:
   # strace -f /sbin/klogd | grep 'System.map'   31208 open("/boot/System.map-2.4.18", O_RDONLY|O_LARGEFILE) = 2        
顯然,不僅klogd在三個(gè)搜索目錄中尋找正確版本的map文件,klogd也同樣知道尋找名字為 "System.map" 后加"-內(nèi)核版本",象 System.map-2.4.18. 這是klogd未公開的特性。
有一些驅(qū)動(dòng)程序?qū)⑹褂肧ystem.map來(lái)解析符號(hào)(因?yàn)樗鼈兣c內(nèi)核頭連接而非glibc庫(kù)等),如果沒(méi)有System.map文件,它們將不能正確地工作。這與一個(gè)模塊由于內(nèi)核版本不匹配而沒(méi)有得到加載是兩碼事。模塊加載是與內(nèi)核版本有關(guān),而與即使是同一版本內(nèi)核其符號(hào)表也會(huì)變化的編譯后內(nèi)核無(wú)關(guān)。
還有誰(shuí)使用了System.map?
不要認(rèn)為System.map文件僅對(duì)內(nèi)核oops有用。盡管內(nèi)核本身實(shí)際上不使用System.map,其它程序,象klogd,lsof,
   satan# strace lsof 2>&1 1> /dev/null | grep System   readlink("/proc/22711/fd/4", "/boot/System.map-2.4.18", 4095) = 23   
ps,
   satan# strace ps 2>&1 1> /dev/null | grep System   open("/boot/System.map-2.4.18", O_RDONLY|O_NONBLOCK|O_NOCTTY) = 6   
以及其它許多軟件,象dosemu,需要有一個(gè)正確的System.map文件。
如果我沒(méi)有一個(gè)好的System.map,會(huì)發(fā)生什么問(wèn)題?
假設(shè)你在同一臺(tái)機(jī)器上有多個(gè)內(nèi)核。則每個(gè)內(nèi)核都需要一個(gè)獨(dú)立的 System.map文件!如果所啟動(dòng)的內(nèi)核沒(méi)有對(duì)應(yīng)的System.map文件,那么你將定期地看到這樣一條信息:
System.map does not match actual kernel (System.map與實(shí)際內(nèi)核不匹配)
不是一個(gè)致命錯(cuò)誤,但是每當(dāng)你執(zhí)行ps ax時(shí)都會(huì)惱人地出現(xiàn)。有些軟件,比如dosemu,可能不會(huì)正常工作。最后,當(dāng)出現(xiàn)一個(gè)內(nèi)核oops時(shí),klogd或ksymoops的輸出可能會(huì)不可靠。
我如何對(duì)上述情況進(jìn)行補(bǔ)救?
方法是將你所有的System.map文件放在目錄/boot下,并使用內(nèi)核版本號(hào)重新對(duì)它們進(jìn)行命名。假設(shè)你有以下多個(gè)內(nèi)核:
/boot/vmlinuz-2.2.14
/boot/vmlinuz-2.2.13
那么,只需對(duì)應(yīng)各內(nèi)核版本對(duì)map文件進(jìn)行改名,并放在/boot下,如:
   /boot/System.map-2.2.14   /boot/System.map-2.2.13
如果你有同一個(gè)內(nèi)核的兩個(gè)拷貝怎么辦?例如:
/boot/vmlinuz-2.2.14
/boot/vmlinuz-2.2.14.nosound
最佳解決方案將是所有軟件能夠查找下列文件:
   /boot/System.map-2.2.14   /boot/System.map-2.2.14.nosound
但是說(shuō)實(shí)在的,我并不知道這是否是最佳情況。我曾經(jīng)見(jiàn)到搜尋"System.map-kernelversion",但是對(duì)于搜索"System.map-kernelversion.othertext"的情況呢? 我不太清楚。此時(shí)我所能做的就是利用這樣一個(gè)事實(shí):/usr/src/linux是標(biāo)準(zhǔn)map文件的搜索路徑,所以你的map文件將放在:
/boot/System.map-2.2.14
/usr/src/linux/System.map (對(duì)于nosound版本)
你也可以使用符號(hào)連接:
   System.map-2.2.14   System.map-2.2.14.sound   System.map -> System.map-2.2.14.sound


本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u1/34267/showart_1679840.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP