在使用perf排查問題時,我們經常會發現[kernel.kallsyms]這個模塊。這到底是個什么東西呢?
簡介:
在2.6版的內核中,為了更方便的調試內核代碼,開發者考慮將內核代碼中所有函數以及所有非棧變量的地址抽取出來,形成是一個簡單的數據塊(data blob:符號和地址對應),並將此鏈接進 vmlinux 中去。
在需要的時候,內核就可以將符號地址信息以及符號名稱都顯示出來,方便開發者對內核代碼的調試。完成這一地址抽取+數據快組織封裝功能的相關子系統就稱之為 kallsyms。
反之,如果沒有 kallsyms 的幫助,內核只能將十六進制的符號地址呈現給外界,因為它能理解的只有符號地址,並不能顯示各種函數名等符號。
kallsyms抽取了內核用到的所有函數地址(全局的、靜態的)和非棧數據變量地址,生成一個數據塊,作為只讀數據鏈接進kernel image,相當於內核中存了一個System.map。
開啟kallsyms
要在一個內核中啟用 kallsyms 功能。須設置 CONFIG_KALLSYMS 選項為y;如果要在 kallsyms 中包含全部符號信息,須設置 CONFIG_KALLSYMS_ALL 為y
查看kallsyms表:
得益於/proc文件系統,我們可以直接讀取這個表。
Example:
01 |
000000000000a018 D per_cpu__xen_vcpu |
02 |
000000000000a020 D per_cpu__xen_vcpu_info |
03 |
000000000000a060 d per_cpu__mc_buffer |
04 |
000000000000b570 D per_cpu__xen_mc_irq_flags |
05 |
000000000000b578 D per_cpu__xen_cr3 |
06 |
000000000000b580 D per_cpu__xen_current_cr3 |
07 |
000000000000b5a0 d per_cpu__xen_runstate |
08 |
000000000000b5e0 d per_cpu__xen_runstate_snapshot |
09 |
000000000000b610 d per_cpu__xen_residual_stolen |
10 |
000000000000b618 d per_cpu__xen_residual_blocked |
11 |
000000000000b620 d per_cpu__xen_clock_events |
12 |
000000000000b6a0 d per_cpu__xen_debug_irq |
13 |
000000000000b6a4 d per_cpu__xen_resched_irq |
14 |
000000000000b6a8 d per_cpu__xen_callfunc_irq |
15 |
000000000000b6ac d per_cpu__xen_callfuncsingle_irq |
列表的項:
這個應該可以很容易看出,第一列為符號地址,第二列為類型,第三列為符號名。
注意:如果發現符號地址均為0,那是因為系統保護。使用root權限查看即可。
第二列的類型:
有的符號是大寫的,有的是小寫。大寫的符號是全局的。
- b 符號在未初始化數據區(BSS)
- c 普通符號,是未初始化區域
- d 符號在初始化數據區
- g 符號針對小object,在初始化數據區
- i 非直接引用其他符號的符號
- n 調試符號
- r 符號在只讀數據區
- s 符號針對小object,在未初始化數據區
- t 符號在代碼段
- u 符號未定義
from:https://yq.aliyun.com/articles/53679