2

我正在AT91SAM9263開發板上進行嵌入式開發,並遇到一個奇怪的問題。它正在運行Debian Linux內核2.6.18.4,並使用arm-linux-gcc 3.4.6進行交叉編譯,並使用uClibc-0.9.28作爲C庫。我正在調試一個內核設備驅動程序,並且一個特定的函數沒有出現在System.map文件中。可以理解的是,我可以不在它上面設置一個斷點。奇怪的是,如果我闖入它的調用函數,我不能介入它 - 使用gdb的nexti命令執行它,但跳過源。該函數是atmel_rx_chars(struct uart_port * port)。它是atmel_serial.c中聲明的一個靜態void函數,它的一個例子出現在[1]。在同一個文件中還有其他的靜態void函數(例如atmel_tx_chars(struct uart_port * port)),它們在同一個文件中聲明,實際上在System.map文件中被索引。根據[2]「System.map由'nm vmlinux'生成,而無關或不感興趣的符號被清除。」我曾嘗試使用nm(以及objdump)查看所有符號,但它仍然不出現在輸出中。但是,當我grep atmel_rx_chars vmlinux它返回一個匹配。我曾經認爲自己是一個超級用戶,但在此之後我真的很難過。任何意見將不勝感激。從Linux System.map中缺少的函數名稱和地址

謝謝

Jayce

[1] http://lxr.free-electrons.com/source/drivers/serial/atmel_serial.c#L379
[2] http://www.faqs.org/docs/Linux-HOWTO/Kernel-HOWTO.html#systemmap

+0

你是如何編譯代碼的?聽起來好像代碼是用優化開關編譯的,在gdb跳過它或system.map與內核不同步的情況下? – t0mm13b 2010-02-20 02:00:21

+0

內核編譯時沒有進行優化,並且打開了-g(調試信息)。同樣,我覺得有趣的是,在同一個文件中定義的相同返回類型和簽名的其他函數映射到System.map文件中,並且對調試器可見,但是這個函數神祕地缺失。不過謝謝你的建議。 -jayce – user277453 2010-02-22 14:46:33

+0

我誤會了 - 內核是用-Os編譯的,而-g是打開的。我試圖用-O0進行編譯,但是在[kernel root] /net/core/dev.c + 1710和+1717中斷了。 – user277453 2010-02-22 20:00:46

回答

0

對於任何人誰可能有興趣,我無法弄清楚,爲什麼它不映射atmel_rx_chars到System.map中的地址。您仍然可以像平常一樣設置斷點,以便在這種情況下進行調試。我想當我尋找答案時應該更加明顯。無論如何,在這個例子中,gdb的命令行中鍵入

b source_file.c:line# 

所以,這將是

b atmel_serial.c:381 

,它會破壞每當你打出了「失蹤」的程序。不過,這仍然是一個不完整的解決方案。分解成特定的行可行,但它不會離開調用函數(atmel_handle_receive)的堆棧框架,因此atg_rx_chars的本地不能被gdb訪問。一如往常,任何幫助或見解將不勝感激。希望這是一個很好的起點,如果有其他人遇到這個問題或喜歡它。

謝謝

Jayce

2

你沒有看到它是因爲編譯器內聯該功能的原因。它被聲明爲靜態的,只在一個地方被調用,以便編譯器將其內聯。如果您想在其上放置斷點,請更改源代碼,使其不再聲明爲靜態並重新編譯。