1、GDB调试基本命令
(1)开启调试:gdb filename(启动一个程序来调试)或者attach pid(调试正在运行程序)或者file filename(开启gdb后,然后启动一个程序开始执行)
(2)l(list):查看文件
(3)b 6 | b sum | b 8 if i == 10:设置文件行断点;设置函数断点;设置条件断点
(4)info b:查看断点信息
(5)r(run):运行代码
(6)c(continue):继续运行指导遇到断点或退出程序
(7)n(next):下一步,遇到函数,则跳过函数
(8)s(step):下一步,遇到函数,则进入该函数
(9)delete 断点号:删除指定断点
(10)disable 断点号:停止指定断点
(11)p(print) 变量 | 表达式:查看程序运行时对应表达式和变量的值
(12)display 表达式 | info display | undisplay num:自动显示
(13)x显示内存
(14)bt:显示调用栈
(15)set:设置运行中程序变量的值
2、多线程程序调试
(1)info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。
(2)thread ID 切换当前调试的线程为指定ID的线程。
(3)break thread_test.c:123 thread all 在所有线程中相应的行上设置断点
(4)thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。
(5)thread apply all command 让所有被调试线程执行GDB命令command。
(6)set scheduler-locking off|on|step 估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。
注意在set scheduler-locking on,设置只运行当前线程后,需要c一下,代码才会继续往下执行
多线程调试示例程序
- #include <pthread.h>
- #include <stdio.h>
- void print_xs(void* a)
- {
- while(1)
- {
- sleep(1);
- printf("thread %d,x\n",pthread_self());
- }
- return NULL;
- }
- void print_ys(void* a )
- {
- while(1)
- {
- sleep(1);
- printf("thread %d,y\n",pthread_self());
- }
- return NULL;
- }
- int main()
- {
- pthread_t thread_id1,thread_id2;
- pthread_create(&thread_id1,NULL,&print_xs,NULL);
- pthread_create(&thread_id2,NULL,&print_ys,NULL);
- while(1);
- return 0;
- }
#include <pthread.h>
#include <stdio.h>
void print_xs(void* a)
{
while(1)
{
sleep(1);
printf("thread %d,x\n",pthread_self());
}
return NULL;
}
void print_ys(void* a )
{
while(1)
{
sleep(1);
printf("thread %d,y\n",pthread_self());
}
return NULL;
}
int main()
{
pthread_t thread_id1,thread_id2;
pthread_create(&thread_id1,NULL,&print_xs,NULL);
pthread_create(&thread_id2,NULL,&print_ys,NULL);
while(1);
return 0;
}
3、程序core掉调试
(1)设定core文件和文件大小为无限大
ulimit -c unlimited
ulimit unlimited
(2)用gdb查看core文件
gdb ./test test.core
(3)bt查看发生段错误segment error的地方
- #include <stdio.h>
- int sum()
- {
- int i = 100;
- int a = i/0;
- }
- int main()
- {
- sum();
- return 0;
- }
#include <stdio.h>
int sum()
{
int i = 100;
int a = i/0;
}
int main()
{
sum();
return 0;
}
环境:两台centos虚拟机,Host(199.168.128.1),Target(199.168.128.5);Host装有GDB、Target装有GDBserver。
步骤:(1)Host上-g编译生成测试程序test
(2)将测试程序拷贝到Target机上,并执行:gdbserver 199.168.128.1:2345 ./test
(3)在Host机上执行:gdb test;target remote 199.168.128.5:2345
(4)开始打断点,并display查看各个变量的值
注意: (1)第三步时出现 No route to host,关闭Host和Target的防火墙,执行:service iptables stop
(2)如果Target为Arm体系,则需要在Host将GDB源码自行编译成针对Arm平台的程序(暂命名为GDBARM),并在Host上用GDBARM代替GDB来调试程序
(3)同样,对于Target上产生的core,则可将其拷贝到Host上,执行:GDBARM ./test core
(4)参考 http://blog.chinaunix.net/uid-20680966-id-3475824.html