配置:
①要安裝軟件的依賴關系
②設置程序安裝所需要的初始化信息,比如安裝路徑,需要安裝哪些組件
③配置完成,會生成makefile文件供第二步make使用
編譯:是對源文件進行編譯鏈接生成可執行程序;
安裝:做的工作就簡單多了,就是將生成的可執行文件拷貝到配置時設置的初始路徑下;
1.1. 配置
查詢可用的配置選項: #./configure --help
配置路徑: #./configure --prefix=/usr/local/snmp
–prefix是配置使用的最常用選項,設置程序安裝的路徑;
1.2. 編譯
編譯使用make編譯: #make -f myMakefile
$@目標文件名
@^所有前提名,除副本
@+所有前提名,含副本
@<一個前提名
@?所有新於目標文件的前提名
@*目標文件的基名稱
編譯依賴的庫
makefile編譯過程中所依賴的非標准庫和頭文件路徑需要顯示指明:
CPPFLAGS -I標記非標准頭文件存放路徑
LDFLAGS -L標記非標准庫存放路徑
make -f myMakefile LDFLAGS='-L/var/xxx/lib -L/opt/mysql/lib'
CPPFLAGS='-I/usr/local/libcom/include -I/usr/local/libpng/include'
g++編譯
應用:查詢宏展開的中間文件:
在g++的編譯選項中,添加 -E選項,然後去掉-o選項 ,重定向到一個文件中即可:
g++ -g -E unixApp.cpp -I/opt/app/source > midfile
1.3. 安裝
安裝做的工作就簡單多了,就是將生成的可執行文件拷貝到配置時設置的初始路徑下:
$make install
GDB是一個由GNU開源組織發布的、UNIX/LINUX操作系統下的、基於命令行的、功能強大的程序調試工具。
對於一名Linux下工作的c++程序員,gdb是必不可少的工具;
啟動gdb $g++ -g hello.cpp -o hello
調試可執行文件: #gdb <program>
調試服務程序:
$gdb <program> <PID>
$gdb hello 11127
以下從一個完整的調試過程簡單說明最基本的幾個命令;
$gdb programmer # 啟動gdb
>break main # 設置斷點
>run # 運行調試程序
>next # 單步調試
>print var1 # 在調試過程中,我們需要查看當前某個變量值的時候,使用print 命令打印該值
>list # 顯示當前調試處的源代碼
>info b # 顯示當前斷點設置情況
同時,你需要更高效的調試:常用的調試命令都會有單字符的縮寫,使用縮寫更方便;同時,直接敲回車表示重復執行上一步命令;這在單步調試時非常有用;
pstack 跟蹤棧空間 #pstrack <program-pid>
strace常用來跟蹤進程執行時的系統調用和所接收的信號。用戶態模式切換至內核態模式
跟蹤28979進程的所有系統調用,並統計系統調用的花費時間,以及開始時間(以可視化的時分秒格式顯示),最後將記錄結果存在output.txt文件裡面
#strace -o output.txt -T -tt -e trace=all -p 28979
查看進程正在做什麼(實時輸出進程執行系統調用的情況)#strace -p <process-pid>
2.2. 目標文件分析
nm --用來列出目標文件的符號清單。
$nm myProgrammer
正文段--可執行代碼的段;,數據段--不可執行的信息或數據; BSS 段--以符號數據開頭的塊
nm命令列出的每個符號,它們的值使用十六進制來表示(缺省行為),並且在該符號前面加上了一個表示符號類型的編碼字符。常見的各種編碼包括:
A 表示絕對 (absolute),這意味著不能將該值更改為其他的連接;
B 表示 BSS 段中的符號;
C 表示引用未初始化的數據的一般符號。
objdump 顯示二進制文件的信息,就是以一種可閱讀的格式讓你更多地了解二進制文件可能帶有的附加信息
#objdump -d myprogrammer
常用參數說明
-f 顯示文件頭信息
-D 反匯編所有section (-d反匯編特定section)
-h 顯示目標文件各個section的頭部摘要信息
-x 顯示所有可用的頭信息,包括符號表、重定位入口。-x 等價於 -a -f -h -r -t 同時指定。
-i 顯示對於 -b 或者 -m 選項可用的架構和目標格式列表。
-r 顯示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反匯編後的格式顯示出來。
-R 顯示文件的動態重定位入口,僅僅對於動態目標文件有意義,比如某些共享庫。
-S 盡可能反匯編出源代碼,尤其當編譯的時候指定了-g這種調試參數時,效果比較明顯。隱含了-d參數。
-t 顯示文件的符號表入口。類似於nm -s提供的信息
查看本機目標結構(使用大端還是小端存儲):$objdump -i
反匯編程序:$objdump -d main.o
顯示符號表入口:$objdump -t main.o
readelf
$readelf -all a.out
$readelf --debug-dump a.out | more
size 查看程序內存占用
#top
#whereis fcitx
#size /usr/bin/fcitx
file 文件類型查詢
$file core.22355
strings 查詢數據中的文本信息
一個文件中包含二進制數據和文本數據,如果只需要查看其文本信息,使用這個命令就很方便;過濾掉非字符數據,將文本信息輸出:$strings <objfile>
顯示所有正在使用著指定的file, file system 或者 sockets的進程信息;
fuser 顯示文件使用者
顯示所有正在使用著指定的file, file system 或者 sockets的進程信息;
$fuser -m -u redis-server
fuser通常被用在診斷系統的”resource busy”問題。如果你希望kill所有正在使用某一指定的file, file system or sockets的進程的時候,你可以使用-k選項:
$fuser –k /path/to/your/filename
xxd 十六進制顯示數據
#xxd /root/Desktop/1
od
通常使用od命令查看特殊格式的文件內容。通過指定該命令的不同選項可以以十進制、八進制、十六進制和ASCII碼來顯示文件。
參數說明:
-A 指定地址基數,包括:
d 十進制
o 八進制(系統默認值)
x 十六進制
n 不打印位移值
-t 指定數據的顯示格式,主要的參數有:
c ASCII字符或反斜槓序列
d 有符號十進制數
f 浮點數
o 八進制(系統默認值為02)
u 無符號十進制數
x 十六進制數
$od -Ax /root/Desktop/1
系統響應變慢:IO瓶頸、CPU瓶頸、內存瓶頸、程序導致的系統問題
使用top工具能夠比較全面的查看我們關注的點:#top
進入交互模式後:
輸入M,進程列表按內存使用大小降序排序,便於我們觀察最大內存使用者使用有問題(檢測內存洩漏問題);
輸入P,進程列表按CPU使用大小降序排序,便於我們觀察最耗CPU資源的使用者是否有問題;
top第三行顯示當前系統的,其中有兩個值很關鍵:
%id:空閒CPU時間百分比,如果這個值過低,表明系統CPU存在瓶頸;
%wa:等待I/O的CPU時間百分比,如果這個值過高,表明IO存在瓶頸;
3.2. 分析內存瓶頸 --free命令
一 使用free 命令
#free -mh
二 使用vmstat 命令
vmstat是Virtual Meomory 可實時動態監視操作系統的虛擬內存、進程、CPU活動。
vmstat [-V] [-n] [delay [count]]
-V表示打印出版本信息;
-n表示在周期性循環輸出時,輸出的頭部信息僅顯示一次;
delay是兩次輸出之間的延遲時間;
count是指按照這個時間間隔統計的次數。
/root$vmstat 5 5
procs -----------------memory-----------------------swap-- -----------io--------- -system-- ---------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 5524 172304 178400 969340 0 0 8 29 50 146 1 0 98 1 0
0 0 5524 172252 178400 969348 0 0 0 0 378 1089 19 3 78 0 0
3 0 5524 170888 178412 969352 0 0 0 31 636 1460 38 6 56 0 0
Procs Memory Swap system:
r:運行隊列中進程數量 swpd:使用虛擬內存大小 si:每秒從交換區寫到內存的大小
in: 每秒中斷數,包括時鐘中斷
b:等待IO的進程數量 free:可用內存大小 so:每秒寫入交換區的內存大小
cs: 每秒上下文切換數
buff:用作緩沖的內存大小 IO:現在Linux版本塊的大小為1024b
CPU(以百分比表示)
cache:用作緩存的內存大小 bi:每秒讀取的塊數
us: 用戶進程執行時間
bo:每秒寫入的塊數
sy: 系統進程執行時間
id: 空閒時間(包括IO等待時間)
wa: 等待IO時間
3.3. 分析IO瓶頸
如果IO存在性能瓶頸,top工具中的%wa會偏高;
進一步分析使用iostat工具:root$iostat -d -x -k 1 1
如果%iowait的值過高,表示硬盤存在I/O瓶頸。
如果 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁盤可能存在瓶頸。
如果 svctm 比較接近 await,說明 I/O 幾乎沒有等待時間;
如果 await 遠大於 svctm,說明I/O 隊列太長,io響應太慢,則需要進行必要優化。
如果avgqu-sz比較大,也表示有大量io在等待。
3.4. 分析進程調用--pstack和pstrace
pstack用來跟蹤進程棧,這個命令在排查進程問題時非常有用
查看bash程序進程棧:/opt/app/tdev1$ps -fe| grep bash
strace用來跟蹤進程中的系統調用;這個工具能夠動態的跟蹤進程執行時的系統調用和所接收的信號。是一個非常有效的檢測、指導和調試工具。系統管理員可以通過該命令容易地解決程序問題。
$strace cat /dev/null
命令實例1:
跟蹤可執行程序
strace -f -F -o ~/straceout.txt myserver
-f -F選項告訴strace同時跟蹤fork和vfork出來的進程,-o選項把所有strace輸出寫到~/straceout.txt裡 面,myserver是要啟動和調試的程序。
跟蹤服務程序
strace -o output.txt -T -tt -e trace=all -p 28979
跟蹤28979進程的所有系統調用(-e trace=all),並統計系統調用的花費時間,以及開始時間(並以可視化的時分秒格式顯示),最後將記錄結果存在output.txt文件裡面。
3.5. 優化程序代碼
編完代碼,再優化
精力集中在優化那20%最耗時的代碼上
gprof使用步驟
用gcc、g++、xlC編譯程序時,使用-pg參數,如:g++ -pg -o test.exe test.cpp編譯器會自動在目標代碼中插入用於性能測試的代碼片斷,這些代碼在程序運行時采集並記錄函數的調用關系和調用次數,並記錄函數自身執行時間和被調用函數的執行時間。
執行編譯後的可執行程序,如:./test.exe。該步驟運行程序的時間會稍慢於正常編譯的可執行程序的運行時間。程序運行結束後,會在程序所在路徑下生成一個缺省文件名為gmon.out的文件,這個文件就是記錄程序運行的性能、調用關系、調用次數等信息的數據文件。
使用gprof命令來分析記錄程序運行信息的gmon.out文件,如:gprof test.exe gmon.out則可以在顯示器上看到函數調用相關的統計、分析信息。上述信息也可以采用gprof test.exe gmon.out> gprofresult.txt重定向到文本文件以便於後續分析。
3.6. 其它工具
調試內存洩漏的工具valgrind,感興趣的朋友可以google了解;
OProfile: Linux 平台上的一個功能強大的性能分析工具,使用參考 [f2] ;
除了上面介紹的工具,還有一些比較全面的性能分析工具,比如sar(Linux系統上默認不安裝,需要手動安裝下); 將sar的常駐監控工具打開後,能夠收集比較全面的性能分析數據;
普通文件
目錄
網絡文件系統的文件
字符或設備文件
(函數)共享庫
管道,命名管道
符號鏈接
網絡文件(例如:NFS file、網絡socket,unix域名socket)
還有其它類型的文件,等等
命令參數
-a 列出打開文件存在的進程
-c<進程名> 列出指定進程所打開的文件
-g 列出GID號進程詳情
-d<文件號> 列出占用該文件號的進程
+d<目錄> 列出目錄下被打開的文件
+D<目錄> 遞歸列出目錄下被打開的文件
-n<目錄> 列出使用NFS的文件
-i<條件> 列出符合條件的進程。(4、6、協議、:端口、 @ip )
-p<進程號> 列出指定進程號所打開的文件
-u 列出UID號進程詳情
-h 顯示幫助信息
-v 顯示版本信息
實例1:無任何參數$lsof| more
lsof輸出各列信息的意義如下:
COMMAND:進程的名稱
PID:進程標識符
PPID:父進程標識符(需要指定-R參數)
USER:進程所有者
PGID:進程所屬組
FD:文件描述符,應用程序通過文件描述符識別該文件。如cwd、txt等:
(1)cwd:表示current work dirctory,即:應用程序的當前工作目錄,這是該應用程序啟動的目錄,除非它本身對這個目錄進行更改
(2)txt :該類型的文件是程序代碼,如應用程序二進制文件本身或共享庫,如上列表中顯示的 /sbin/init 程序
(3)lnn:library references (AIX);
(4)er:FD information error (see NAME column);
(5)jld:jail directory (FreeBSD);
(6)ltx:shared library text (code and data);
(7)mxx :hex memory-mapped type number xx.
(8)m86:DOS Merge mapped file;
(9)mem:memory-mapped file;
(10)mmap:memory-mapped device;
(11)pd:parent directory;
(12)rtd:root directory;
(13)tr:kernel trace file (OpenBSD);
(14)v86 VP/ix mapped file;
(15)0:表示標准輸出
(16)1:表示標准輸入
(17)2:表示標准錯誤
一般在標准輸出、標准錯誤、標准輸入後還跟著文件狀態模式:r、w、u等
(1)u:表示該文件被打開並處於讀取/寫入模式
(2)r:表示該文件被打開並處於只讀模式
(3)w:表示該文件被打開並處於
(4)空格:表示該文件的狀態模式為unknow,且沒有鎖定
(5)-:表示該文件的狀態模式為unknow,且被鎖定
同時在文件狀態模式後面,還跟著相關的鎖
(1)N:for a Solaris NFS lock of unknown type;
(2)r:for read lock on part of the file;
(3)R:for a read lock on the entire file;
(4)w:for a write lock on part of the file;(文件的部分寫鎖)
(5)W:for a write lock on the entire file;(整個文件的寫鎖)
(6)u:for a read and write lock of any length;
(7)U:for a lock of unknown type;
(8)x:for an SCO OpenServer Xenix lock on part of the file;
(9)X:for an SCO OpenServer Xenix lock on the entire file;
(10)space:if there is no lock.
TYPE:文件類型,如DIR、REG等,常見的文件類型:
(1)DIR:表示目錄
(2)CHR:表示字符類型
(3)BLK:塊設備類型
(4)UNIX: UNIX 域套接字
(5)FIFO:先進先出 (FIFO) 隊列
(6)IPv4:網際協議 (IP) 套接字
DEVICE:指定磁盤的名稱
SIZE:文件的大小
NODE:索引節點(文件在磁盤上的標識)
NAME:打開文件的確切名稱
查找某個文件相關的進程$lsof /bin/bash
實例3:列出某個用戶打開的文件信息$lsof -u username
實例4:某個程序進程所打開的文件信息$lsof -c mysql
實例5:列出某個用戶以及某個進程所打開的文件信息$lsof -u test -c mysql
實例6:通過某個進程號顯示該進程打開的文件$lsof -p 11968
實例7:列出所有的網絡連接$lsof -i
實例8:列出所有tcp 網絡連接信息$lsof -i tcp $lsof -n -i tcp
實例9:列出誰在使用某個端口 $lsof -i :3306
實例10:列出某個用戶的所有活躍的網絡端口$lsof -a -u test -i
實例11:根據文件描述列出對應的文件信息$lsof -d description(like 2)
實例12:列出被進程號為1234的進程所打開的所有IPV4 network files
$lsof -i 4 -a -p 1234
實例13:列出目前連接主機nf5260i5-td上端口為:20,21,80相關的所有文件信息,且每隔3秒重復執行
lsof -i @nf5260i5-td:20,21,80 -r 3
歡迎大家分享更好的思路,熱切期待^^_^^ !