ps:前不久好像说过linux的ARM-CPU结构体系。最近一直在搬家,很忙,上网时间少,也没写什么文章,也不知道写点什么,因为很多东西baidu一大堆。今天随便补充点儿东西!
makefile的一些用法:再了解makefile之前,希望大家好好了解一下vi的用法,有兴趣也可了解一下Emacs的高级用法,掌握一下GCC的用法。还有由于linux的shell命令很多也不想一一讲解。在此之前我先深入浅出的介绍一下GDB的用法。
我们先看一个例子(">"先用这个符号代表注释部分):
//源代码
#include<stdio.h>
int func(int n)
{
int sum = 0,i;
for(i = 0; i < n; i++)
{
sum += i;
}
return sum;
}
main()
{
int i;
long result = 0;
for(i = 1; i <= 100; i++)
{
result += 1;
}
printf("result[1-100] = %d n ",result);
printf("result[1-250] = %d n ",func(250));
}
>我们先进行编译
[root@localhost opencTM]# vi test.c
[root@localhost opencTM]# gcc -Werror -g test.c -o test
[root@localhost opencTM]#
>然后我们进行调试一下
[root@localhost opencTM]# gdb
GNU gdb Everest Linux (6.4-2)
Copyright 2005 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 "i686-pc-linux-gnu".
(gdb)
>载入文件test
(gdb) file test
Reading symbols from /root/My Documents/opencTM/test...done.
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb)
>列出部分代码
(gdb) list
5 int sum = 0,i;
6 for(i = 0; i < n; i++)
7 {
8 sum += i;
9 }
10 return sum;
11 }
12
13 main()
14 {
(gdb)
>直接按回车继续上一个命令
(gdb)
15 int i;
16 long result = 0;
17 for(i = 1; i <= 100; i++)
18 {
19 result += 1;
20 }
21 printf("result[1-100] = %d n ",result);
22 printf("result[1-250] = %d n ",func(250));
23 }
24
(gdb)
>设置断点,分别在主函数和func入口处。
(gdb) break main
Breakpoint 1 at 0x80483a1: file test.c, line 14.
(gdb) break func
Breakpoint 2 at 0x804837a: file test.c, line 5.
(gdb)
>查看断点信息
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483a1 in main at test.c:14
2 breakpoint keep y 0x0804837a in func at test.c:5
(gdb)
>运行程序
(gdb) run
Starting program: /root/My Documents/opencTM/test
Breakpoint 1, main () at test.c:14
14 {
(gdb)
>由于我不想从断点main处运行,想从func函数开始运行我们来个跳转
(gdb) jump func
Line 5 is not in `main'. Jump anyway? (y or n) y
Continuing at 0x804837a.
Breakpoint 2, func (n=134513569) at test.c:5
5 int sum = 0,i;
(gdb)
>发现一个错误,可能这里没有基础的人看不明白,此处n=134513569根本不是我们想要的值,这是怎么回事,等等再告诉大家这个jump跳转在跳转的同时可能会出现非比寻常的错误,此处就是一个在n还没有发生累加同时系统随机给n赋值产生错误,我们回过头来再调试!
(gdb) clear
Deleted breakpoint 2
(gdb) break func
Breakpoint 3 at 0x804837a: file test.c, line 5.
(gdb) run
Starting program: /root/My Documents/opencTM/test
result[1-100] = 100
Breakpoint 1, func (n=250) at test.c:5
5 int sum = 0,i;
(gdb)
>这回对了,n=250。。。我们开始没条语句进行调试。。。别忘了,直接按回车进行上一次命令重复!
(gdb) next
6 for(i = 0; i < n; i++)
(gdb)
8 sum += i;
(gdb)
6 for(i = 0; i < n; i++)
gdb)
8 sum += i;
(gdb)
6 for(i = 0; i < n; i++)
(gdb)
8 sum += i;
(gdb)
6 for(i = 0; i < n; i++)
(gdb)
8 sum += i;
(gdb) c
Continuing.
result[1-250] = 31125 //此处注释一下,应该有点问题。已经退出了!我要检查一下。。。
Program exited with code 030.
(gdb)
>忘了告诉大家,本来想后来再说的,刚刚误输入现在只能先说了,所有命令在GDB中都可以缩写,GDB会帮助补全,比如run我们也可输入“r”,所以刚才输入的“c”就是continue。。。然后我们继续。。。
(gdb) p i
$1 = 3
(gdb)
>晕!又输错了,"p"的意思就是print,打印i现在值。
>next后面可以是一个表达式。。。
(gdb) n sum += i
8 sum += i;
(gdb)
>查看堆栈
(gdb) bt
#0 func (n=250) at test.c:8
#1 0x080483ef in main () at test.c:22
>退出函数
(gdb) finish
Run till exit from #0 func (n=250) at test.c:8
0x080483ef in main () at test.c:22
22 printf("result[1-250] = %d n ",func(250));
Value returned is $2 = 31128
(gdb)
>继续运行
(gdb) c
Continuing.
result[1-250] = 31128
Program exited with code 030.
>已经退出了.
>退出
(gdb) q
[root@localhost opencTM]#
>可能对于不了解GBD的人来说很茫然,所以我系统的再介绍一下,可能会有遗漏与不足的地方希望谅解。。。
GBD有很多命令,比如:
file----装入想要调试的可执行文件!
kill----终止正在调试的程序!
list----列出产生文件源代码的一部分!
next----执行一行源代码,但是不进入函数的内部!
step----执行代码并且进入函数内部!
run----执行正在被调试的程序!
quit---终止并退出调试!
watch----监视一个值,无论什么时候改变始终监视!
break----在代码里设置断点!
make----不必退出!
shell----不必离开!
1:先说一下启动gdb,启动gdb一般在后面输入你要启动的文件名字就可以,比如刚才我们同样可以输入gdb test,也可以再输入GDB回车后用file命令载入要调试的文件比如:file test。
我们还可以再你的program后面加一个core,而core是程序非法执行core dump后产生的文件。
还可以再你的program后面加上一个PID,比如你的程序是一个服务程序,那么这个服务程序的进程ID,gbd会自动连上并调试,这个program应该在PATH环境变量中搜索得到!在调试的时候,我们可以先ps查看正在运行程序的PID,然后用attach挂载上,当程序调试完后,我们可以用detach取消挂载的进程。
我们还可以加一些选项,比如:
-se file //从指定文件中读取符号表
-c file //调试core dump的core文件。
-d directory //加入一些搜索路径。
2:我们可以帮助,只需输入和help就可以比如:
help class:查看种类中的命令
help breakpoint:查看断点
help command:查看命令等等。我们也可自动补上我们忘记的命令写法,与shell方法相同,就是输入头字母然后连按两下[tab]就可以自动补上,比如:
(gdb) b
backtrace break bt
(gdb) b
如上,输入b,然后连按两下[tab]就会自动补上命令的查看。我们也可用缩写,比如quit可以直接写成q:
(gdb) q
[root@localhost opencTM]#
这样我们就退出了,与quit命令相同!
3:我们在gdb中可以用shell命令,方法很简单,直接输入shell command就可以了。比如:
(gdb) shell pwd
/root
(gdb)
这样我们在gdb中就可以调用shell命令了。我们也可用make来修改程序,这个与shell make基本相同。
4:运行程序run,在运行程序之前,我们可以设置很多程序参数,比如set args 可以指定运行的参数,比如输入set args 10 20 30 40 50 。我们当然可以查看参数,输入show args。
其次我们可以设置运行环境,用path,查看运行环境show path,(由于现在没有网络,有些东西介绍起来很不方便,而且网上这些命令详细用法很多,有兴趣可以自己好好研究一下,我只能做个简单介绍!)。
还可以设置环境变量:set environments,比如set env user=openctm。同时可以查看:show env [环境变量名]。
顺便加上一个程序输入与输出可以使用重定向“>”比如:run > outfile。还有tty输入输出的终端设备等等。。。
由于时间问题,我们只能说到这里,gdb很强大,比如还有:break设置断点,设置watch观察点,设置catch捕获点,clear维护停止点,查看栈信息bt,搜索源代码search查看改变数据print(不止能打印,还可以改变!)及跳转指令jump,信号量singal,强制返回return强制调用call,及程序调试的方式直接运行,单步调试等等也不是一下两下能说完的,而且调试还需要大家对调试相当有经验,而且每一个命令都有很多扩展用法,有兴趣可以baidu查看。。。
本来要说一下makefile的用法,现在打了这么多就再跟一篇说一下makefile的用法吧。。。