linux常用命令--開(kāi)發(fā)調(diào)試篇

前言

Linux常用命令中有一些命令可以在開(kāi)發(fā)或調(diào)試過(guò)程中起到很好的幫助作用,有些可以幫助了解或優(yōu)化我們的程序杂彭,有些可以幫我們定位疑難問(wèn)題。本文將簡(jiǎn)單介紹一下這些命令。

示例程序

我們用一個(gè)小程序匈勋,來(lái)幫助后面我們對(duì)這些命令的描述,程序清單cmdTest.c如下:

#include<stdio.h>
int test(int a,int b)
{
    return a/b;
}
int main(int argc, char *argv[])
{
    int a = 10;
    int b = 0;
    printf("a=%d,b=%d\n",a,b);
    test(a,b);
    return 0;
}

編譯獲得elf文件cmdTest并運(yùn)行:

gcc -g -o cmdTest cmdTest.c
./cmdTest
a=10,b=0
Floating point exception (core dumped)

程序內(nèi)容是在main函數(shù)中調(diào)用test膳叨,計(jì)算a/b的值洽洁,其中b的值為0,因此程序由于除0錯(cuò)誤異常終止菲嘴。

  • 查看文件基本信息-->file
file cmdTest
cmdTest: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=448e1c34b4c548120e2c04f6a2bfce4e6d2281a3, not stripped

通過(guò)file命令可以看到cmdTest的類(lèi)型為elf饿自,是64位、運(yùn)行于x86-64的程序龄坪,not striped表明elf文件中還保留著符號(hào)信息以及調(diào)試信息等不影響程序運(yùn)行的內(nèi)容昭雌。

  • 查看程序依賴庫(kù)-->ldd
ldd cmdTest
       linux-vdso.so.1 =>  (0x00007ffc8e548000)
       libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0621931000)
       /lib64/ld-linux-x86-64.so.2 (0x00007f0621cf6000)

我們可以看到cmdTest依賴了libc.so等庫(kù)。

  • 查看函數(shù)或者全局變量是否存在于elf文件中-->nm

nm命令用于查看elf文件的符號(hào)信息健田。文件編譯出來(lái)之后烛卧,我們可能不知道新增加的函數(shù)或者全局變量是否已經(jīng)成功編譯進(jìn)去。這時(shí)候妓局,我們可以使用nm命令來(lái)查看总放。
例如,查看前面所提到的elf文件有沒(méi)有test函數(shù)好爬,可以用命令:

nm cmdTest | grep test
000000000040052d T test  #打印結(jié)果

按照地址順序列出符號(hào)信息:

nm -n cmdTest
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
                 w __gmon_start__
                 U __libc_start_main@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
00000000004003e0 T _init
0000000000400440 T _start
0000000000400470 t deregister_tm_clones
00000000004004a0 t register_tm_clones
00000000004004e0 t __do_global_dtors_aux
0000000000400500 t frame_dummy
000000000040052d T test
0000000000400540 T main
0000000000400590 T __libc_csu_init
0000000000400600 T __libc_csu_fini
(列出部分內(nèi)容)

可以看到test函數(shù)的開(kāi)始地址為0x000000000040052d局雄,結(jié)束地址為0x0000000000400540。

  • 打印elf文件中的可打印字符串-->strings

例如你在代碼中存儲(chǔ)了一個(gè)版本號(hào)信息存炮,那么即使編譯成elf文件后炬搭,仍然可以通過(guò)strings搜索其中的字符串甚至可以搜索某個(gè).c文件是否編譯在其中:

strings elfFile | grep "someString"
  • 查看文件段大小-->size

可以通過(guò)size命令查看各段大序诶臁:

size cmdTest
   text       data      bss      dec      hex  filename
   1319      560        8     1887      75f   cmdTest

text段:正文段字節(jié)數(shù)大小
data段:包含靜態(tài)變量和已經(jīng)初始化的全局變量的數(shù)據(jù)段字節(jié)數(shù)大小
bss段:存放程序中未初始化的全局變量的字節(jié)數(shù)大小
當(dāng)我們知道各個(gè)段的大小之后,如果有減小程序大小的需求尚蝌,就可以有針對(duì)性的對(duì)elf文件進(jìn)行優(yōu)化處理迎变。

  • 為elf文件”瘦身“-->strip

strip用于去掉elf文件中所有的符號(hào)信息:

ls -al cmdTest
-rwxr-xr-x 1 hyb root 9792 Sep 25 20:30 cmdTest #總大小為9792字節(jié)

strip cmdTest
ls -al cmdTest
-rwxr-xr-x 1 hyb root 6248 Sep 25 20:35 cmdTest#strip之后大小為6248字節(jié)

可以看到,“瘦身”之后飘言,大小減少將近三分之一衣形。但是要特別注意的是,“瘦身”之后的elf文件由于沒(méi)有了符號(hào)信息姿鸿,許多調(diào)試命令將無(wú)法正常使用谆吴,出現(xiàn)core dump時(shí),問(wèn)題也較難定位苛预,因此只建議在正式發(fā)布時(shí)對(duì)其進(jìn)行“瘦身”句狼。

  • 查看elf文件信息-->readelf

readelf用于查看elf文件信息,它可以查看各段信息热某,符號(hào)信息等腻菇,下面的例子是查看elf文件頭信息:

readelf -h cmdTest
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  #elf文件魔數(shù)字
  Class:                             ELF64  #64位 elf文件
  Data:                              2's complement, little endian#字節(jié)序?yàn)樾《诵?  Version:                           1 (current)
  OS/ABI:                            UNIX - System V #
  ABI Version:                       0
  Type:                              EXEC (Executable file)#目標(biāo)文件類(lèi)型
  Machine:                           Advanced Micro Devices X86-64 #目標(biāo)處理器體系
  Version:                           0x1
  Entry point address:               0x400440  #入口地址
  Start of program headers:          64 (bytes into file)
  Start of section headers:          4456 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         28
  Section header string table index: 27

從elf頭信息中,我們可以知道該elf是64位可執(zhí)行文件昔馋,運(yùn)行在x86-64中筹吐,且字節(jié)序?yàn)樾《诵颉A硗饷囟簦覀冞€注意到它的入口地址是0x400440 (_start)丘薛,而不是400540 (main)。也就是說(shuō)邦危,我們的程序運(yùn)行并非從main開(kāi)始洋侨。

  • 反匯編指定函數(shù)-->objdump

objdump用于展示elf文件信息,功能較多倦蚪,在此不逐一介紹希坚。有時(shí)候我們需要反匯編來(lái)定位一些問(wèn)題,可以使用命令:

objdump -d cmdTest #反匯編整個(gè)cmdTest程序

但是如果程序較大陵且,那么反匯編時(shí)間將會(huì)變長(zhǎng)裁僧,而且反匯編文件也會(huì)很大米罚。如果我們已經(jīng)知道了問(wèn)題在某個(gè)函數(shù)怔揩,只想反匯編某一個(gè)函數(shù)足丢,怎么處理呢?
我們可以利用前面介紹的nm命令獲取到函數(shù)test的地址脓钾,然后使用下面的方式反匯編:

objdump -d cmdTest --start-address=0x40052d --stop-address=0x400540 ##反匯編指定地址區(qū)間
  • 端口占用情況查看-->netstat

我們可能常常會(huì)遇到進(jìn)程第一次啟動(dòng)后,再次啟動(dòng)會(huì)出現(xiàn)端口綁定失敗的問(wèn)題桩警,我們可以通過(guò)netstat命令查看端口占用情況:

netstat -anp | grep 端口號(hào)
  • 進(jìn)程狀態(tài)查看-->ps或top

ps命令的用法可以參考ps命令常見(jiàn)實(shí)用用法可训。
top命令實(shí)時(shí)顯示當(dāng)前進(jìn)程狀態(tài),最活躍的進(jìn)程顯示在最頂部。

  • -core dump文件生成配置-->ulimit -c*

有時(shí)候我們的程序core dump了卻沒(méi)有生成core文件握截,很可能是我們?cè)O(shè)置的問(wèn)題:

ulimit -c #查看core文件配置飞崖,如果結(jié)果為0,程序core dump時(shí)將不會(huì)生成core文件
ulimit -c unlimited #不限制core文件生成大小
ulimit -c 10 #設(shè)置最大生成大小為10kb

調(diào)試神器-->gdb

gdb是一個(gè)強(qiáng)大的調(diào)試工具谨胞,但這里僅介紹兩個(gè)簡(jiǎn)單使用示例固歪。有時(shí)候程序可能已經(jīng)正在運(yùn)行,但是又不能終止它胯努,這時(shí)候仍然可以使用gdb調(diào)試正在運(yùn)行的進(jìn)程:

gdb processFile PID #processFile為進(jìn)程文件牢裳,pid為進(jìn)程id,可通過(guò)ps命令查找到

有時(shí)候程序可能core dump了叶沛,但是系統(tǒng)還留給了我們一個(gè)禮物--core文件蒲讯。在core文件生成配置完成之后,運(yùn)行cmdTest程序灰署,產(chǎn)生core文件判帮。我們可以用下面的方法通過(guò)core文件定位出錯(cuò)位置:

gdb cmdTest core #cmdTest為進(jìn)程文件,core為生成的core文件
Core was generated by `./cmdTest'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x00000000004004fb in test (a=10, b=0) at cmdTest.c:4
4         return a/b;

(gdb)bt
#0  0x00000000004004fb in test (a=10, b=0) at cmdTest.c:4
#1  0x000000000040052c in main (argc=1, argv=0x7ffca9536d38) at cmdTest.c:10
(gdb)

輸入bt后溉箕,就可以看到調(diào)用棧了,出錯(cuò)位置在test函數(shù)晦墙,cmdTest.c的第4行。

  • 定位crash問(wèn)題-->addr2line

有時(shí)候程序崩潰了但不幸沒(méi)有生成core文件约巷,是不是就完全沒(méi)有辦法了呢偎痛?還是cmdTest的例子。運(yùn)行完cmdTest之后独郎,我們通過(guò)dmesg命令可以獲取到以下內(nèi)容

[27153070.538380] traps: cmdTest[2836] trap divide error ip:40053b sp:7ffc230d9280 error:0 in cmdTest[400000+1000]

該信息記錄了cmdTest運(yùn)行出錯(cuò)的基本原因(divide error)和出錯(cuò)位置(40053b),我們使用addr2line命令獲取出錯(cuò)具體行號(hào):

addr2line -e cmdTest 40053b
/home/hyb/practice/cmdTest.c:4

可以看到addr2line命令將地址(40053b)翻譯成了文件名(cmdTest.c)和行號(hào)(4)踩麦,確定了出錯(cuò)位置。

總結(jié)

本文對(duì)以上命令僅介紹其經(jīng)典使用氓癌,這些命令都還有其他一些有幫助的用法谓谦,但由于篇幅有限,不在此介紹贪婉,更多使用方法可以通過(guò)man 命令名的方式去了解反粥。


=========我是華麗的分割線=========


更多知識(shí):
點(diǎn)擊關(guān)注專(zhuān)題:嵌入式Linux&ARM

或?yàn)g覽器打開(kāi):http://www.reibang.com/c/42d33cadb1c1

或掃描二維碼:

文章參考微信公眾號(hào)[編程珠璣]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疲迂,隨后出現(xiàn)的幾起案子才顿,更是在濱河造成了極大的恐慌,老刑警劉巖尤蒿,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件郑气,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡腰池,警方通過(guò)查閱死者的電腦和手機(jī)尾组,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)忙芒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人讳侨,你說(shuō)我怎么就攤上這事呵萨。” “怎么了跨跨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵潮峦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我歹叮,道長(zhǎng)跑杭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任咆耿,我火速辦了婚禮德谅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萨螺。我一直安慰自己窄做,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布慰技。 她就那樣靜靜地躺著椭盏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吻商。 梳的紋絲不亂的頭發(fā)上掏颊,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音艾帐,去河邊找鬼乌叶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛柒爸,可吹牛的內(nèi)容都是我干的准浴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼捎稚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乐横!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起今野,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤葡公,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后条霜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體催什,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年蛔外,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛆楞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夹厌,死狀恐怖豹爹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矛纹,我是刑警寧澤臂聋,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站或南,受9級(jí)特大地震影響孩等,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜采够,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一肄方、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蹬癌,春花似錦权她、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至董济,卻和暖如春步清,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虏肾。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工廓啊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人询微。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓崖瞭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親撑毛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子书聚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 一、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡(jiǎn)單分配策略的問(wèn)題地址空間不隔離內(nèi)存使用效率低程序運(yùn)行的地址不確定 關(guān)于...
    SeanCST閱讀 7,819評(píng)論 0 27
  • 煩事繞心亂緒結(jié)藻雌, 前程岔道暫緩歇雌续。 來(lái)渝立業(yè)途莫測(cè), 中傳五載欲作別胯杭。
    支武昂閱讀 201評(píng)論 0 0
  • Contact.h Contact.m AddContactViewController.h AddContact...
    小苗曉雪閱讀 344評(píng)論 0 0
  • 當(dāng)記憶的痕跡淡去驯杜,還能體會(huì)曾經(jīng)的心情么? 這是洛卡同學(xué)曾經(jīng)對(duì)我說(shuō)過(guò)的一個(gè)觀點(diǎn)做个,至今我仍然印象深刻鸽心。 我忘記那是哪一...
    零凝閱讀 172評(píng)論 0 0
  • 昨天晚上滚局,我看見(jiàn)話題“為什么一定要努力”從知乎熱搜榜底冒出來(lái)的時(shí)候,就猜到它一定會(huì)火顽频。今天早上醒來(lái)的時(shí)候藤肢,發(fā)現(xiàn)它不...
    西風(fēng)De話閱讀 169評(píng)論 0 1