系統內存和進程內存

===系統內存===

系統內存的使用情況可以用以下公式表示:
MemTotal = MemFree +【Slab+ VmallocUsed + PageTables + KernelStack + HardwareCorrupted + Bounce + X】+【Active + Inactive + Unevictable + (HugePages_Total * Hugepagesize)】
MemTotal = MemFree +【Slab+ VmallocUsed + PageTables + KernelStack + HardwareCorrupted + Bounce + X】+【Cached + AnonPages + Buffers + (HugePages_Total * Hugepagesize)】
MemTotal = MemFree +【Slab+ VmallocUsed + PageTables + KernelStack + HardwareCorrupted + Bounce + X】+【ΣPss + (Cached – mapped) + Buffers + (HugePages_Total * Hugepagesize)】

File-backed內存,anon匿名內存,Shmem是tmpfs所使用的內存

=cached是和file有關的所有文件映射和文件系統
【buffers + cached 】= 【Active(file) + Inactive(file) + Shmem 】

=AnonPages不算tmpfs,shmem,純進程申請malloc和佔用內存
【Active(anon)+Inactive(anon)+(mlock=Unevictable)】 = 【AnonPages + Shmem】

=ΣPss = grep Pss /proc/[1-9]*/smaps | awk '{total+=$2}; END {print total}'
【AnonPages】=【ΣPss – mapped】
mapped包括代碼段和數據段

SHR是RES中”映射至文件”的物理內存總和。包括:
程序的代碼段。
動態庫的代碼段。
通過mmap做的文件映射。
通過mmap做的匿名映射,但指明瞭MAP_SHARED屬性。
通過shmget申請的共享內存。
/proc//smaps內Shared_*統計的是RES中映射數量>=2的物理內存。
/proc//smaps內Private_*統計的是RES中映射數量=1的物理內存。

===進程內存===

程序編譯:預編譯hello.i,編譯hello.s,彙編hello.o,連接a.out
ELF文件一共有4種類型:Relocatable file、Executable file、Shared object file和Core Dump file
.o文件,目標文件只是ELF文件的可重定位文件(Relocatable file)
.so文件是Shared object file
bin可執行文件是Executable file

文件結構:text代碼段,data數據段,bss預留段,other sections,(只讀,註釋,堆棧)
sectios table,string table,symbol table

1,ELF文件大小
    size:    輸出指定輸入文件各段及其總和的大小
    text       data        bss        dec        hex    filename
    1492        564         12       2068        814    sleep

ELF文件提供兩種視圖,使用objdump工具和readelf工具可以查看分析elf文件的格式
link:ELF header,program header table,sections,section header table
exec:ELF header,program header table,segments,section header table

- ELF header: 描述整個文件的組織。
- Program Header Table: 描述文件中的各種segments,用來告訴系統如何創建進程映像的。
- sections 或者 segments:segments是從運行的角度來描述elf文件,sections是從鏈接的角度來描述elf文件,
    也就是說,在鏈接階段,我們可以忽略program header table來處理此文件,
    在運行階段可以忽略section header table來處理此程序
    segments與sections是包含的關係,一個segment包含若干個section。
    當ELF文件被加載到內存中後,系統會將多個具有相同權限(flg值)section合併一個segment
    如果section的長度不是其整數倍,則導致多餘部分也將佔用一個頁
- Section Header Table: 包含了文件各個segction的屬性信息

對比三類ELF文件,我們得到了以下結論: 
(1)e_type標識了文件類型 
(2)Relocatable File(.o文件)不需要執行,因此e_entry字段爲0,且沒有Program Header Table等執行視圖 
(3)不同類型的ELF文件的Section也有較大區別,比如只有Relocatable File有.strtab節


2,彙編程序
反彙編代碼
查看源代碼被翻譯成的彙編代碼, 大概有3種方法, 
1) 通過編譯器直接從源文件生成, 如gcc -S 
2) 對目標代碼反彙編, 一種是靜態反彙編, 就是使用objdump
3) 另外一種就是對運行時的代碼反彙編, 一般通過gdb disassemble
readelf並不提供反彙編功能. 
objdump -d,查看彙編

gdb主要功能的實現依賴於一個系統函數ptrace
gdb使用ptrace的基本流程
1、gdb調試一個新進程:通過fork函數創建一個新進程,
在子進程中執行ptrace(PTRACE_TRACEME, 0, 0, 0)函數,然後通過execv()調用準備調試的程序。
2、attach到已運行進程:將pid傳遞給gdb,然後執行ptrace(PTRACE_ATTACH, pid, 0, 0)

gdb 設置斷點,向該地址寫入斷點指令INT3,即0xCC,發送SIGSTOP信號
gdb 單步調試,next指令時,會計算下一條語句對應的第一條指令的地址,然後控制目標程序走到該位置停止


3,看data和bss段內容
.data、.bss、.rodata都屬於數據段。其中,
.data    存放已初始化的全局變量、常量、靜態局部變量。
.bss    存放未初始化的全局變量,靜態局部變量,所以此段數據均爲0,僅作佔位。
.rodata    是隻讀數據段,此段的數據不可修改,存放常量
static int x1 = 0;    bss段
static int x2 = 12;    data段

4,符號表是什麼
查看ldd依賴項:objdump -x xxx.so | grep "NEEDED" 
查看動態符號表: objdump -T xxx.so
查看符號表: objdump -t xxx.so

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章