编译与调试工具
gcc
gcc
、g++
分别是gnu的c
、c++
编译器,gcc/g++在执行编译工作的时候,总共需要4步:
- 预处理: 生成预处理文件,后缀名
.i
(预处理器cpp
)
- 编译: 预处理后的文件编译生成汇编语言文件,后缀名
.s
(编译器egcs
)
- 汇编: 汇编语言文件汇编生成目标代码(机器代码)文件,后缀名
.o
(汇编器as
)
- 链接: 链接目标代码, 生成可执行文件 (链接器
ld
)
参数详解
-x language filename
设定文件所使用的语言,使后缀名无效,对以后的多个文件有效,直到下一个参数的使用。
language
可以是:
c, objective-c, c-header, c++, cpp-output, assembler, assembler-with-cpp
。
例如: gcc -x c hello.pig
-x none filename
关掉上一个选项,即让gcc根据文件名后缀,自动识别文件类型
例如: gcc -x c hello.pig -x none hello2.c
-c
只激活预处理,编译和汇编,生成后缀名.o
的obj文件
例如: gcc -c hello.c
-S
只激活预处理和编译,生成后缀名.s
的汇编代码文件。
例如: gcc -S hello.c
-E
只激活预处理,不生成文件,你需要把它重定向到一个输出文件里面。
例如: gcc -E hello.c > pianoapan.txt
-o
指定目标名称,缺省的时候,gcc 编译出来的文件是a.out
例如: gcc -o hello hello.c
,gcc -o hello.asm -S hello.c
-pipe
使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问题
例如: gcc -pipe -o hello.exe hello.c
-ansi
关闭gnu c
中与ansi c
不兼容的特性,激活ansi c
的专有特性
(包括禁止asm
,inline
,typeof
关键字,以及unix
,vax
等预处理宏)。具体参考man page
-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
包含某个代码,简单来说,就是当某个文件需要另一个文件的时候,就可以用它设定,功能就相当于在代码中使用#include<filename>
例如: gcc hello.c -include /root/pianopan.h
-imacros file
将file
文件的宏,扩展到gcc/g++
的输入文件,宏定义本身并不出现在输入文件中。这个选项跟-include
选项很像,但是任何通过扫描file
产生的输出都被丢弃,定义的选项仍被定义,这允许你获得所有头文件的宏定义但不处理他的声明。所有该选项指定的文件将在-include
选项指定的文件之前处理。
-Dmacro
相当于C语言中的#define macro
-Dmacro=defn
相当于C语言中的#define macro=defn
-Umacro
相当于C语言中的#undef macro
-undef
取消对任何非标准宏的定义
-Idir
在你使用#include "file"
的时候,gcc/g++
会先在当前目录查找你所指定的头文件,如果没有找到,他会到缺省的头文件目录找,如果使用-I
指定了目录,他会先在你所指定的目录查找,然后再按常规的顺序去找。对于#include <file>
, gcc/g++
会到-I
指定的目录查找,查找不到,然后将到系统的缺省的头文件目录查找。
-I-
就是取消前一个参数的功能,所以一般在-Idir
之后使用
-idirafter dir
在-I
的目录里面查找失败,将到这个目录里面查找。
-iprefix prefix
,-iwithprefix dir
一般一起使用,当-I
的目录查找失败,会到prefix+dir
下查找
-nostdinc
使编译器不在系统缺省的头文件目录里面找头文件,一般和-I
联合使用,明确限定头文件的位置
-nostdinc++
规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,此选项在创建libg++
库使用
-C
在预处理的时候,不删除注释信息,一般和-E
一起使用,有时候分析程序,用这个很方便的
-M
生成文件关联的信息。包含目标文件所依赖的所有源代码,你可以用gcc -M hello.c
来测试一下,很简单。
-MM
和上面的那个一样,但是它将忽略由#include<file>
造成的依赖关系。
-MD
和-M
相同,但是输出将导入到.d
的文件里面
-MMD
和-MM
相同,但是输出将导入到.d
的文件里面
-Wa,option
此选项传递option
给汇编程序;如果option
中间有逗号,就将option
分成多个选项,然后传递给汇编程序
-Wl.option
此选项传递option
给链接程序;如果option
中间有逗号,就将option
分成多个选项,然后传递给链接程序.
-llibrary
指定编译的时候使用的库 例如: gcc -lcurses hello.c
-Ldir
指定编译的时候,搜索库的路径。如果不指定,编译器将只在标准库的目录找。
-O0
,-O1
,-O2
,-O3
编译器的优化选项的4个级别,-O0
表示没有优化,-O1
为缺省值,-O3
优化级别最高
-g
指示编译器,在编译的时候,产生调试信息。
-gstabs
此选项以stabs格式生成调试信息,但是不包括gdb调试信息。
-gstabs+
此选项以stabs格式生成调试信息,并且包含仅供gdb使用的额外调试信息。
-ggdb
此选项将尽可能的生成gdb可以使用的调试信息。
-static
此选项将禁止使用动态库。
-share
此选项将尽量使用动态库。
-traditional
试图让编译器支持传统的C语言特性
-w
不生成任何警告信息。默认选项
-Wall
生成所有警告信息。
objdump
简单来说objdump
工具就是用来展示目标文件各种信息的。其manpage的描述为:
display information from object files
常用参数
-a
: 如果目标文件是归档文件(archive, .a
),展示归档头部信息(archive header infomation),类似ls -l
- 可以使用
ar tv
,objdump -a
展示每个成员的文件格式
-g
: 显示调试信息
-d
, --disassemble
: 用于反汇编。Display the assembler mnemonics for the machine instructions from the input file.
- This option only disassembles those sections which are expected to contain instructions.
-D
, --disassemble-all
: Like -d, but disassemble the contents of all sections, not just those expected to contain instructions.
-f
: Display summary information from the overall header of each of the objfile files.
-H
: 简短的帮助信息
-s
: 显示指定section的完整内容。默认所有的非空section都会被显示
仅供参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| --archive-headers -a 显示档案库的成员信息,类似ls -l将lib*.a的信息列出。
-b bfdname --target=bfdname 指定目标码格式。这不是必须的,objdump能自动识别许多格式,比如:
objdump -b oasys -m vax -h fu.o 显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。 objdump -i将给出这里可以指定的目标码格式列表。
-C --demangle 将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外, 还使得C++函数名以可理解的方式显示出来。
--debugging -g 显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。 仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。
-e --debugging-tags 类似-g选项,但是生成的信息是和ctags工具相兼容的格式。
--disassemble -d 从objfile中反汇编那些特定指令机器码的section。
-D --disassemble-all 与 -d 类似,但反汇编所有section.
--prefix-addresses 反汇编的时候,显示每一行的完整地址。 这是一种比较老的反汇编格式。
-EB -EL --endian={big|little} 指定目标文件的小端。这个项将影响反汇编出来的指令。 在反汇编的文件没描述小端信息的时候用。例如S-records.
-f --file-headers 显示objfile中每个文件的整体头部摘要信息。
-h --section-headers --headers 显示目标文件各个section的头部摘要信息。
-H --help 简短的帮助信息。
-i --info 显示对于 -b 或者 -m 选项可用的架构和目标格式列表。
-j name --section=name 仅仅显示指定名称为name的section的信息
-l --line-numbers 用文件名和行号标注相应的目标代码, 仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大, 在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
-m machine --architecture=machine 指定反汇编目标文件时使用的架构, 当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。 可以用-i选项列出这里能够指定的架构.
--reloc -r 显示文件的重定位入口。 如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。
--dynamic-reloc -R 显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。
-s --full-contents 显示指定section的完整内容。默认所有的非空section都会被显示。
-S --source 尽可能反汇编出源代码, 尤其当编译的时候指定了-g这种调试参数时,效果比较明显。 隐含了-d参数。
--show-raw-insn 反汇编的时候,显示每条汇编指令对应的机器码, 如不指定--prefix-addresses,这将是缺省选项。
--no-show-raw-insn 反汇编时,不显示汇编指令的机器码, 如不指定--prefix-addresses,这将是缺省选项。
--start-address=address 从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。
--stop-address=address 显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。
-t --syms 显示文件的符号表入口。类似于nm -s提供的信息
-T --dynamic-syms 显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。 它显示的信息类似于 nm -D|--dynamic 显示的信息。
-V --version 版本信息
--all-headers -x 显示所可用的头信息,包括符号表、重定位入口。 -x 等价于-a -f -h -r -t 同时指定。
-z --disassemble-zeroes 一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。
@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
|
strace
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
| -c 统计每个系统调用的时间、次数和错误,并在程序退出时报告摘要 -C 类似于 -c,但在进程运行时也打印常规输出 -D 将跟踪进程作为分离的孙进程运行,而不是作为跟踪对象的父进程运行。 这通过保持跟踪对象是调用进程的直接子进程来减少 strace 的可见效果 -d 输出 strace 关于标准错误的调试信息 -f 跟踪由 fork(2), vfork(2) and clone(2) 调用所产生的子进程 -ff 如果提供 -o FILENAME,则所有进程的跟踪结果输出到相应的 FILENAME.pid 中, pid 是各进程的进程号 -F 该选项已废弃,作用等同于 -f -h 输出简要的帮助信息 -i 在系统调用时打印指令指针 -q 禁止附加、分离等信息。 当输出被重定向到文件并直接运行命令而不是附加命令时,这将自动发生 -qq 如果给定两次,则禁止关于进程退出状态的消息 -r 在每次系统调用进入时打印相对时间戳。它记录连续系统调用开始之间的时间差 -t 在输出中的每一行前加上时间信息 -tt 如果给定两次,在输出中的每一行前加上微秒级的时间信息 -ttt 如果给定三次,则打印的时间将包括微秒,并且开始部分将打印自纪元以来的秒数 -T 显示每一系统调用所耗的时间 -v 输出所有的系统调用。 一些调用关于环境变量,状态,输入输出等调用,由于使用频繁默认不输出 -V 输出 strace 的版本信息. -x 以十六进制形式输出非标准字符串 -xx 所有字符串以十六进制形式输出 -y 与文件描述符参数关联的打印路径 -a COLUMN 设置返回值的输出位置,默认为40 -b SYSCALL 如果达到指定的系统调用,与跟踪进程分离。目前,只支持 execve。 如果希望跟踪多线程进程,因此需要 -f,但不希望跟踪其(可能非常复杂的)子进程,则此选项非常有用 -e EXPR 指定一个表达式,用来控制如何跟踪。格式如下: [qualifier=][!]value1[,value2]... qualifier 只能是 trace, abbrev, verbose, raw, signal, read, write 其中之一。 value 是用来限定的符号或数字。默认的 qualifier 是 trace,感叹号是否定符号。 例如:-e open 等价于 -e trace=open,表示只跟踪 open 调用。 而 -etrace=!open 表示跟踪除了 ope 以外的所有其他调用。有两个特殊的符号 all 和 none, 分别表示跟踪所有和不跟踪任何系统调用。 注意有些 Shell 使用 ! 来执行历史记录里的命令,所以要使用反斜杠对 ! 进行转义 -e trace=SET 只跟踪指定的系统调用。 例如: -e trace=open,close,rean,write 表示只跟踪这四个系统调用,默认的为 trace=all -e trace=file 只跟踪有关文件操作的系统调用 -e trace=process 只跟踪有关进程控制的系统调用 -e trace=network 跟踪与网络有关的所有系统调用 -e strace=signal 跟踪所有与系统信号有关的系统调用 -e trace=ipc 跟踪所有与进程通讯有关的系统调用 -e trace=desc 跟踪所有与文件描述符相关的系统调用 -e trace=memory 跟踪所有与内存映射相关的系统调用 -e abbrev=SET 缩写打印大型结构的每个成员的输出。 默认值是 abbrev=all。-v 选项的效果是 abbrev=none -e verbose=SET 为指定的系统调用集取消引用结构。默认是 verbose=all -e raw=SET 将指定的系统调用的参数以十六进制显示 -e signal=SET 指定跟踪的系统信号,默认为 signal=all。 如 signal=!SIGIO(或 signal=!io),表示不跟踪 SIGIO 信号 -e read=SET 输出从指定文件描述符中读出的数据。例如:-e read=3,5 -e write=SET 输出写入到指定文件中的数据 -o FILENAME 将 strace 的输出写入指定文件 -O OVERHEAD 将跟踪系统调用的开销设置为指定的微秒 -p PID 跟踪指定的进程 -P PATH 只跟踪系统调用的访问路径。多个 -P 选项可用于指定多个路径 -s STRSIZE 指定输出的字符串的最大长度,默认为 32。 注意,文件名不被认为是字符串,总是全部打印 -S SORTBY 根据指定的条件对 -c 选项打印的直方图的输出进行排序。 SORTBY 合法值是 time、calls、name 和 nothing,默认值是 time -u USERNAME 以指定用户的 UID、GID 和补充组执行被跟踪的命令 -E VAR=VAL 为命令设置环境变量 -E VAR 从继承的环境变量列表中删除变量 VAR,然后将其传递给命令
|