gcc g++ 常用編譯選項
|
 |
Linux中gcc,g++常用編譯選項
-x language filename
設定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根據約定,C語言的后綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個
性,決定你的C代碼文件的后綴名是.pig
哈哈,那你就要用這個參數,這個參數對他后面的文件名都起作用,除非到了下一個參數的使用。可以使用的參數有下面的這些: `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a ssembler-with-cpp'. 看到英文,應該可以理解的。 例子用法: cd..
gcc -x c hello.pig
-x none filename 關掉上一個
/* 注釋中的不常用****************************************************
-fno-asm 此選項實現ansi選項的功能的一部分,它禁止將asm,inline和typeof用作關鍵字。 -fno-strict-prototype 只對g++起作用,使用這個選項,g++將對不帶參數的函數,都認為是沒有顯式的對參數的個數和類型說明,而不是沒有參數. 而gcc無論是否使用這個參數,都將對沒有帶參數的函數,認為沒有顯式說明的類型
-fthis-is-varialble 就是向傳統c++看齊,可以使用this當一般變量使用. -fcond-mismatch 允許條件表達式的第二和第三參數類型不匹配,表達式的值將為void類型 -funsigned-char -fno-signed-char -fsigned-char -fno-unsigned-char 這四個參數是對char類型進行設置,決定將char類型設置成unsigned char(前兩個參 數)或者 signed char(后兩個參數)
*注釋完成*********************************************/
-include file 包含某個代碼,簡單來說,就是便于某個文件需要另一個文件的時候,就可以用它設 定,功能就相當于在代碼中使用#i nclude<filename> 例子用法: gcc hello.c -include /root/pianopan.h -imacros file 將file文件的宏,擴展到gcc/g++的輸入文件,宏定義本身并不出現在輸入文件中 -Dmacro 相當于C語言中的#define macro -Dmacro=defn 相當于C語言中的#define macro=defn -Umacro 相當于C語言中的#undef macro -undef 取消對任何非標準宏的定義 -Idir 在你是用#i nclude"file"的時候,gcc/g++會先在當前目錄查找你所制定的頭文件,如 果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他 回先在你所制定的目錄查找,然后再按常規的順序去找. 對于#i nclude<file>,gcc/g++會到-I制定的目錄查找,查找不到,然后將到系統的缺 省的頭文件目錄查找 -I- 就是取消前一個參數的功能,所以一般在-Idir之后使用 -idirafter dir 在-I的目錄里面查找失敗,講到這個目錄里面查找. -iprefix prefix -iwithprefix dir 一般一起使用,當-I的目錄查找失敗,會到prefix+dir下查找 -nostdinc 使編譯器不再系統缺省的頭文件目錄里面找頭文件,一般和-I聯合使用,明確限定頭 文件的位置 -nostdin C++ 規定不在g++指定的標準路經中搜索,但仍在其他路徑中搜索,.此選項在創libg++庫 使用 -C 在預處理的時候,不刪除注釋信息,一般和-E使用,有時候分析程序,用這個很方便的
-M 生成文件關聯的信息。包含目標文件所依賴的所有源代碼你可以用gcc -M hello.c 來測試一下,很簡單。 -MM 和上面的那個一樣,但是它將忽略由#i nclude<file>造成的依賴關系。 -MD 和-M相同,但是輸出將導入到.d的文件里面 -MMD 和-MM相同,但是輸出將導入到.d的文件里面 -Wa,option 此選項傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選項,然 后傳遞給會匯編程序 -Wl.option 此選項傳遞option給連接程序;如果option中間有逗號,就將option分成多個選項,然 后傳遞給會連接程序. -llibrary 制定編譯的時候使用的庫 例子用法 gcc -lcurses hello.c 使用ncurses庫編譯程序 -Ldir 制定編譯的時候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然 編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。 -O0 -O1 -O2 -O3 編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為缺省值,-O3優化級別最高 -g 只是編譯器,在編譯的時候,產生調試信息。 -gstabs 此選項以stabs格式聲稱調試信息,但是不包括gdb調試信息. -gstabs+ 此選項以stabs格式聲稱調試信息,并且包含僅供gdb使用的額外調試信息. -ggdb 此選項將盡可能的生成gdb的可以使用的調試信息. -static 此選項將禁止使用動態庫,所以,編譯出來的東西,一般都很大,也不需要什么 動態連接庫,就可以運行. -share 此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫. -traditional 試圖讓編譯器支持傳統的C語言特性
|
|
posted @
2008-12-27 00:36 。。。。 閱讀(3171) |
評論 (0) |
編輯 收藏
*************構建ACE:
1、下載,解壓縮ACE包,設置環境變量PATH包含$ACE_ROOT$/bin
2、設置$ACE_ROOT$/ace/config.h,加入一行:(該語句是ACE針對WIN32平臺的配置文件)
#include "ace/config-win32.h"
注意:
A、如果你使用9x/Me,加入:
#define ACE_HAS_WINNT4 0
B、如果你要使用標準C++頭文件的話
#define ACE_HAS_STANDARD_CPP_LIBRARY 1
C、要使用MFC的話
#define ACE_HAS_MFC 1
以上的define語句都要在#include "ace/config-win32.h"之前包含
3、VC6打開$ACE_ROOT$/ace/ace.dsw,VC.net打開$ACE_ROOT$/ace/ace/ace.sln,構建ACE
4、構建成功與否,可打開$ACE_ROOT$/tests下的工程文件看看能不能編譯通過
其實,如果你初學ACE的話,暫時還不想涉及上面煩瑣的步驟的話,可以找一個.exe安裝包,安裝完成之后,打開ace.dsw/ace.sln即可構建
了;偶開始學ACE的時候,就是使用《ACE程序員指南 網絡與系統編程的實用設計模式》書后自帶光盤中ACE53b.exe安裝、構建的。
**************在你的程序中使用ACE方法:打開項目-->設置:
C/C++選項卡
Code Generation:選擇多線程版的運行時庫(如:Debug Multithreaded DLL)
Proprocessor:在“附加包含路徑”中包含$ACE_ROOT$
Link選項卡
Input:在“對象/庫模塊”包含適當的ACE庫文件名(附表A)
加上.lib,如:aced.lib,acesd.lib等
Input:在“附加庫路徑”中包含$ACE_ROOT$/ace
**************附表A:
-----------------------------------------------------------
配置 文件名
-----------------------------------------------------------
DLL debug aced
DLL release ace
Static library debug acesd
Static library release aces
MFC DLL debug acemfcd
MFC DLL release acemfc
-----------------------------------------------------------
英文比較好的,可直接查看$ACE_ROOT$/ACE-INSTALL.html#msvc
ACE環境構建筆記(Linux) :)
**************構建ACE**************
1:下載ACE源碼包。我下的是5.4版的,文件名為ACE54SRC.tar.gz。gzip解壓,tar解包后,得到一個叫ACE_wrappers
的目錄,我把它放在/home/lok/ace目錄下。注意如果我沒有特別說明,所有操作都是在一般用戶下進行的。
2:編譯前的必要工作。
設置環境變量,在shell下輸入:ACE_ROOT=/home/lok/ace/ACE_wrappers; export ACE_ROOT
(注意上面的操作是在同一行中執行的,如果要分行,可以不用分號)。這樣設置的變量只是臨時的,如果想要永久保存這個變量,可以切換到root,把變量寫到文件/etc/profile中;
在$ACE_ROOT/ace目錄下新建一個config.h文件,內容為:#include "ace/config-linux.h"
在$ACE_ROOT/include/makeinclude目錄下新建一個platform_macros.GNU文件,內容為:include
$(ACE_ROOT)/include/makeinclude/platform_linux.GNU
3:在$ACE_ROOT目錄下,新建一個目錄,用以執行configure的結果
mkdir aaa
cd aaa
在$ACE_ROOT/aaa中運行
../configure
在確認結果無誤后,執行
make
4:切換到root用戶,把剛生成的libACE.so和libACE.so.5.4.0(在$ACE_ROOT/ace目錄下)拷貝到/usr/lib,ACE開發環境構建完畢!
**************寫個小程序測試ACE**************
1:編寫Log_Msg.cpp,內容如下:
#include "ace/Log_Msg.h"
void foo (void);
int ACE_TMAIN (int, ACE_TCHAR *[])
{
ACE_TRACE(ACE_TEXT ("main"));
ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n")));
foo();
ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));
return 0;
}
void foo (void)
{
ACE_TRACE (ACE_TEXT ("foo"));
ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
}
2:寫makefile,內容如下:
LIB = -lACE
LIBPATH = -L$(ACE_ROOT)/ace
HPATH = -I$(ACE_ROOT)
Log_Msg : Log_Msg.cpp
g++ Log_Msg.cpp -o Log_Msg $(LIB) $(LIBPATH) $(HPATH)
3:make,運行Log_Msg,測試完畢!
***************補充*************
$(ACE_ROOT)/example下有很多例子可以參考,但你會發現它們的makefile寫得很奇怪,這是因為這些makefile是由程序自動
生成的,目的是讓它們可以在不同系統下都可正常工作。關于這些makefile,可以到http://www.kehui.net
/index.php?op=article&file=read&aid=30812去看一下。如果你的程序只需要在linux下工
作,那只要自己寫上-lACE就可以了。
posted @
2008-12-26 23:57 。。。。 閱讀(1015) |
評論 (0) |
編輯 收藏
當我們的程序崩潰時,內核有可能把該程序當前內存映射到core文件里,方便程序員找到程序出現問題的地方。最常出
現的,幾乎所有C程序員都出現過的錯誤就是“段錯誤”了。也是最難查出問題原因的一個錯誤。下面我們就針對“段錯誤”來分析core文件的產生、以及我們
如何利用core文件找到出現崩潰的地方。
何謂core文件
當一個程序崩潰時,在進程當前工作目錄的core文件中復制了該進程的存儲圖像。core文件僅僅是一個內存映象(同時加上調試信息),主要是用來調試的。
當程序接收到以下UNIX信號會產生core文件:
名字
|
說明
|
ANSI C POSIX.1
|
SVR4 4.3+BSD
|
缺省動作
|
SIGABRT
|
異常終止(abort)
|
. .
|
. .
|
終止w/core
|
SIGBUS
|
硬件故障
|
.
|
. .
|
終止w/core
|
SIGEMT
|
硬件故障
|
|
. .
|
終止w/core
|
SIGFPE
|
算術異常
|
. .
|
. .
|
終止w/core
|
SIGILL
|
非法硬件指令
|
. .
|
. .
|
終止w/core
|
SIGIOT
|
硬件故障
|
|
. .
|
終止w/core
|
SIGQUIT
|
終端退出符
|
.
|
. .
|
終止w/core
|
SIGSEGV
|
無效存儲訪問
|
. .
|
. .
|
終止w/core
|
SIGSYS
|
無效系統調用
|
|
. .
|
終止w/core
|
SIGTRAP
|
硬件故障
|
|
. .
|
終止w/core
|
SIGXCPU
|
超過CPU限制(setrlimit)
|
|
. .
|
終止w/core
|
SIGXFSZ
|
超過文件長度限制(setrlimit)
|
|
. .
|
終止w/core
|
在系統默認動作列,“終止w/core”表示在進程當前工作目錄的core文件中復制了該進程的存儲圖像(該文件名為core,由此可以看出這種功能很久之前就是UNIX功能的一部分)。大多數UNIX調試程序都使用core文件以檢查進程在終止時的狀態。
core文件的產生不是POSIX.1所屬部分,而是很多UNIX版本的實現特征。UNIX第6版沒有檢查條件
(a)和(b),并且其源代碼中包含如下說明:“如果你正在找尋保護信號,那么當設置-用戶-ID命令執行時,將可能產生大量的這種信號”。4.3 +
BSD產生名為core.prog的文件,其中prog是被執行的程序名的前1 6個字符。它對core文件給予了某種標識,所以是一種改進特征。
表中“硬件故障”對應于實現定義的硬件故障。這些名字中有很多取自UNIX早先在DP-11上的實現。請查看你所使用的系統的手冊,以確切地確定這些信號對應于哪些錯誤類型。
下面比較詳細地說明這些信號。
• SIGABRT 調用abort函數時產生此信號。進程異常終止。
• SIGBUS 指示一個實現定義的硬件故障。
• SIGEMT 指示一個實現定義的硬件故障。
EMT這一名字來自PDP-11的emulator trap 指令。
• SIGFPE 此信號表示一個算術運算異常,例如除以0,浮點溢出等。
• SIGILL 此信號指示進程已執行一條非法硬件指令。
4.3BSD由abort函數產生此信號。SIGABRT現在被用于此。
• SIGIOT 這指示一個實現定義的硬件故障。
IOT這個名字來自于PDP-11對于輸入/輸出TRAP(input/output TRAP)指令的縮寫。系統V的早期版本,由abort函數產生此信號。SIGABRT現在被用于此。
• SIGQUIT 當用戶在終端上按退出鍵(一般采用Ctrl-\)時,產生此信號,并送至前臺進
程組中的所有進程。此信號不僅終止前臺進程組(如SIGINT所做的那樣),同時產生一個core文件。
• SIGSEGV 指示進程進行了一次無效的存儲訪問。
名字SEGV表示“段違例(segmentation violation)”。
• SIGSYS 指示一個無效的系統調用。由于某種未知原因,進程執行了一條系統調用指令,
但其指示系統調用類型的參數卻是無效的。
• SIGTRAP 指示一個實現定義的硬件故障。
此信號名來自于PDP-11的TRAP指令。
• SIGXCPU SVR4和4.3+BSD支持資源限制的概念。如果進程超過了其軟C P U時間限制,則產生此信號。
• SIGXFSZ 如果進程超過了其軟文件長度限制,則SVR4和4.3+BSD產生此信號。
摘自《UNIX環境高級編程》第10章 信號。
使用core文件調試程序
看下面的例子:
/*core_dump_test.c*/
#include <stdio.h>
const char *str = "test";
void core_test(){
str[1] = 'T';
}
int main(){
core_test();
return 0;
}
編譯:
gcc –g core_dump_test.c -o core_dump_test
如果需要調試程序的話,使用gcc編譯時加上-g選項,這樣調試core文件的時候比較容易找到錯誤的地方。
執行:
./core_dump_test
段錯誤
運行core_dump_test程序出現了“段錯誤”,但沒有產生core文件。這是因為系統默認core文件的大小為0,所以沒有創建。可以用ulimit命令查看和修改core文件的大小。
ulimit -c 0
ulimit -c 1000
ulimit -c 1000
-c 指定修改core文件的大小,1000指定了core文件大小。也可以對core文件的大小不做限制,如:
ulimit -c unlimited
ulimit -c unlimited
如果想讓修改永久生效,則需要修改配置文件,如 .bash_profile、/etc/profile或/etc/security/limits.conf。
再次執行:
./core_dump_test
段錯誤 (core dumped)
ls core.*
core.6133
可以看到已經創建了一個core.6133的文件.6133是core_dump_test程序運行的進程ID。
調式core文件
core文件是個二進制文件,需要用相應的工具來分析程序崩潰時的內存映像。
file core.6133
core.6133: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from 'core_dump_test'
在Linux下可以用GDB來調試core文件。
gdb core_dump_test core.6133
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
Core was generated by `./core_dump_test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x080482fd in core_test () at core_dump_test.c:7
7 str[1] = 'T';
(gdb) where
#0 0x080482fd in core_test () at core_dump_test.c:7
#1 0x08048317 in main () at core_dump_test.c:12
#2 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6
GDB中鍵入where,就會看到程序崩潰時堆棧信息(當前函數之前的所有已調用函數的列表(包括當前函數),gdb只顯示最近幾個),我們很容易找到我們的程序在最后崩潰的時候調用了core_dump_test.c 第7行的代碼,導致程序崩潰。注意:在編譯程序的時候要加入選項-g。您也可以試試其他命令, 如 fram、list等。更詳細的用法,請查閱GDB文檔。
core文件創建在什么位置
在進程當前工作目錄的下創建。通常與程序在相同的路徑下。但如果程序中調用了chdir函數,則有可能改變了當前工
作目錄。這時core文件創建在chdir指定的路徑下。有好多程序崩潰了,我們卻找不到core文件放在什么位置。和chdir函數就有關系。當然程序
崩潰了不一定都產生core文件。
什么時候不產生core文件
在下列條件下不產生core文件:
( a )進程是設置-用戶-ID,而且當前用戶并非程序文件的所有者;
( b )進程是設置-組-ID,而且當前用戶并非該程序文件的組所有者;
( c )用戶沒有寫當前工作目錄的許可權;
( d )文件太大。core文件的許可權(假定該文件在此之前并不存在)通常是用戶讀/寫,組讀和其他讀。
利用GDB調試core文件,當遇到程序崩潰時我們不再束手無策。
posted @
2008-12-10 21:23 。。。。 閱讀(14757) |
評論 (0) |
編輯 收藏
摘要: 便利的開發編輯工具-vim
mounton @ www.ihere.org ( mount0n@yahoo.com)
2003年6月
0. 序言
編程人員花費最長時間的開發工具可能就是編輯器了,一個非常方便、高效的編輯器對開發人員來說是非常有效的。在unix/linux下,甚至windows下,vim都可以說是個非常優秀的編輯器。雖然許多朋友開發過程中都在使用vim,但通常...
閱讀全文
posted @
2008-12-09 21:13 。。。。 閱讀(1037) |
評論 (0) |
編輯 收藏
查看棧信息
當程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。當你的程序調用了一個函數,函數的地址,函數參數,函數內的局部變量都會被壓入“棧”(Stack)中。你可以用GDB命令來查看當前的棧中的信息。
下面是一些查看函數調用棧信息的GDB命令:
Backtrace,bt 打印當前的函數調用棧的所有信息。如:
(gdb) bt
#0 func (n=250) at tst.c:6
#1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30
#2 0x400409ed in __libc_start_main () from /lib/libc.so.6
從上可以看出函數的調用棧信息:__libc_start_main --> main() --> func()
backtrace <n>, bt <n> n是一個正整數,表示只打印棧頂上n層的棧信息。
backtrace <-n> ,bt <-n> -n表一個負整數,表示只打印棧底下n層的棧信息。
如果你要查看某一層的信息,你需要在切換當前的棧,一般來說,程序停止時,最頂層的棧就是當前棧,如果你要查看棧下面層的詳細信息,首先要做的是切換當前棧。
frame <n>,f <n> n是一個從0開始的整數,是棧中的層編號。比如:frame 0,表示棧頂,frame 1,表示棧的第二層。
up <n> 表示向棧的上面移動n層,可以不打n,表示向上移動一層。
down <n> 表示向棧的下面移動n層,可以不打n,表示向下移動一層。
上面的命令,都會打印出移動到的棧層的信息。如果你不想讓其打出信息。你可以使用這三個命令:
select-frame <n> 對應于 frame 命令。
up-silently <n> 對應于 up 命令。
down-silently <n> 對應于 down 命令。
查看當前棧層的信息,你可以用以下GDB命令:
frame 或 f 會打印出這些信息:棧的層編號,當前的函數名,函數參數值,函數所在文件及行號,函數執行到的語句。
info frame,info f 這個命令會打印出更為詳細的當前棧層的信息,只不過,大多數都是運行時的內內地址。比如:函數地址,調用函數的地址,被調用函數的地址,目前的函數是由什么樣的程序語言寫成的、函數參數地址及值、局部變量的地址等等。如:
(gdb) info f
Stack level 0, frame at 0xbffff5d4:
eip = 0x804845d in func (tst.c:6); saved eip 0x8048524
called by frame at 0xbffff60c
source language c.
Arglist at 0xbffff5d4, args: n=250
Locals at 0xbffff5d4, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffff5d4, eip at 0xbffff5d8
info args 打印出當前函數的參數名及其值。
info locals 打印出當前函數中所有局部變量及其值。
info catch 打印出當前的函數中的異常處理信息。
posted @
2008-12-09 21:06 。。。。 閱讀(1817) |
評論 (0) |
編輯 收藏