gcc和gdb常用命令

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 生成所有警告信息。

GDB命令 比较完整的一篇介绍

另一篇:http://fanqiang.chinaunix.net/program/other/2006-07-14/4834.shtml

(gdb) break main Skip the set-up code Breakpoint 1 at 0x160f: file temp.c, line 9. gdb puts breakpoint at main() (gdb) run Run as far as main() Starting program: /home/james/tmp/temp Program starts running Breakpoint 1, main () at temp.c:9 gdb stops at main() (gdb) n Go to next line This is my program Program prints out (gdb) s step into bazz() bazz (anint=4231) at temp.c:17 gdb displays stack frame (gdb) up Move up call stack #1 0x1625 in main () at temp.c:11 gdb displays stack frame (gdb) p i Show us the value of i $1 = 4231 gdb displays 4231

 

 

 

 

 

1.设置断点

>  b <函数名> <filename:line_no>; 例如: b funb example.cpp:230

2.从断点继续执行

>  c

3.查看当前执行行附近程序代码:

> l l <filename:line_no> 列出filename line_no附近代码

4.单步向下执行

>  n

5. 单步执行,进入子函数

> s   在执行到函数调用点时,使用s进入子函数,用n是跳过子函数

6. 显示变量值

> p <变量名>  p var p/x var 前才以十进制方式给出var的值,后才以十六进制方式。对于字符串变量,p str会显示字符串内容,p/x str给出str的地址值。对于自定义结构型变量,p struct_var p/x struct_var会显示struct_var的地址,p *struct_var 会给出struct_var变量的内容。

7. 执行程序:

>  r dbg执行后,进入gdb的提示符,用户在定提示符下可打印变量值,查看程序代码或是设置断点。之后,用r命令开始执行被调试程序,之后被调试程序进入单步执行状态。

查看堆栈

> bt

参数设置

(gdb)set args –b –x
(gdb) show args

变量的类型
(gdb) whatis p
type = int *

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 的值。

检查 core 文件

要检查一个 core 文件,以通常的方式起动 gdb。不要 输入 break 或者 run,而要输入

(gdb) core progname.core

如果你没有和 core 文件在同一个目录,首先要执行 dir /path/to/core/file

你应该可以看见:

% gdb a.out
GDB 
is free software and you are welcome to 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.
GDB 
4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
(gdb) core a.
out.core
Core was generated by `a.
out'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 
0x7020796d.
#
0  0x164a in bazz (anint=0x5) at temp.c:17
(gdb)

这种情况下,运行的程序叫 a.out,因此 core 文件 就叫 a.out.core。我们知道程序崩溃的原因就是函数 bazz 试图访问一块不属于它的内存。

有时候,能知道一个函数是怎么被调用的是非常有用处的。因为在一个复杂的程序里面问题可能会发生在函数调用栈上面很远的地方。命令 bt 会让 gdb 输出函数调用栈的回溯追踪。

(gdb) bt
#0  0x164a in bazz (anint=0x5) at temp.c:17
#1  0xefbfd888 in end ()
#2  0x162c in main () at temp.c:11
(gdb)

函数 end() 在一个程序崩溃的时候将被调用;在本例中,函数 bazz() 是从 main() 中被 调用的。

 

gdb 一个最精致的特性就是它能粘付到一个已经在运行的程序上。当然,我们得首先假定你有足够的权限这样去做。一个常见的问题就是,当我们在追踪一个包含子进程的程序时,如果你要追踪子进程,但是调试器只允许你追踪父进程。

你要做的就是起动另一个 gdb,然后用 ps 找出子进程的进程号。然后在 gdb中执行

(gdb) attach pid

就可以像平时一样调试了。

“这很好,”你可能在想,“当我这样做了以后,子进程就会不见了”。别怕,亲爱的读者,我们可以这样来做(参照 gdb 的 info 页)


if ((pid = fork()) < 0)      /* _Always_ check this */
    error();
else if (pid == 0) {        /* child */
    
int PauseMode = 1;

    
while (PauseMode)
        sleep(
10);  /* Wait until someone attaches to us */
    
else {            /* parent */
    

现在所有你要做的就是粘付到子进程,设置 PauseMode0,然后等待函数 sleep 返回!

 

 

使用Vmware问题:

1)使用其Tool来实现XP和Vmware中Linux的目录共享,开始使用鼠标点击rpm安装包运行,怎么了不能共享。后来,我通过命令方式安装,这样就好了。这也比较奇怪,既然不能成功,为何要提供啊?

 

使用gdb的问题:

1)n 输出“the program be not runned”, 通过b设置断点,然后运行到断点,再n/s就可以输出每步的执行语句,p输出变量值也可以使用,很奇怪,不知道什么原因。

 

linux下g++使用的 makefile 模板

这个makefile可用于编译大多数的c++工程。
你可以根据需要修改下面的参数:
VPATH: 源文件的文件路径。多个文件夹路径用空格分隔
OBJ: 编译目标所需要的.o文件
当然,你也可以不改动此文件,而直接在 make 命令的参数中指定
如:
make VPATH="path1 path2" OBJ="main.o a.o b.o"

 

Code

 

在Target机上操作:

1) ulimit -S -c unlimited > /dev/null 2>&1

2) 运行程序./panda_elf,发生异常生成core.13811

将core.13811拷贝到Host机上以便进行分析:
1) mipsel-linux-gdb -c core.13811 panda_elf
2) 列出问题所在(gdb) where
注意红色标志部分,IpanelScreen::keyReleaseEvent ()是我们实行的Qt按键处理函数,cormdump的入口就在这里。
地址0x0048d558就是产生问题的入口:
#0  0x0048d558 in IpanelScreen::keyReleaseEvent ()
3) mipsel-linux-objdump -d panda_elf > panda_elf.asm
将panda_elf反汇编,用UE打开panda_elf.asm,找出地址48d558(去掉前面的零)所在的行,最后定位是一个全局变量没有加互斥保护。
另外,如果编译时打开debug选项,则可以在gdb中直接查看是哪一行的源代码导致coredump,不用再反汇编那么麻烦
posted @ 2009-07-08 23:34  辛勤耕耘  阅读(1754)  评论(0编辑  收藏  举报