亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C/C++ 編譯器和調試器以及靜態庫、動態庫使用匯總

2019-11-17 05:14:02
字體:
來源:轉載
供稿:網友

經常的,有朋友問到有關unix下面條是的技術。我整理了大多數的unix系統下面的常用的調試工具的調試技術的文章。希望對大家有所幫助。

另外靜態庫、動態庫也是問的頻率比較高的問題。在這里也做了總結。


######大多數unix系統下面的調試器的使用方法如下:######

***************gdb介紹*********************
GNU 的調試器稱為 gdb,該程序是一個交互式工具,工作在字符模式。在 X Window 系統中,有一個 gdb 的
前端圖形工具,稱為 xxgdb。gdb 是功能強大的調試程序,可完成如下的調試任務:
* 設置斷點;
* 監視程序變量的值;
* 程序的單步執行;
* 修改變量的值。
在可以使用 gdb 調試程序之前,必須使用 -g 選項編譯源文件??稍?makefile 中如下定義 CFLAGS 變量:
CFLAGS = -g
運行 gdb 調試程序時通常使用如下的命令:
gdb PRogname

在 gdb 提示符處鍵入help,將列出命令的分類,主要的分類有:
* aliases:命令別名
* breakpoints:斷點定義;
* data:數據查看;
* files:指定并查看文件;
* internals:維護命令;
* running:程序執行;
* stack:調用棧查看;
* statu:狀態查看;
* tracepoints:跟蹤程序執行。
鍵入 help 后跟命令的分類名,可獲得該類命令的具體清單。


*********gdb 的常用命令***************
命令 解釋
break NUM 在指定的行上設置斷點。
BT 顯示所有的調用棧幀。該命令可用來顯示函數的調用順序。
clear 刪除設置在特定源文件、特定行上的斷點。其用法為:clear FILENAME:NUM。
continue 繼續執行正在調試的程序。該命令用在程序由于處理信號或斷點而
導致停止運行時。
display EXPR 每次程序停止后顯示表達式的值。表達式由程序定義的變量組成。
file FILE 裝載指定的可執行文件進行調試。
help NAME 顯示指定命令的幫助信息。
info break 顯示當前斷點清單,包括到達斷點處的次數等。
info files 顯示被調試文件的具體信息。
info func 顯示所有的函數名稱。
info local 顯示當函數中的局部變量信息。
info prog 顯示被調試程序的執行狀態。
info var 顯示所有的全局和靜態變量名稱。
kill 終止正被調試的程序。
list 顯示源代碼段。
make 在不退出 gdb 的情況下運行 make 工具。
next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。
print EXPR 顯示表達式 EXPR 的值。

******gdb 使用范例************************
-----------------
清單 一個有錯誤的 C 源程序 bugging.c
-----------------
#include
#include

static char buff [256];
static char* string;
int main ()
{

printf ("Please input a string: ");
gets (string);

printf ("/nYour string is: %s/n", string);
}
-----------------
上面這個程序非常簡單,其目的是接受用戶的輸入,然后將用戶的輸入打印出來。該程序使用了一個未經過初
始化的字符串地址 string,因此,編譯并運行之后,將出現 Segment Fault 錯誤:
$ gcc -o test -g test.c
$ ./test
Please input a string: asfd
Segmentation fault (core dumped)
為了查找該程序中出現的問題,我們利用 gdb,并按如下的步驟進行:
1.運行 gdb bugging 命令,裝入 bugging 可執行文件;
2.執行裝入的 bugging 命令;
3.使用 where 命令查看程序出錯的地方;

4.利用 list 命令查看調用 gets 函數四周的代碼;
5.唯一能夠導致 gets 函數出錯的因素就是變量 string。用 print 命令查看 string 的值;
6.在 gdb 中,我們可以直接修改變量的值,只要將 string 取一個合法的指針值就可以了,為此,我們在第
11 行處設置斷點;
7.程序重新運行到第 11 行處停止,這時,我們可以用 set variable 命令修改 string 的取值;
8.然后繼續運行,將看到正確的程序運行結果。




運行 gcc/egcs

**********運行 gcc/egcs***********************
GCC 是 GNU 的 C 和 C++ 編譯器。實際上,GCC 能夠編譯三種語言:C、C++ 和 Object C(C 語言的一種面向對象擴展)。利用 gcc 命令可同時編譯并連接 C 和 C++ 源程序。

假如你有兩個或少數幾個 C 源文件,也可以方便地利用 GCC 編譯、連接并生成可執行文件。例如,假設你有
兩個源文件 main.c 和 factorial.c 兩個源文件,現在要編譯生成一個計算階乘的程序。
清單 factorial.c
-----------------------
#include
#include

int factorial (int n)
{
if (n <= 1)
return 1;

else
return factorial (n - 1) * n;
}
-----------------------

-----------------------
清單 main.c
-----------------------
#include
#include

int factorial (int n);

int main (int argc, char **argv)
{
int n;

if (argc < 2) {
printf ("Usage: %s n/n", argv [0]);
return -1;
}
else {
n = atoi (argv[1]);
printf ("Factorial of %d is %d./n", n, factorial (n));
}

return 0;
}
-----------------------
利用如下的命令可編譯生成可執行文件,并執行程序:
$ gcc -o factorial main.c factorial.c
$ ./factorial 5
Factorial of 5 is 120.

GCC 可同時用來編譯 C 程序和 C++ 程序。一般來說,C 編譯器通過源文件的后綴名來判定是 C 程序還是 C+
+ 程序。在 linux 中,C 源文件的后綴名為 .c,而 C++ 源文件的后綴名為 .C 或 .cpp。
但是,gcc 命令只能編譯 C++ 源文件,而不能自動和 C++ 程序使用的庫連接。因此,通常使用 g++ 命令來完
完成 C++ 程序的編譯和連接,該程序會自動調用 gcc 實現編譯。
假設我們有一個如下的 C++ 源文件(hello.C):

#include

void main (void)
{
cout << "Hello, world!" << endl;
}

則可以如下調用 g++ 命令編譯、連接并生成可執行文件:

$ g++ -o hello hello.C
$ ./hello
Hello, world!


**********************gcc/egcs 的主要選項*********
gcc 命令的常用選項
選項 解釋
-ansi 只支持 ANSI 標準的 C 語法。這一選項將禁止 GNU C 的某些特色,
例如 asm 或 typeof 要害詞。
-c 只編譯并生成目標文件。
-DMACRO 以字符串“1”定義 MACRO 宏。
-DMACRO=DEFN 以字符串“DEFN”定義 MACRO 宏。
-E 只運行 C 預編譯器。
-g 生成調試信息。GNU 調試器可利用該信息。
-IDirectorY 指定額外的頭文件搜索路徑DIRECTORY。
-LDIRECTORY 指定額外的函數庫搜索路徑DIRECTORY。

-lLIBRARY 連接時搜索指定的函數庫LIBRARY。
-m486 針對 486 進行代碼優化。
-o FILE 生成指定的輸出文件。用在生成可執行文件時。
-O0 不進行優化處理。
-O 或 -O1 優化生成代碼。
-O2 進一步優化。
-O3 比 -O2 更進一步優化,包括 inline 函數。
-shared 生成共享目標文件。通常用在建立共享庫時。
-static 禁止使用共享連接。
-UMACRO 取消對 MACRO 宏的定義。
-w 不生成任何警告信息。
-Wall 生成所有警告信息。



#######SCO UNIX下面dbaxtra的調試技術#########
在sco unix下編程大多離不開C語言,即使是數據庫應用也有很多是與c搭配使用的,例如informix esql/c 就可以在c語言中嵌入sql 語句。很多人認為在unix下寫程序是件很痛苦的事情,其中一個很重要原因是不知道在unix下怎樣調試程序。其實在sco unix源碼調試器是dbxtra或dbXtra,linux下是gdb。它們類似turbo c的調試器,可以跟蹤源碼變量。在unix 下調試程序有如下傳統方法

---- 一、在要調試語句之前,輸出要調試的變量,利用printf()函數。

---- 二、寫日志文件,把結果輸出到文件中避免屏幕混亂,利用fprintf()函數。

---- 三、利用sco 內置調試器dbxtra或dbXtra。

---- dbxtra 適用字符界面,在sco unix的圖形界面用dbXtra。(編按:請注重大小寫)

以下是dbxtra基本命令:
c cont 在斷點后繼續執行
d delete 刪除所設斷點
h help 幫助
e edit 編輯源程序
n next 源程序區的內容向下翻一屏。
p print 顯示變量
q quit 退出dbxtra
r run 運行程序,直到遇上設置的斷點
rr rerun 再次運行
s step 單步運行
st stop 設置斷點
j status 顯示當前斷點
t where 顯示當前狀態,列出所有設置的變量值
di display 開顯示窗,用于查看變量
ud undisplay 刪除顯示窗的條目
f forward 源程序區的內容向上 翻一屏。
B backward 源程序區的內容向下 翻一屏。
Stopi stop inst 設置斷點
tracei trace inst跟蹤子程序

dbxtra [options] [objectfile ]


---- dbxtra 在啟動時有個參數-Idir值得一提.我們在編寫一個較大程序的時候,通常源程序和編譯生成的可執行文件都放在不同的目錄中,這樣便于治理。默認dbxtra將在可執行文件所在的目錄下找匹配c的源程序。當我們啟動時,指定-I參數,dbxtra就會到我們指定的目錄下找匹配的c程序。 例如:
---- dbxtra -I"/work/c" program1

---- 源程序在用cc編譯時要帶上-g 參數,這樣是加上符號表等調試信息。只有這樣編譯過的文件,dbxtra才可以調試。調試信息使源代碼和機器碼關聯。

---- 下面這個C程序輸出結果和我們的預想結果不一樣,說明某些地方有錯誤。我們用調試器來調試它:

---- 程序一:

t.c
main()
{ int i=10 ,*p1;
float j=1.5,*p2;
p1=&
p2=&
p2=p1;
printf("%d,%d/n",*p1,*p2);
}

首先帶上-g參數編譯 cc -g -o t t.c
啟動調試器 dbxtra t
屏幕顯示:
1.main()
2.{ int i=10 ,*p1;
3. float j=1.5,*p2;
4. p1=&
5. p2=&
6. p2=p1;
7. printf("%d,%d/n",*p1,*p2);
8.}
C[browse] File:t.c Func.-
Readubg symbolic information
Type 'help' for help
(dbxtra)
(dbxtra)

設置斷點:

(dbxtra)stop at 5
運行:
(dbxtra) run
程序自動在第5行停下。
這時我們可以看變量的值。
(dbxtra) print *p1

單步執行。
(dbxtra) step
程序將執行第5行源碼,指針將移到第6行。
(dbxtra) print *p2

(dbxtra) step
程序執行了第6行源碼后,將指針移到第7行。
(dbxtra) print *p1 , *p2

---- 我們發現 在執行了第6行源碼后,*p1,*p2的值就不對了,所以問題就出在第6行上。仔細檢查后發現指針p1指向整型,指針p2指向實型。它們之間的賦值要進行強制類型轉換。這種錯誤在C程序中是很常見的。
---- 有時我們在調試一些程序時,要在整個程序運行中時刻監視莫些變量的值,例如程序一中我們要時刻了解*p1,*p2的值,除了在每一行程序執行完后,打print *p1,*p2外,還可以開一個顯示窗口。

---- (dbxtra)display *p1,*p2

---- 用undisplay 刪掉不想要的變量。

---- 有些程序運行時要帶參數,mycat /etc/passwd 在調試時候

---- (dbxtra) run '/etc/passwd'

---- 再運行時,無需再寫一遍參數。

---- (dbxtra) rerun

---- 在涉及到curses庫編程或屏幕有大量的人機界面時,為了調試方便,我們可以把程序輸出結果重定向到個虛屏。

---- (dbxtra) run >/dev/tty03

---- 當然要先把tty03 disable 掉。(disable tty03)



#######創建和使用靜態庫#########

具體的使用情況,請大家man手冊,這里只介紹一下。靜態庫相對的比較簡單。

創建一個靜態庫是相當簡單的。通常使用 ar 程序把一些目標文件(.o)組合在一起,
成為一個單獨的庫,然后運行 ranlib,以給庫加入一些索引信息。

########創建和使用共享庫#########
非凡的編譯和連接選項
-D_REENTRANT 使得預處理器符號 _REENTRANT 被定義,這個符號激活一些宏特性。
-fPIC 選項產生位置獨立的代碼。由于庫是在運行的時候被調入,因此這個
選項是必需的,因為在編譯的時候,裝入內存的地址還不知道。假如
不使用這個選項,庫文件可能不會正確運行。
-shared 選項告訴編譯器產生共享庫代碼。
-Wl,-soname -Wl 告訴編譯器將后面的參數傳遞到連接器。而 -soname 指定了
共享庫的 soname。
# 可以把庫文件拷貝到 /etc/ld.so.conf 中列舉出的任何目錄中,并以
root 身份運行 ldconfig;或者
# 運行 export LD_LIBRARY_PATH='pwd',它把當前路徑加到庫搜索路徑中去。


#######使用高級共享庫特性#########

1. ldd 工具
ldd 用來顯示執行文件需要哪些共享庫, 共享庫裝載治理器在哪里找到了需要的共享庫.

2. soname

共享庫的一個非常重要的,也是非常難的概念是 soname——簡寫共享目標名(short for shared object name)。這是一個為共享庫(.so)文件而內嵌在控制數據中的名字。如前面提到的,每一個程序都有一個需要使用的庫的清單。這個清單的內容是一系列庫的 soname,如同 ldd 顯示的那樣,共享庫裝載器必須找到這個清單。

soname 的要害功能是它提供了兼容性的標準。當要升級系統中的一個庫時,并且新庫的 soname 和老的庫的 soname 一樣,用舊庫連接生成的程序,使用新的庫依然能正常運行。這個特性使得在 Linux 下,升級使用共享庫的程序和定位錯誤變得十分輕易。

在 Linux 中,應用程序通過使用 soname,來指定所希望庫的版本。庫作者也可以通過保留或者改變 soname 來聲明,哪些版本是相互兼容的,這使得程序員擺脫了共享庫版本沖突問題的困擾。

查看/usr/local/lib 目錄,分析 MiniGUI 的共享庫文件之間的關系

3. 共享庫裝載器

當程序被調用的時候,Linux 共享庫裝載器(也被稱為動態連接器)也自動被調用。它的作用是保證程序所需要的所有適當版本的庫都被調入內存。共享庫裝載器名字是 ld.so 或者是 ld-linux.so,這取決于 Linux libc 的版本,它必須使用一點外部交互,才能完成自己的工作。然而它接受在環境變量和配置文件中的配置信息。



文件 /etc/ld.so.conf 定義了標準系統庫的路徑。共享庫裝載器把它作為搜索路徑。為了改變這個設置,必須以 root 身份運行 ldconfig 工具。這將更新 /etc/ls.so.cache 文件,這個文件其實是裝載器內部使用的文件之一。



可以使用許多環境變量控制共享庫裝載器的操作(表1-4+)。

表 1-4+ 共享庫裝載器環境變量
變量 含義
LD_AOUT_LIBRARY_PATH 除了不使用 a.out 二進制格式外,與 LD_LIBRARY_PATH 相同。

LD_AOUT_PRELOAD 除了不使用 a.out 二進制格式外,與 LD_PRELOAD 相同。
LD_KEEPDIR 只適用于 a.out 庫;忽略由它們指定的目錄。
LD_LIBRARY_PATH 將其他目錄加入庫搜索路徑。它的內容應該是由冒號
分隔的目錄列表,與可執行文件的 PATH 變量具有相同的格式。
假如調用設置用戶 ID 或者進程 ID 的程序,該變量被忽略。
LD_NOWARN 只適用于 a.out 庫;當改變版本號是,發出警告信息。
LD_PRELOAD 首先裝入用戶定義的庫,使得它們有機會覆蓋或者重新定義標準庫。
使用空格分開多個入口。對于設置用戶 ID 或者進程 ID 的程序,
只有被標記過的庫才被首先裝入。在 /etc/ld.so.perload 中指定
了全局版本號,該文件不遵守這個限制。

4. 使用 dlopen

另外一個強大的庫函數是 dlopen()。該函數將打開一個新庫,并把它裝入內存。該函數主要用來加載庫中的符號,這些符號在編譯的時候是不知道的。比如 Apache Web 服務器利用這個函數在運行過程中加載模塊,這為它提供了額外的能力。一個配置文件控制了加載模塊的過程。這種機制使得在系統中添加或者刪除一個模塊時,都不需要重新編譯了。

可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定義,并在 dl 庫中實現。它需要兩個參數:一個文件名和一個標志。文件名可以是我們學習過的庫中的 soname。標志指明是否馬上計算庫的依靠性。假如設置為 RTLD_NOW 的話,則馬上計算;假如設置的是 RTLD_LAZY,則在需要的時候才計算。另外,可以指定 RTLD_GLOBAL,它使得那些在以后才加載的庫可以獲得其中的符號。

當庫被裝入后,可以把 dlopen() 返回的句柄作為給 dlsym() 的第一個參數,以獲得符號在庫中的地址。使用這個地址,就可以獲得庫中特定函數的指針,并且調用裝載庫中的相應函數。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久视频在线直播| 亚洲精品美女久久| 亚洲护士老师的毛茸茸最新章节| 亚洲人成亚洲人成在线观看| 黑人巨大精品欧美一区二区一视频| 欧美色视频日本高清在线观看| 精品国产网站地址| 日韩成人av网址| 欧美精品久久久久久久久| 亚洲欧美在线一区二区| 国产激情久久久| 日韩av网址在线| 久久久久久久久中文字幕| 91av在线国产| 国产激情久久久| 亚洲欧美国产va在线影院| 欧美国产日韩二区| 国产精品88a∨| 欧美福利小视频| 国产91久久婷婷一区二区| 日韩**中文字幕毛片| 亚洲大尺度美女在线| 91在线色戒在线| 中文字幕一区二区精品| 亚洲黄色成人网| 亚洲欧美综合精品久久成人| 国产精品美女久久久久久免费| 欧美激情18p| 国产欧美精品一区二区三区-老狼| 久久久亚洲影院| 亚洲国产精品国自产拍av秋霞| 欧美乱大交做爰xxxⅹ性3| 亚洲xxxx做受欧美| 国产欧美日韩丝袜精品一区| 亚洲跨种族黑人xxx| 日韩av中文字幕在线| 欧美亚洲激情视频| 精品成人av一区| 日韩免费观看高清| 欧美肥婆姓交大片| 亚洲人成网站色ww在线| 国产精品自产拍在线观看| 中文字幕日韩专区| 欧美在线影院在线视频| 久久亚洲精品国产亚洲老地址| 欧美一区二区三区四区在线| 色一情一乱一区二区| 中文字幕亚洲精品| 最近中文字幕2019免费| 午夜精品久久久久久久99黑人| 免费不卡欧美自拍视频| 亚洲精品视频网上网址在线观看| 久久久久久亚洲精品中文字幕| 91精品视频免费观看| 久久久久久九九九| 亚洲精品美女视频| 国产精品第三页| 久久久精品日本| 欧美在线免费观看| 亚洲人成网站色ww在线| 精品国产31久久久久久| 亚洲人成啪啪网站| 国产精品久久久久一区二区| 亚洲国产一区二区三区在线观看| 亚洲精品网址在线观看| 日本精品视频在线播放| 亚洲高清久久久久久| 久久久www成人免费精品张筱雨| 国产成人精品久久二区二区| 亚洲一区二区三区香蕉| 亚洲电影成人av99爱色| 日韩美女主播视频| 久久精品最新地址| 欧美日韩国产麻豆| 俺去亚洲欧洲欧美日韩| 亲子乱一区二区三区电影| 国产精品美女久久久久av超清| 亚洲级视频在线观看免费1级| 国产精品久久久久9999| 亚洲成色www8888| 性色av一区二区三区| 亚洲第一区第二区| 国产精品羞羞答答| 国产成人精品免高潮在线观看| 国产a级全部精品| 国产精品扒开腿做爽爽爽的视频| 久久这里有精品视频| 精品久久久视频| 日韩亚洲欧美中文在线| 亚洲精品国偷自产在线99热| 欧美性受xxxx黑人猛交| 国产精品一区二区三区久久| 亚洲国产私拍精品国模在线观看| 欧美一级高清免费| 亚洲高清免费观看高清完整版| 亚洲欧美国产精品va在线观看| 久久精品国产成人精品| 欧美日韩爱爱视频| 亚洲欧美激情精品一区二区| 精品久久久久久久久久久久久| 亚洲xxxx妇黄裸体| 久久韩剧网电视剧| 国产成人精品亚洲精品| 日韩精品欧美国产精品忘忧草| 亚洲乱码一区av黑人高潮| 免费99精品国产自在在线| 久久久精品亚洲| 国产婷婷97碰碰久久人人蜜臀| 国产99视频在线观看| 成人av资源在线播放| 91精品在线看| 精品国产户外野外| 欧美疯狂性受xxxxx另类| 美女精品视频一区| xxx欧美精品| 亚洲国产精品成人va在线观看| 国内外成人免费激情在线视频网站| 中文字幕久热精品在线视频| 国产99久久久欧美黑人| 国产日韩欧美电影在线观看| 国产精品女主播视频| 两个人的视频www国产精品| 欧美男插女视频| 91日韩在线视频| 国产主播喷水一区二区| 中文字幕亚洲激情| 亚洲91精品在线观看| 日韩欧美一区二区三区久久| 国产精品久久久久久五月尺| 日本精品一区二区三区在线| 亚洲欧美三级伦理| 亚洲专区国产精品| 欧美亚洲另类在线| 亚洲国产欧美一区二区三区久久| 国产精品999999| 97碰在线观看| 亚洲九九九在线观看| 国产欧美在线观看| 国产美女搞久久| 日韩av在线网址| 亚洲影院色在线观看免费| 亚洲精品美女久久久久| 精品国产自在精品国产浪潮| 日韩av日韩在线观看| 久久国产精品久久精品| 伊人久久久久久久久久久| 尤物精品国产第一福利三区| 91在线视频导航| 欧美一级片免费在线| 不卡av在线播放| 日韩免费高清在线观看| 亚洲一区二区中文字幕| 91日韩在线视频| 国产精品视频男人的天堂| 久久精品亚洲94久久精品| 日韩免费在线看| 亚洲a一级视频| 国模叶桐国产精品一区| 久久99精品久久久久久噜噜| 青青草成人在线| 91在线中文字幕| 欧美在线视频免费观看| 久久亚洲精品小早川怜子66| 亚洲美女喷白浆|