程序的编译与调试
gcc (gnu c compiler)
gcc所支持的后缀名
.c c原始程序
.C/.cc/.cxx c++原始程序
.i 已经预处理的c原始程序
.ii 已经预处理的c++原始程序
.s/.S 汇编语言原始程序
.h 预处理文件
.o 目标文件
.a/.so 编译后的库文件
gcc的编译流程
预处理
编译
汇编
链接
gcc 的总体选项
-c 只编译不链接,生成目标文件.o
-S 只编译不汇编,生成汇编代码
-E 只进行预编译
-g 在可执行程序中包含标准调试信息
-o file 把输出文件输出到file中
-v 打印出编译器内部编译各过程的命令行信息和编译器版本
-I 在头文件的搜索路径列表中添加dir目录
-static 链接静态库
-llibrary 链接名为 library的库文件
gcc的安装
[root@localhost Server]#yun install gcc
示例代码如下
[retacn@localhost tmp]$ vi hello.c
#include <stdio.h>
int main (void){
printf("hello world\n");
return 0;
}
使用gcc编译命令
[retacn@localhost tmp]$ gcc hello.c -o hello
运行程序
[retacn@localhost tmp]$ ./hello
hello world
只进行预编译不作其他处理
[retacn@localhost tmp]$ gcc -E hello.c -o hello.i
[retacn@localhost tmp]$ cat hello.i
extern char *ctermid (char *__s) __attribute__ ((__nothrow__));
# 814 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 844 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
int main (void){
printf("hello world\n");
return 0;
}
只编译不汇编,生成汇编代码
[retacn@localhost tmp]$ gcc -S hello.i -o hello.s
[retacn@localhost tmp]$ cat hello.s
.file "hello.c"
.section .rodata
.LC0:
.string "hello world"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
movl $.LC0, (%esp)
call puts
movl $0, %eax
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-52)"
.section .note.GNU-stack,"",@progbits
只编译不链接,生成目标文件.o
[retacn@localhost tmp]$ gcc -c hello.s -o hello.o
[retacn@localhost tmp]$ gcc hello.o -o hello
[retacn@localhost tmp]$ ./hello
hello world
在可执行程序中包含标准调试信息
[retacn@localhost tmp]$ gcc -g hello.c -o hello2
完成程序的优化工作
[retacn@localhost tmp]$ gcc -O2 hello.c -o hello3
[retacn@localhost tmp]$ ll
总计 288
-rwxrw-r-- 1 retacn retacn 158 01-04 03:45 function.main
-rwxrwxr-x 1 retacn retacn 4941 01-10 04:23 hello
-rwxrwxr-x 1 retacn retacn 6105 01-10 04:26 hello2
-rwxrwxr-x 1 retacn retacn 4957 01-10 04:27 hello3
=============================================================
gdb程序调试
启动被调试程序
让被调用的程序在指定的位置停住(有点像断点)
当程序停住时,可以检查程序状态
g++安装
[root@localhost ~]# yum install gdb
程序调试示例代码如下:
#include <stdio.h>
int main(void){
int i;
long result=0;
for(i=1;i<=100;i++){
result+=i;
}
printf("result=%d\n",result);
return 0;
}
编译程序
[root@localhost tmp]# gcc -g tst.c -o tst
启动gdb
[root@localhost tmp]# gdb tst
也可以使用
[root@localhost tmp]# gdb
(gdb) file 文件名
设置断点
(gdb) b main
Breakpoint 1 at 0x80483b5: file tst.c, line 4.
运行程序
(gdb) run
Starting program: /home/retacn/tmp/tst
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
Breakpoint 1, main () at tst.c:4
4 long result=0;
单步执行
(gdb) next
5 for(i=1;i<=100;i++){
安成执行
(gdb) c
Continuing.
result=5050
Program exited normally.
gdb命令
list(l)查看程序
break(b) 函数名 在函数入口添加断点
break(b) 行号 在指定行添加断点
break(b) 文件名:行号 在指定文件的指定行添加断点
break(b) 行号 if 条件 当条件为真时,在指定行添加断点
inf break 查看所有设置断点
delete 断点编号 删除段点
run(r) 开始执行程序
next(n) 单步运行程序(不进入子函数)
step(s) 单步运行程序(进入子函数)
continue(c) 继续运行程序
print(p)变量名 查看指定变量值
finish 运行程序,直到当前函数结束
watch 变量名 对指定变量进行监控
quit(q) 退出
gcc (gnu c compiler)
gcc所支持的后缀名
.c c原始程序
.C/.cc/.cxx c++原始程序
.i 已经预处理的c原始程序
.ii 已经预处理的c++原始程序
.s/.S 汇编语言原始程序
.h 预处理文件
.o 目标文件
.a/.so 编译后的库文件
gcc的编译流程
预处理
编译
汇编
链接
gcc 的总体选项
-c 只编译不链接,生成目标文件.o
-S 只编译不汇编,生成汇编代码
-E 只进行预编译
-g 在可执行程序中包含标准调试信息
-o file 把输出文件输出到file中
-v 打印出编译器内部编译各过程的命令行信息和编译器版本
-I 在头文件的搜索路径列表中添加dir目录
-static 链接静态库
-llibrary 链接名为 library的库文件
gcc的安装
[root@localhost Server]#yun install gcc
示例代码如下
[retacn@localhost tmp]$ vi hello.c
#include <stdio.h>
int main (void){
printf("hello world\n");
return 0;
}
使用gcc编译命令
[retacn@localhost tmp]$ gcc hello.c -o hello
运行程序
[retacn@localhost tmp]$ ./hello
hello world
只进行预编译不作其他处理
[retacn@localhost tmp]$ gcc -E hello.c -o hello.i
[retacn@localhost tmp]$ cat hello.i
extern char *ctermid (char *__s) __attribute__ ((__nothrow__));
# 814 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 844 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
int main (void){
printf("hello world\n");
return 0;
}
只编译不汇编,生成汇编代码
[retacn@localhost tmp]$ gcc -S hello.i -o hello.s
[retacn@localhost tmp]$ cat hello.s
.file "hello.c"
.section .rodata
.LC0:
.string "hello world"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
movl $.LC0, (%esp)
call puts
movl $0, %eax
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-52)"
.section .note.GNU-stack,"",@progbits
只编译不链接,生成目标文件.o
[retacn@localhost tmp]$ gcc -c hello.s -o hello.o
[retacn@localhost tmp]$ gcc hello.o -o hello
[retacn@localhost tmp]$ ./hello
hello world
在可执行程序中包含标准调试信息
[retacn@localhost tmp]$ gcc -g hello.c -o hello2
完成程序的优化工作
[retacn@localhost tmp]$ gcc -O2 hello.c -o hello3
[retacn@localhost tmp]$ ll
总计 288
-rwxrw-r-- 1 retacn retacn 158 01-04 03:45 function.main
-rwxrwxr-x 1 retacn retacn 4941 01-10 04:23 hello
-rwxrwxr-x 1 retacn retacn 6105 01-10 04:26 hello2
-rwxrwxr-x 1 retacn retacn 4957 01-10 04:27 hello3
=============================================================
gdb程序调试
启动被调试程序
让被调用的程序在指定的位置停住(有点像断点)
当程序停住时,可以检查程序状态
g++安装
[root@localhost ~]# yum install gdb
程序调试示例代码如下:
#include <stdio.h>
int main(void){
int i;
long result=0;
for(i=1;i<=100;i++){
result+=i;
}
printf("result=%d\n",result);
return 0;
}
编译程序
[root@localhost tmp]# gcc -g tst.c -o tst
启动gdb
[root@localhost tmp]# gdb tst
也可以使用
[root@localhost tmp]# gdb
(gdb) file 文件名
设置断点
(gdb) b main
Breakpoint 1 at 0x80483b5: file tst.c, line 4.
运行程序
(gdb) run
Starting program: /home/retacn/tmp/tst
warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
Breakpoint 1, main () at tst.c:4
4 long result=0;
单步执行
(gdb) next
5 for(i=1;i<=100;i++){
安成执行
(gdb) c
Continuing.
result=5050
Program exited normally.
gdb命令
list(l)查看程序
break(b) 函数名 在函数入口添加断点
break(b) 行号 在指定行添加断点
break(b) 文件名:行号 在指定文件的指定行添加断点
break(b) 行号 if 条件 当条件为真时,在指定行添加断点
inf break 查看所有设置断点
delete 断点编号 删除段点
run(r) 开始执行程序
next(n) 单步运行程序(不进入子函数)
step(s) 单步运行程序(进入子函数)
continue(c) 继续运行程序
print(p)变量名 查看指定变量值
finish 运行程序,直到当前函数结束
watch 变量名 对指定变量进行监控
quit(q) 退出