首頁>技術>

一:Linux偵錯程式-gdb(1)debug與release

程式的釋出方式有debug和release兩種模式,release沒有除錯資訊,不能進行除錯,體積較小,debug攜帶除錯資訊,可以進行除錯,但是檔案較大

Linux中,使用gcc/g++編譯的程式,預設使用的是release模式,所以就不能直接使用gdb進行除錯。如果想要除錯,必須在進行gcc/g++編譯時,攜帶-g選項

如下,同一個檔案分別使用debug(帶-d的)和release,其中debug的檔案大小明顯大於release

使用readelf -S命令可以檢視debug檔案

(2)一起來除錯一個程式

如下是一個計算1-100的和的C語言程式,進行編譯(不要忘記-g)

1:開啟除錯

輸入gdb [檔名],進入除錯狀態

2:顯示原始碼

輸入list(簡寫為l),顯示原始碼便於觀察,每次顯示10行,按Enter向下翻輸入list n(簡寫為l n),顯示第n-5行第n+5行

3:斷點

輸入break n(簡寫為b n),在第n行打上一個斷點輸入info b,可以檢視斷點資訊輸入d [斷點編號],刪除對應編號的斷點輸入disable breakpoint [斷點編號],禁用對應編號的斷點;輸入disable breakpoints,禁用所有斷點輸入enable breakpoint [斷點編號],啟用對應編號的斷點;輸入enable breakpoints,啟用所有斷點

4:執行程式①:開啟執行

輸入run(簡寫為 r),程式開始執行,如果沒有斷點將直接輸入程式結果,如果有斷點,程式將停止到第一個斷點處。類似於在VS中,在某行上按下了F5打上了斷點,然後再按F5,程式將跳轉到此斷點處,但還沒有執行

②:逐語句,逐過程執行

如上,此時來到一個斷點處,類似於VS,你會有兩種選擇:要麼逐語句F10,不進入此函式,直接執行此函式跳到下一行語句,要麼逐過程F11進入此函式執行

輸入next(簡寫為n),程式會到下一句,若輸入step(簡寫為s),程式會進入這個函式上述程式在執行過程中,若需要檢視變數的值,則輸入p [變數名]若需要動態檢視變數名,則輸入display [變數名],接著再執行程式,程式在執行過程中除顯示當前執行的語句外,還會顯示執行過程中的變數在動態檢視中若不想檢視某個變量了,取消的方式和設定的方式稍微有點區別。可以發現設定display後,gdb為每個要展示的變數都設定了相應的編號,所以取消時輸入undisplay [變數名所對應的編號];如果要全部取消則直接輸入display

④:執行中跳轉

上述,進入sum函式,就在不斷執行迴圈,如果臨時決定想要跳出這個迴圈,或者直接到某一行,那麼就輸入until n,其中n表示行號如果想要從一個斷點,跳轉到下一個斷點,則輸入c如果進入了某個函式,想要立即結束掉這個函式直接返回到呼叫處,則輸入finish。(3)總結-gdb選項

選項

描述

list [行號]

顯示原始碼

list [函式名]

顯示某函式的原始碼

run

執行程式

next

逐語句執行

step

進入函式

break [行號]

在某行出設定斷點

break [函式名]

在某函式開頭設定斷點

info break

檢視斷點資訊

finish

結束當前函式,返回呼叫處

p []變數]

列印變數的值

c

跳轉到下一個斷點

d [斷點編號]

delete breakpoints

disable/enable breakpoint [斷點編號]

禁用/啟用對應編號斷點

display [變數名]

跟蹤變數,執行時每次都顯示

undisplay

取消跟蹤

until [行號]

跳轉到對應行

quit

退出

二:Linux專案自動化構建工具-Make/Makefile(1)前言

對於一個大型專案,可能會涉及到很多檔案,例如標頭檔案,原始檔等等。在VS中,我們只需在其設定的目錄下,新建對應檔案然後進行編寫即可,然後按下執行鍵,只要你的程式碼沒有問題,那麼就可以執行出結果。這一切一切的感覺看起來很輕鬆,但是實則不然,例如首先編譯哪個檔案,如何連結?這些都是需要考慮的,但是VS作為一個整合開發環境,自然而然幫你做好了這一切,但是在Linux中,這些都是需要自己做的。而正因為做這些很麻煩,且不好理解,所以make,makefile應用而生

make/makefilie:用於在Linux中維護專案檔案之間的關係,其中make是一個目錄,makefile是一個檔案,通常該檔案存放於當前工作目錄

(2)依賴關係和依賴方法

通俗的來講依賴關係是指:要生成A就必須先生成B,而依賴方法是指:怎樣透過B生成A。

比如前述在gcc編譯過程時,這幾個檔案就存在以下依賴關係和依賴方法(假設由hello.c編譯生成hello.exe)

hello.exe依賴hello.o,依賴方法是gcc hello.o -o hello.exehello.o依賴hello.s,依賴方法是gcc hello.s -o hello.ohello.s依賴hello.i,依賴方法是gcc hello.i -o hello.shello.i依賴hello.c,依賴方法是gcc hello.c -o hello.i(3)單檔案Makefile

簡單其工作過程就是,在同一個目錄下,建立一個檔案叫做Makefile,然後在該檔案內,進行編寫,編寫的程式碼反映了上述的依賴關係和依賴方法,然後返回終端透過輸入目命令,來執行這個過程。很像Windows中的批處理。

準確來說:make是執行依賴關係和依賴方法的命令,Makefile是維護該機制的檔案,Makefile裡面儲存了專案的依賴結構

如下,建立一個hello.c的檔案,並編寫簡單程式碼,然後再在相同目錄下建立檔案Makefile接著在Makefile編寫如下程式碼,其中各項作用解釋於圖中。Makefile編寫好之後,在命令列直接使用make,就可以呼叫這個檔案執行操作。下面的兩個操作相當於VS中的生成解決方案和清理解決方案。(4)多檔案Makefile

編寫一個簡單加法程式,兩個原始檔:main .c,compute .c,一個頭檔案compute. h,使用Makefile進行編譯

首先,編寫程式如下編寫Makefile如下執行(5)總結

綜上所述,當我們編寫好Makefile,然後在終端輸入make,make就會在當前目錄下尋找名字叫做Makefile的檔案,如果找到,它會以該檔案中的第一個檔案(比如上面的exe檔案)作為最終需要生成的檔案,如果該檔案不存在或者說它依賴的.o檔案要比這個.exe檔案新,那麼它就會執行依賴方法,來生成這個.exe檔案,同樣的,如果.o檔案不存在,那麼make就會找這個檔案的依賴性,再根據上面的規則走下去。但最終,.c檔案和.h檔案一定會存在的,於是一層套一層,最終直到生成目標檔案。

終極makefile三:小程式:進度條(1)兩個問題A:緩衝區問題

有如下程式碼

#include <stdio.h>#include <unistd.h>int main(){	printf("Hello linux\n");	sleep(3)	return 0;}12345678

執行效果如下,可以發現當輸出帶有\n時,能按照正常的邏輯輸出,即先列印再等待

若將程式碼改為下面這樣,去掉\n

#include <stdio.h>#include <unistd.h>int main(){	printf("Hello linux");	sleep(3)	printf("\n");	return 0;}123456789

可以發現似乎先執行了sleep,再執行printf

但是任何語言都是自上向下執行的,不會出現胡亂執行的問題,出現這個問題的原因在於緩衝區。printf在執行時,並不是一下就把語句輸出到螢幕上去,而是先輸出到緩衝區裡,然後等到合適的刷新出現後,就將內容傳送到螢幕上去,第一次之所以正常輸出,是因為有了\n,這個重新整理標誌,而第二次之所以沒有正常輸出,是因為printf沒有遇到重新整理標誌,然後就接著執行sleep,最後遇到return才重新整理,自然而然感覺是先重新整理後列印了

為了解決這一個問題,可以在printf結束之後,讓其強制重新整理,即輸入fflush(stdout),即強制重新整理螢幕

#include <stdio.h>#include <unistd.h>int main(){	printf("Hello linux");	fflush(stdout);	sleep(3)	printf("\n");	return 0;}12345678910
(B)回車與換行

跳脫字元\r表示回車,回車的意思是回到本行的第一個字元處跳脫字元\n表示換行,換行的意思是到下一行對應位置再輸入

(2)進度條

效果

程式碼

#include "bar.h"  4 void bar()  5 {  6   char bar[NUM];  7   memset(bar,'\0',sizeof(bar));  8   9   const char* label="|/-\\"; 10   int i=0; 11   while(i<100) 12   { 13     fflush(stdout); 14     bar[i++]='#'; 15     usleep(150000); 16     printf("[%-100s][%3d%%][%c]\r",bar,i,label[i%4]);                                                                              17   } 18   printf("\n"); 19 }123456789101112131415161718
四:Git

如何在Linux上使用GitHub託管程式碼

按照正常步驟,在GitHub上建立一個程式碼倉庫,複製https使用git clone,在本地建立相應的一個倉庫需要的程式碼,複製到這個倉庫裡三板斧之第一板斧–git add。輸入git add [檔名]三板斧之第二板斧-git commit。輸入git commit三板斧之第三板斧-git push。輸入git push,然後輸入使用者名稱和密碼即可

18
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Python 資料處理(一)