嵌入式学习小组
直播中

djelje

8年用户 1017经验值
擅长:光电显示
私信 关注

gdb基本命令怎么使用?

gdb基本命令怎么使用?

回帖(1)

李微波

2021-12-24 15:34:00
一、
db简介GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。不可少的工具。
二、gdb基本命令使用
查看断点
信息break [n] – n断点号简写:ib
设置断点
break filename:linenum在源文件文件名的linenum行处停住。break
在进入指定时停住
break ... if ...可以是上述的参数,条件表示条件,在条件程序启动时停住。比如在文件thread.c中,可以设置break if sum == 4,当sum为4时停住。
例如:
gdb)b thread.c:64 if sum == 4删除断断点
delete删除所有
断点简写:d delete breakpoint [n]删除某个
断点disable breakpoint [disable breakpoint]
enable breakpoint [n] 使能
断点恢复程序运行和步调试
continue 继续直到下一个断点运行简写:c
next 追过程继续,不会进入函数简写:n
setp 步步执行,会进入子函数简写:s
直到运行至当前语句块结束简写:u
完成运行至函数结束并跳出,并打印函数的返回值
变量的调试
打印变量值的格式:
打印(可简写为p)打印变量内容
p temp;默认十打印打印打印
p /x temp;按十六打印打印
X按十六进制格式显示变量。
d按十进制格式显示变量。
ü按十六进制格式显示无符号整型。
ö按八进制格式显示变量。
吨按二进制格式显示变量。
一个按十六进制格式显示变量。
ç按字符格式显示变量。
˚F按浮点数格式显示变量。
打印基本类型,结构体,数组等
(1)打印基本类型,结构体,数组等,则直接p变量,即可把对应变量的值(包括其成员)全部出来
(2)如果变量是打印打印变量,要内容,需要p*变量,如果海思p变量,则可以打印打印对应的地址。
(3)除了可以打印全部内容,也可以打印成员变量,包括结构体的成员,数组元素等。只需p变量成员。
设置变量
集合变种变量= XXX
打印全局变量与局部变量
如果你的局部变量状语从句:全局变量发生冲突(重名),一般情况显示下局部变量会隐藏变量,如果一个变量和一个函数中的局部变量名时,如果当前停止点在函数中,用打印出的变量值会是函数中的变量的值。如果此时你想查看变量的值时,你可以使用“::”符操作:
file::variable
function::variable
可以通过这种形式指定你所想查看的变量,是哪个文件中的哪个函数中的
。 c'::sum --文件要加上单引号查看文件的全局变量总和
gdb) p sdd::sum --查看函数sdd的局部变量总和
观察点(WatchPoint)
在变量、写或变化时中断,这类方式常用来定位错误。
观看变量变量发生变化时中断
rwatch变量变量被读时中断
awatch变量变量值被读或被写时中断
使用步骤如下


  • 使用break在要观察的变量处设置断电;
  • 使用run执行,直到断点;
  • 使用watch设置观察点;
  • 使用继续观察设置的观察点是否有变化。


调试方式运行程序
(1)调试启动无参程序
gdb 可执行文件


gdb thread


(2)调试启动带参程序
gdb 可执行文件
set args 参数
run运行


gdb thread
gdb)set args a b c
gdb)r


注:show args 命令可以查看设置好的运行参数。


(3)在线调试程序
gdb attach 进程ID


注:如果程序已经在运行,需要使用gdb attach 进程ID,在线调试,不会再开进程。如果程序还没运行,使用gdb 可执行文件,则会启动进程。


三、gdb应用例子
(1)线程卡死问题
在Linux上,执行有多线程的程序时,可能因为各种原因而导致卡死,比如死锁现象,很难快速定位问题,借助gdb attach在线调试即可排查程序卡死问题(死锁问题)。
多线程调试命令:


bt:查看函数调用栈的所有信息,当程序执行异常时,可通过此命令查看程序的调用过程;
info threads:显示当前进程中的线程;
thread id:切换到具体的线程id,一般切换到具体的线程后再执行bt等操作。
排查步骤:
1、info threads 查看有哪些线程
2、thread id 切换到可疑线程
3、 bt 查看函数调用栈的所有信息,即可定位死锁问题。


gdb测试例程:


#include
#include
#include
#include
#include
#include
int sum = 9;
typedef struct student
{
        char name[24];
        int age;
        int six;
}stu;
pthread_mutex_t info_mutex;
void *myroutinue(void *arg)
{
        //stu student;
        //student = *(stu *)arg;
        stu *student = arg;
        int a;
        printf("pthread_self( ) = %xn",pthread_self( ));
        prctl(PR_SET_NAME,"Thread_snmp",0,0,0);
        pthread_detach(pthread_self( ));
        while(1)
        {
                int mun=0;
                pthread_mutex_lock(&info_mutex);
                mun++;
                //pthread_mutex_unlock(&info_mutex);
                printf("student.name = %sn",student->name);
                printf("student.age = %dn",student->age);
                printf("student.six = %dn",student->six);
                printf("mun1 = %dn",mun);
               
                sleep(2);       
        }
}


int sdd()
{
        int a=4;
        a+=5;
        int sum =8;
        return a;
}


int main(char argc,char **argv)
{
       
        int mun=0,i,n;
        for(n=0;n         {
                printf("argv[%d] = %sn",n,argv[n]);
        }
        int sum = 0;
        pthread_t tid;
        stu *student;
        int va = 6;
        int stud[12] = {8,8,3,4,5,6,7,3};
        stu stu1;
        stu1.age = 17;
        stu1.six = 165;
        pthread_mutex_init(&info_mutex, NULL);
        void *p = (void*)malloc(sizeof(stu));
        student = (stu *)p;
        strcpy(student->name,"chenjiaguang");
        student->age = 16;
        student->six = 43;
        pthread_create(&tid , NULL , myroutinue , p);
        printf("tid = %x",tid);
        pthread_mutex_lock(&info_mutex);
        mun++;
        pthread_mutex_unlock(&info_mutex);
        sdd();
        for(i=0;i<10;i++)
        {
                sum++;
        }
        while(1)
        {
                mun++;
                printf("mun = %dn",mun);
                sleep(2);
        }
        return 0;
}


测试效果:
运行gdb attach ip


(gdb) info threads
  Id   Target Id         Frame
* 1    Thread 0x7f7231ac4700 (LWP 104014) "thread" 0x00007f72313a030d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
  2    Thread 0x7f72312d3700 (LWP 104015) "Thread_snmp" __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) thread  2
[Switching to thread 2 (Thread 0x7f72312d3700 (LWP 104015))]
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
135     ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: 没有那个文件或目录.
(gdb) bt
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x00007f72316a7dbd in __GI___pthread_mutex_lock (mutex=0x6020c0 ) at ../nptl/pthread_mutex_lock.c:80
#2  0x0000000000400923 in myroutinue (arg=0x12e1420) at thread.c:27
#3  0x00007f72316a56ba in start_thread (arg=0x7f72312d3700) at pthread_create.c:333
#4  0x00007f72313db41d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109


从上面可以看出,是在pthread_mutex_lock死锁,只有锁,没有解锁,从而导致死锁。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分