多进程 多线程调试方法 GDB调试 .
使用GDB调试多线程实例详解
使⽤GDB调试多线程实例详解
先写⼀段多线程程序。
makefile
加上 -g参数⽣成可调式信息,可以进⾏调试。
pthread不是Linux下的默认的库,也就是在链接的时候,⽆法找到phread库中哥函数的⼊⼝地址,于是链接会失败。
在gcc编译的时候,附加要加 -lpthread参数即可解决。
gdb test 进⼊调试
需要调试的地⽅打下断点,run运⾏到断点处。
r 运⾏到断点处,info thread可以查看被调试的线程。
thread apply all bt 让所有线程打印堆栈信息
set scheduler-locking off|on|step
在使⽤step或continue命令调试当前被调试线程的时候,其他线程也是同时执⾏的,如果我们只想要被调试的线程执⾏,⽽其他线程停⽌等待,那就要锁定要调试的线程,只让它运⾏。
off:不锁定任何线程,所有线程都执⾏。
on:只有当前被调试的线程会执⾏。
step:阻⽌其他线程在当前线程单步调试的时候抢占当前线程。
只有当next、continue、util以及finish的时候,其他线程才会获得重新运⾏的。
show scheduler-locking:
这条命令是为了查看当前锁定线程的模式。
感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!。
GDB调试简易教程
GDB调试简易教程GDB(GNU调试器)是一个开源的调试工具,它用于调试C、C++和其他编程语言的程序。
它允许程序员在执行过程中观察程序的内部状态,帮助找到程序中的错误并进行修复。
下面是一个简易的GDB调试教程,以帮助你入门并学会使用它。
安装GDB首先,你需要在你的系统上安装GDB。
对于大多数Linux发行版,你可以通过在终端中运行以下命令来安装它:```sudo apt-get install gdb```编译程序在使用GDB之前,你需要编译你的程序,并在编译时使用-g选项,以便生成调试信息。
例如,对于C语言程序,你可以使用以下命令来编译:```gcc -g program.c -o program```这将生成一个可执行文件program,并在目录中生成调试信息。
启动GDB在终端中使用以下命令来启动GDB并调试你的程序:```gdb program```这将启动GDB,并且你将看到GDB的命令提示符。
设置断点断点是你在程序中指定的一个位置,当程序执行到该位置时会暂停。
你可以使用断点来观察程序在这一点的状态。
要设置断点,请在GDB的命令提示符下输入以下命令:```break line_number```line_number是你想要设置断点的源代码行号。
例如,要在程序的第10行设置断点,你可以使用以下命令:```break 10```或者你也可以使用函数名作为参数来设置断点:```break function_name```开始调试一旦设置好断点,你可以开始调试你的程序了。
要开始执行程序,请输入以下命令:```run```程序将开始运行直到第一个断点处。
此时,程序会停下来并且GDB会等待你的进一步命令。
观察变量在程序运行到断点处时,你可以使用以下命令来观察程序内部的变量值:```print variable_name```variable_name是你想要观察的变量的名称。
例如,要查看变量x的值,你可以使用以下命令:```print x```你还可以通过使用其他GDB命令来观察更多的变量信息,例如观察数组、结构体等。
gdb 调试方法
gdb 调试方法
GDB 是一款功能强大的调试工具,它可以用于调试C、C++、Python 等编程语言的代码。
下面是一些常用的 GDB 调试方法:
1. 设置断点:可以使用`break` 命令在代码的某一行设置断点,例如 `break main.c:10` 表示在 main.c 文件的第 10 行设置断点。
2. 运行程序:使用 `run` 命令来运行程序,例如 `run arg1 arg2` 表示运行程序并传入参数 arg1 和 arg2。
3. 单步执行:可以使用 `step` 命令以单步方式执行代码,进入
函数时会逐行执行其中的代码。
4. 查看变量值:使用 `print` 命令可以查看变量的值,例如
`print x` 表示打印变量 x 的值。
5. 修改变量值:使用 `set` 命令可以修改变量的值,例如 `set x = 10` 表示将变量 x 的值设置为 10。
6. 查看函数调用栈:使用 `backtrace` 或 `bt` 命令可以打印函数调用栈。
7. 继续执行:使用 `continue` 命令可以继续执行程序直到下一
个断点或程序结束。
8. 异常处理:可以使用 `catch` 命令来设置异常断点,例如
`catch throw` 表示在抛出异常时停止程序执行。
9. 调试多线程程序:GDB 支持调试多线程程序,可以使用
`thread` 命令来操作线程,例如 `thread 2` 表示切换到线程 2 进行调试。
以上是一些常用的 GDB 调试方法,通过掌握这些方法可以更好地使用 GDB 进行程序的调试。
同时,GDB 还提供了更多强大的调试功能,可以根据具体需求来进一步探索和学习。
gdb调试技巧
gdb调试技巧GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。
它是一种强大的命令行调试工具。
一般来说,调试器的功能:能够运行程序,设置所有能影响程序运行的参数;能够让程序在指定条件下停止运行;能够在程序停止时检查所有参数的情况;能够根据指定条件改变程序的运行。
gdb调试源代码流程:1)进入GDB #gdb test只需输入GDB和要调试的可执行文件即可,在GDB的启动画面中指出了GDB的版本号、遵循的许可等信息,接下来就进入了由"(gdb)"开头的命令行界面了;2)查看文件(gdb) l在GDB中键入"l"(list)就可以查看程序的源码了,GDB列出的源代码中明确地给出了对应的行号,方便代码的定位;3)设置断点(gdb) b 6只需在"b"(break)后加入对应的行号即可,在GDB中利用行号设置断点是指代码运行到对应行之前暂停;设置断点可以使程序执行到某个位置时暂停,程序员在该位置处可以方便地查看变量的值、堆栈情况等;一般情况下,源代码中大家行号与用户书写程序的行号是一致的,但有时由于用户的某些编译选项会导致行号不一致的情况,因此,一定要查看在GDB中的行号;4)查看断点处情况(gdb) info b可以键入"info b"来查看断点处情况,可以设置多个断点;5)运行代码(gdb) rGDB默认从首行开始运行代码,键入"r"(run)即可;程序运行到断点处停止。
6)看变量值(gdb) p n在程序暂停之后,程序员可以查看断点处的相关变量值,在GDB 中只需键入"p 变量名"(print)即可;GDB在显示变量值时都会在对应值之前加上"$N"标记,它是当前变量值的引用标记,以后若想再次引用此变量,就可以直接写作"$N",而无需写冗长的变量名;7)观察变量(gdb) watch n在某一循环处,往往希望能够观察一个变量的变化情况,这时就可以键入命令"watch"来观察变量的变化情况,GDB在"n"设置了观察点;8)单步运行(gdb) n单步运行是指一次只运行一条语句,这样可以方便查看程序运行的结果,在此处只需键入"n"(next)即可;随着程序的单步运行,当变量n的值发生变化时,GDB就会自动显示出n的变化情况。
gdb调试方法
gdb调试方法
GDB是一款功能强大的调试器,可以帮助开发人员快速定位和解决程序中的错误。
以下是GDB调试的一些常用方法:
1. 启动程序:在终端中输入gdb programname,其中programname 是要调试的程序的名称。
2. 设置断点:使用break命令设置断点,例如break functionname,在函数functionname处设置断点。
3. 运行程序:使用run命令运行程序,程序会在设置的断点处停止执行。
4. 单步执行:使用单步命令step或next执行程序,step命令会进入函数内部,next命令则不会。
5. 查看变量值:使用print命令查看变量的值,例如print varname。
6. 修改变量值:使用set命令修改变量的值,例如set varname=newvalue。
7. 查看函数调用栈:使用backtrace命令查看函数调用栈,可以确定程序执行到哪个函数。
8. 调试多线程程序:可以使用thread命令查看和切换线程,使用info threads命令查看线程的状态。
9. 导出调试信息:使用gdb -batch -ex 'info functions' programname > function_list.txt命令将程序的函数列表导出到文件中。
以上是GDB调试的一些常用方法,熟练掌握这些方法可以帮助开发人员快速排除程序中的错误。
gdb 多线程调试原理
GDB(GNU Debugger)是一个功能强大的调试器,它能够解决并发程序调试的难题。
在多线程调试中,其主要任务是准确及时地捕捉被调试程序线程状态的变化的事件,并且GDB针对捕捉到的事件做出相应的操作。
GDB的工作原理可以概括为以下几个步骤:首先,在编译程序时,通常会生成调试信息,包括源代码和符号表。
符号表记录了程序中的函数、变量和类型信息。
然后,GDB会将这些信息与被调试的程序进行匹配,从而确定程序的状态。
最后,GDB会根据用户的命令,控制程序的执行,例如设置断点、单步执行等。
在Linux平台,GDB实现多线程调试主要依赖三个文件:thread.c、infrun.c和symtab.c。
其中,thread.c文件的任务非常简单,就是多线程调试命令子集的实现,比如"info threads"。
当用户在gdb命令行敲入多线程调试命令子集中的命令时,就会调用thread.c中对应的函数。
而GDB对于线程列表的维护工作主要在infrun.c和symtab.c两个文件中实现。
此外,GDB还支持查看程序运行时的内存内容和寄存器状态。
在调试多进程程序时,GDB 默认只追踪父进程,但可以通过命令设置,实现只追踪父进程或子进程,或者同时调试父进程和子进程。
这为调试并发程序或多线程应用程序提供了极大的便利。
gdb调试案例
gdb调试案例以GDB调试案例为题,我将列举以下10个案例,每个案例将描述GDB的使用场景、调试目标、具体步骤和调试结果,以帮助读者更好地理解和掌握GDB调试工具。
案例一:查看程序崩溃的原因场景:当程序崩溃时,我们需要找出崩溃的原因,以便修复程序中的bug。
目标:在程序崩溃时,使用GDB查看崩溃的原因。
步骤:1. 使用-g选项编译程序,以包含调试信息。
2. 执行gdb命令,加载可执行文件。
3. 在GDB中运行程序,当程序崩溃时,GDB会自动停止程序的执行。
4. 使用backtrace命令查看调用栈,找出导致崩溃的函数和行号。
5. 使用print命令查看变量的值,以便进一步分析崩溃原因。
结果:通过查看调用栈和变量的值,我们可以定位到导致程序崩溃的具体代码行,并进行修复。
案例二:设置断点并跟踪程序执行场景:当程序运行过程中出现问题,我们需要跟踪程序的执行过程,以便找出问题所在。
目标:使用GDB设置断点并跟踪程序执行。
步骤:1. 使用-g选项编译程序,以包含调试信息。
2. 执行gdb命令,加载可执行文件。
3. 使用break命令设置断点,可以选择在特定函数或行号上设置断点。
4. 运行程序,GDB会在断点处停止程序的执行。
5. 使用step命令逐行执行程序,并查看变量的值。
6. 使用continue命令继续程序的执行,直到下一个断点或程序结束。
结果:通过设置断点和逐行执行程序,我们可以跟踪程序的执行过程,找出问题所在。
案例三:查看内存信息场景:当程序出现内存相关的问题时,我们需要查看程序的内存使用情况,以便分析问题所在。
目标:使用GDB查看程序的内存信息。
步骤:1. 使用-g选项编译程序,以包含调试信息。
2. 执行gdb命令,加载可执行文件。
3. 运行程序,GDB会自动停止程序的执行。
4. 使用info breakpoints命令查看已设置的断点。
5. 使用info registers命令查看寄存器的值。
GDB调试技巧与实战
GDB调试技巧与实战GDB(GNU调试器)是一种强大的调试工具,广泛用于C/C++程序的调试。
它具有许多有用的功能和命令,可以帮助我们快速定位和解决程序中的bug。
在本文中,我将介绍一些GDB调试技巧和实例,帮助您更好地使用GDB进行调试工作。
1. 启动程序:要使用GDB调试程序,我们需要在启动GDB时将程序作为参数传递给它。
例如,要调试名为myprogram的可执行文件,可以使用以下命令启动GDB:```gdb myprogram```2. 设置断点:当我们想要在特定位置暂停程序执行时,可以在该位置设置断点。
使用GDB的"break"命令可以实现。
例如,要在程序的main 函数处设置断点,可以使用以下命令:```break main```我们还可以使用行号来设置断点,例如:```break file.c:10```3. 运行程序:设置了断点后,我们可以使用GDB的"run"命令来运行程序。
程序会在达到断点时暂停执行。
例如:```run```如果程序需要命令行参数,我们可以在run命令后面添加参数。
例如:```run arg1 arg2```4. 单步调试:一旦程序暂停在断点处,可以使用GDB的"step"命令逐行执行程序。
这对于理解程序的执行流程非常有用。
例如:```step```如果希望在函数内部逐行执行,可以使用"next"命令。
它会跳过函数内部的细节,直接进入下一行。
例如:```next```5. 打印变量:在调试程序时,我们经常需要查看变量的值。
GDB的"print"命令可以用于打印变量的值。
例如,要打印整型变量x的值,可以使用以下命令:```print x```我们还可以使用GDB的表达式语言来计算表达式的值。
例如,要打印变量x和y的和,可以使用以下命令:```print x + y```6. 查看堆栈:GDB可以帮助我们查看程序的堆栈跟踪信息。
linux gdb调试指令 linux下gdb常用的调试指令
u 内存单位(b: 1 字节; h: 2 字节; w: 4 字节; g: 8 字节)
set print address on
set vairiable a = 100 可以修改变量的值
打开地址输出,当程序显示函数信息时,GDB 会显出函数的参数地址。
commands 指定到了特定断点后is buf 显示变量的类型
set print object <on/off>
dump memory 输出文件名 内存起始地址 内存终止地址
在 C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB
restore 文件名 binary 起始位置
会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB 就
delete 删除断点 d 3 删除指定的断点 condition 修改条件 condition 4 a == 90 info 查看信息 info threads 查看线程信息 info breakpoints 查看断点信息 info locals 显示局部变量 info args 显示函数变量 info registers 显示寄存器数据 thread 2 切换线程 where 查看调用堆栈(bt 或者 info s)
set print elements 0 默认这里设置是 200,设置为 0 表示没有限
x/nfu 0×300098 显示指定地址的内存数据
制
n 显示内存单位,长度
还有其它一些 set 命令可以试试:
f 格式(除了 print 格式外,还有 字符串 s 和 汇编 i)
set print address
break 设置断点 b main 设置函数断点 b 9 设置指定行断点 b 将下一行设置为断点 b test if a == 10 设置条件断点
使用 GDB 调试多进程程序的子程序
GDB 是 linux 系统上常用的 c/c++ 调试工具,功能十分强大。
对于较为复杂的系统,比如多进程系统,如何使用 GDB 调试呢?考虑下面这个三进程系统:进程Proc2 是 Proc1 的子进程,Proc3 又是 Proc2 的子进程。
如何使用 GDB 调试 proc2 或者 proc3 呢?实际上,GDB 没有对多进程程序调试提供直接支持。
例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。
如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP 信号并终止。
那么该如何调试子进程呢?其实我们可以利用GDB的特点或者其他一些辅助手段来达到目的。
此外,GDB 也在较新内核上加入一些多进程调试支持。
接下来我们详细介绍几种方法,分别是 follow-fork-mode 方法,attach 子进程方法和 GDB wrapper 方法。
follow-fork-mode在2.5.60版Linux内核及以后,GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。
follow-fork-mode的用法为:set follow-fork-mode [parent|child]∙parent: fork之后继续调试父进程,子进程不受影响。
∙child: fork之后调试子进程,父进程不受影响。
因此如果需要调试子进程,在启动gdb后:(gdb) set follow-fork-mode child并在子进程代码设置断点。
此外还有detach-on-fork参数,指示GDB在fork之后是否断开(detach)某个进程的调试,或者都交由GDB控制:set detach-on-fork [on|off]∙on: 断开调试follow-fork-mode指定的进程。
∙off: gdb将控制父进程和子进程。
GDB高级使用技巧
GDB高级使用技巧GDB是GNU调试器的缩写,是一款功能强大的调试工具,用于帮助开发人员诊断和调试程序。
在日常开发中,我们通常只使用GDB的基本命令来进行程序调试。
然而,GDB还有许多高级使用技巧,可以提高效率和准确性。
下面是一些GDB的高级使用技巧。
1.处理多线程调试- 在多线程程序中进行调试时,可以使用GDB的“set scheduler-locking off”命令来禁止线程调度,这样可以确保只有被调试的线程在运行。
此外,还可以使用“set follow-fork-mode child”命令来跟踪子进程。
2.追踪内存错误- GDB的“run”命令可以在调试会话中重新运行程序。
通过使用“set environment”命令,可以设置运行时环境变量。
对于存在内存错误的程序,可以使用GDB的“run”命令多次调试同一个输入,以便更好地定位错误。
3.使用条件断点- 条件断点可以在特定条件下暂停程序执行。
使用GDB的“break”命令的同时指定条件,即断点只在满足条件时触发。
例如,“break foo if x > 10”将在变量x的值大于10时触发断点。
4.追踪系统调用- 追踪系统调用可以帮助我们在程序运行时分析操作系统的行为。
GDB提供了一些命令来追踪系统调用,如“catch syscall”和“catch syscall name”(name是系统调用的名称)。
5.追踪函数调用- GDB可以追踪程序中的函数调用。
通过使用“breakfunction_name”命令设置断点,即可在函数调用时暂停程序执行。
使用“finish”命令能够从当前函数中返回,然后再次触发断点。
6.反汇编代码- GDB可以将机器码反汇编为汇编代码,以便我们更好地理解程序的运行机制。
使用GDB的“disassemble”命令可以在指定地址范围内显示反汇编代码。
7.定义自定义命令8. 使用Python扩展- GDB提供了Python接口,允许我们使用Python脚本进行更复杂的调试操作。
使用GDB调试多进程程序的子程序
使用GDB调试多进程程序的子程序GDB是一种功能强大的调试器,可用于调试各种类型的程序,包括多进程程序。
在这篇文章中,我们将探讨如何使用GDB调试多进程程序的子程序。
在多进程程序中,通常会有一个主进程(也称为父进程)和多个子进程。
这些子进程可能是通过调用 fork( 系统调用创建的,也可能是通过调用 exec( 系统调用生成的。
在调试多进程程序时,我们希望能够独立地调试每个子进程的代码,以便查找和修复潜在的问题。
以下是一个示例多进程程序的代码:```c#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>int maipid_t pid;pid = fork(;if (pid == 0)//子进程代码printf("This is the child process.\n");int i;for (i = 0; i < 10; i++)printf("Child process: %d\n", i);sleep(1);}} else//父进程代码printf("This is the parent process.\n"); int i;for (i = 0; i < 5; i++)printf("Parent process: %d\n", i);sleep(1);}wait(NULL);}return 0;```让我们使用GDB来调试这个程序。
首先,我们需要在编译时使用 -g 选项来生成调试信息。
在 Linux 系统上,我们可以使用以下命令编译程序:```gcc -g -o program program.c```接下来,我们可以在GDB中打开程序:```gdb program```在GDB命令提示符下,我们可以设置断点来停止程序的执行并查看其中的变量和状态。
GDB调试技巧
1、GDB 启动一般来说GDB主要调试的是C/C++的程序。
要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。
使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。
如:> cc -g hello.c -o hello> g++ -g hello.cpp -o hello如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。
当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。
启动GDB的方法有以下几种:1、gdb <program>program也就是你的执行文件,一般在当然目录下。
2、gdb <program> core用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
3、gdb <program> <PID>如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。
gdb会自动attach上去,并调试他。
program应该在PATH环境变量中搜索得到。
GDB启动时,可以加上一些GDB的启动开关,详细的开关可以用gdb -help查看。
我在下面只例举一些比较常用的参数:-symbols <file>-s <file>从指定文件中读取符号表。
-se file从指定文件中读取符号表信息,并把他用在可执行文件中。
-core <file>-c <file>调试时core dump的core文件。
-directory <directory>-d <directory>加入一个源文件的搜索路径。
默认搜索路径是环境变量中PATH所定义的路径。
2、GDB的命令概貌启动gdb后,就你被带入gdb的调试环境中,就可以使用gdb的命令开始调试程序了,gdb的命令可以使用help命令来查看,如下所示:/home/hchen> gdbGNU gdb 5.1.1Copyright 2002 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 "i386-suse-linux".(gdb) helpList of classes of commands:aliases -- Aliases of other commandsbreakpoints -- Making program stop at certain pointsdata -- Examining datafiles -- Specifying and examining filesinternals -- Maintenance commandsobscure -- Obscure featuresrunning -- Running the programstack -- Examining the stackstatus -- Status inquiriessupport -- Support facilitiestracepoints -- Tracing of program execution without stopping the programuser-defined -- User-defined commandsType "help" followed by a class name for a list of commands in that class.Type "help" followed by command name for full documentation.Command name abbreviations are allowed if unambiguous.(gdb)gdb的命令很多,gdb把之分成许多个种类。
使用gdb调试多线程程序
使用gdb调试多线程程序2009-07-18 11:13gdb对于多线程程序的调试有如下的支持:∙线程产生通知:在产生新的线程时, gdb会给出提示信息(gdb) rStarting program: /root/thread[New Thread 1073951360 (LWP 12900)][New Thread 1082342592 (LWP 12907)]---以下三个为新产生的线程[New Thread 1090731072 (LWP 12908)][New Thread 1099119552 (LWP 12909)]∙查看线程:使用info threads可以查看运行的线程。
(gdb) info threads4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()*1 Thread 1073951360 (LWP 12931) main (argc=1, argv=0xbfffda04) at thread.c:21(gdb)注意,行首的蓝色文字为gdb分配的线程号,对线程进行切换时,使用该该号码,而不是上文标出的绿色数字。
另外,行首的红色星号标识了当前活动的线程∙切换线程:使用thread THREADNUMBER 进行切换,THREADNUMBER 为上文提到的线程号。
下例显示将活动线程从 1 切换至 4。
(gdb) info threads4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()* 1 Thread 1073951360 (LWP 12931) main (argc=1, argv=0xbfffda04) at thread.c:21(gdb) thread 4[Switching to thread 4 (Thread 1099119552 (LWP 12940))]#0 0xffffe002 in ?? ()(gdb) info threads* 4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()1 Thread 1073951360 (LWP 12931) main (argc=1, argv=0xbfffda04) atthread.c:21(gdb)以上即为使用gdb提供的对多线程进行调试的一些基本命令。
GDB高级使用技巧
GDB高级使用技巧GDB(GNU调试器)是一款用于调试程序的强大工具,可以帮助开发人员在代码运行时跟踪和排查错误。
虽然它提供了一些基本的调试功能,如断点设置和变量查看,但它也提供了一些高级功能和技巧,可以帮助开发人员更高效地进行调试。
以下是一些GDB的高级使用技巧。
1. 多线程调试:GDB支持调试多线程程序。
可以使用"setscheduler-locking on"命令来将GDB锁定在一个特定的线程上,以便单步调试该线程。
可以使用"set scheduler-locking off"命令来解锁GDB,并让调度器选择下一个线程进行执行。
2. 远程调试:GDB支持与远程目标进行调试。
可以使用"target remote <IP>:<port>"命令连接到远程目标,并使用GDB对其进行调试。
这对于在嵌入式系统等设备中调试非常有用。
3. 自动生成调试脚本:GDB可以自动生成执行一系列调试命令的脚本。
可以使用"save breakpoints <filename>"命令将当前所有断点保存到一个文件中,然后可以使用"source <filename>"命令加载这个文件,从而自动设置断点。
4.条件断点:GDB支持在满足一定条件时才触发断点。
可以使用"break <line> if <condition>"命令设置一个条件断点,其中"line"是代码行号,"condition"是条件表达式。
当程序执行到该行时,只有当条件为真时才触发断点。
5.硬件断点:GDB支持使用硬件断点进行调试。
硬件断点可以设置在特定的内存地址上,而不是代码行上。
可以使用"break *0xaddress"命令在特定的地址上设置一个硬件断点。
gdb 多线程调试案例
gdb 多线程调试案例主题:gdb 多线程调试案例要求:介绍一个使用 gdb 进行多线程调试的案例,包括问题描述、调试过程和解决方案。
案例:问题描述:在一个多线程程序中,某个线程出现了段错误,但是无法确定是哪个线程导致的,需要使用 gdb 进行多线程调试。
调试过程:1. 编译程序时需要加上 -g 选项,以便在调试时能够获取到符号表信息。
2. 运行程序,使用 ps 命令查看程序的进程 ID。
3. 使用 gdb attach 命令附加到程序进程中,例如:gdb attach 1234。
4. 使用 info threads 命令查看程序中的所有线程,找到出现问题的线程 ID。
5. 使用 thread 命令切换到出现问题的线程上。
6. 使用 backtrace 命令查看线程的调用栈,找到导致段错误的函数。
7. 使用 break 命令在出现问题的函数上设置断点。
8. 继续运行程序,直到程序停在断点处。
9. 使用 info locals 命令查看当前函数的局部变量信息,找到导致段错误的变量。
10. 修改代码,修复问题。
解决方案:在调试过程中,需要注意以下几点:1. 确保程序编译时加上了 -g 选项,以便在调试时能够获取到符号表信息。
2. 使用 gdb attach 命令附加到程序进程中,而不是直接运行程序。
3. 使用 info threads 命令查看程序中的所有线程,找到出现问题的线程 ID。
4. 使用 thread 命令切换到出现问题的线程上,以便查看该线程的调用栈和局部变量信息。
5. 在出现问题的函数上设置断点,以便在程序运行到该函数时停下来进行调试。
6. 使用 info locals 命令查看当前函数的局部变量信息,找到导致问题的变量。
7. 修改代码,修复问题。
总结:使用 gdb 进行多线程调试需要掌握一定的技巧和经验,但是通过合理的调试方法和工具,可以快速定位和解决问题。
在实际开发中,需要注意编译选项、调试命令和调试过程中的注意事项,以提高调试效率和准确性。
linux,gdb调试基本指令_linux gdb调试指令
(5).t 按二进制格式显示变量。
p str@str_len //打印字符串
(6).a 按十六进制格式显示变量。
第3页共7页
(7).i 指令地址格式
本文格式为 Word 版,下载可任意编辑,页眉双击删除即可。
(1)线程锁
(8).c 按字符格式显示变量。
show scheduler-locking
(9).f 按浮点数格式显示变量。
第2页共7页
本文格式为 Word 版,下载可任意编辑,页眉双击删除即可。
(1).p &examined_rows,得到地址
info locals //打印出当前函数中所有局部变量及其值。
(2).watch *(ha_rows *) 0x7ffec8005e28,则可以观察这个变量的变
info args //打印出当前函数的参数名及其值。
next //单步执行
CFLAGS 指定-g 选项,否则调试时没有符号信息。
return //函数未执行完,忽略未执行的语句,返回。
gdb program //最常用的用 gdb 启动程序,开始调试的方式
finish //函数执行完毕返回。
gdb program core //用 gdb 查看 core dump 文件,跟踪程序 core 的
本文格式为 Word 版,下载可任意编辑,页眉双击删除即可。
linux,gdb 调试基本指令_linux gdb 调试指令
比如:打印$pid 进程所有线程的堆栈并退出。 gdb -ex "set pagination 0" -ex "thread apply all
近年来,随着嵌入式技术飞速发展,嵌入式产品随处可见,Linux bt" -batch -p $pid
利用GDB进行多线程调试-CSDN博客
利用GDB 进行多线程调试-CSDN 博客一、多线程调试多线程调试重要就是下面几个命令:info thread 查看当前进程的线程。
thread <ID> 切换调试的线程为指定ID 的线程。
break file.c:100 thread all 在file.c 文件第100行处为所有经过这里的线程设置断点。
set scheduler-locking off|on|step ,这个是问得最多的。
在使用step 或者continue 命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next 过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue 的行为)以外,只有当前线程会执行。
二、调试宏这个问题超多。
在GDB 下,我们无法print 宏定义,因为宏是预编译的。
但是我们还是有办法来调试宏,这个需要GCC 的配合。
在GCC 编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。
另外,你可以使用下述的GDB 的宏调试命令 来查看相关的宏。
info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
macro – 你可以查看宏展开的样子。
三、源文件这个问题问的也是很多的,太多的朋友都说找不到源文件。
在这里我想提醒大家做下面的检查:编译程序员是否加上了-g 参数以包含debug 信息。
路径是否设置正确了。
使用GDB 的directory 命令来设置源文件的目录。
下面给一个调试/bin/ls 的示例(ubuntu 下)1 2 3 $ apt-get sourcecoreutils$ sudoapt-get installcoreutils-dbgsym$ gdb /bin/ls4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 GNU gdb (GDB) 7.1-ubuntu(gdb) list main1192 ls.c: No such fileor directory.inls.c(gdb) directory ~/src/coreutils-7.4/src/Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd(gdb) list main1192 }1193 }11941195 int1196 main (int argc, char **argv)1197 {1198 int i;1199 struct pending *thispend;1200 int n_files;1201四、条件断点条件断点是语法是:break [where] if [condition],这种断点真是非常管用。
使用调试工具进行线程调试
使用调试工具进行线程调试近年来,随着软件开发的快速发展,多线程编程成为了一种常见的开发方式。
在多线程程序中,线程调试是开发人员不可或缺的工作之一。
线程调试的目的是为了解决并发执行中可能发生的各种问题,如死锁、竞态条件等。
为了提高线程调试的效率和准确性,开发人员可以借助各种调试工具来帮助他们进行线程调试。
一、调试工具的选择在选择调试工具时,开发人员应根据自己的需求和编程语言来做出合适的选择。
常见的调试工具有GDB、Visual Studio Debugger、Eclipse Debugger等。
这些工具提供了丰富的调试功能,如设置断点、查看变量的值、单步执行等。
二、断点设置断点是调试中常用的功能之一。
通过在代码中设置断点,开发人员可以在程序执行到断点处停下来,以便观察程序的执行情况。
在调试多线程程序时,设置断点可以使开发人员更容易定位到具体的线程,从而准确地进行调试。
三、线程查看和跟踪调试工具可以提供线程查看和跟踪的功能,帮助开发人员了解线程的运行状态。
通过这些功能,开发人员可以查看当前活动的线程列表,查看每个线程的堆栈信息,并跟踪正在执行的线程。
这对于发现线程并发问题以及定位线程错误非常有帮助。
四、变量监视在调试过程中,开发人员经常需要观察程序中的变量的值。
调试工具提供了变量监视的功能,可以在调试过程中实时监视和查看变量的值。
这可以帮助开发人员追踪变量的状态,从而更容易找出线程问题的根源。
五、调试输出调试输出是调试中常用的方法之一,用于输出程序的状态信息和调试信息。
开发人员可以在代码中插入输出语句,通过调试工具来查看输出的内容。
这对于调试多线程程序尤为重要,因为开发人员可以通过分析输出信息来判断线程的执行情况和可能存在的问题。
六、死锁分析死锁是多线程程序容易遇到的一个问题。
当多个线程因为争夺资源而无法继续执行时,就会发生死锁。
调试工具可以提供死锁分析的功能,帮助开发人员找出死锁的原因和产生死锁的线程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
[root@tivf09 root]# ps -ef|grep -i vnc
root 19609 1 0 Jun05 ?
00:08:46 Xvnc :1 -desktop
tivf09:1 (root)
-httpd /usr/share/vnc/classes -auth /root/.Xauthority
-geometry 1024x768
-depth 16 -rfbwait 30000 -rfbauth /root/.vnc/passwd -rfbport
5901 -pn
root 19627 1 0 Jun05 ?
00:00:00 vncconfig
-iconic
root 12714 10599 0 01:23 pts/0 00:00:00 grep -i vnc
Attach 子进程
众所周知,GDB 有附着(attach)到正在运行的进程的功能,即 attach <pid>命令。因此我们可以利用该命令 attach 到子进程然后进行调试。
例如我们要调试某个进程 RIM_Oracle_Agent.9i,首先得到该进程的 pid
[root@tivf09 tianq]# ps -ef|grep RIM_Oracle_Agent.9i
3、GDB wrapper 方法:专用于 fork+exec 模式,不用添加额外代码, 但需要 X 环境支持(xterm/VNC)这种方式没有使用过,一般对于企业 开发的话是不是很多都没有 x 环境支持的吧(猜测:))
follow-fork-mode 方式比较简单,通过 set follow-fork-mode child | parent 来觉得跟踪 child 还是 parent,然后可以设置断点跟踪了
set follow-fork-mode [程,子进程不受影响。 child: fork 之后调试子进程,父进程不受影响。
因此如果需要调试子进程,在启动 gdb 后:
(gdb) set follow-fork-mode child
Proc2 是 Proc1 的子进程,Proc3 又是 Proc2 的子进程。如何使用 GDB 调试 proc2 或者 proc3 呢? 实际上,GDB 没有对多进程程序调试提供直接支持。例如,使用 GDB 调试某个进程,如果该进程 fork 了子进程,GDB 会继续调试该进程, 子进程会不受干扰地运行下去。如果你事先在子进程代码里设定了断 点,子进程会收到 SIGTRAP 信号并终止。那么该如何调试子进程呢? 其实我们可以利用 GDB 的特点或者其他一些辅助手段来达到目的。此 外,GDB 也在较新内核上加入一些多进程调试支持。
还是上面那个例子,RIM_Oracle_prog fork 出子进程后将紧接着执行 RIM_Oracle_Agent.9i 的二进制代码文件。我们将该文件重命名为 RIM_Oracle_Agent.9i.binary,并新建一个名为 RIM_Oracle_Agent.9i 的 shell 脚本文件,其内容如下:
关于 gdb 调试多进程很早之前就看过,但一直没有总结很深入的学习, 今天又碰到这个问题了,记录下
记得 kk 跟我说过,在开发程序的时候尽量少调试,尽量少使用 gdb 等 调试工具,尽量多的使用 log 等方式来定位错误,这样会大大减少调试 所需的时间和精力,同时也能快速的定位问题。当然,利用 gdb 调试还 是有很多的优势的,比如对于我这个菜鸟来说,可以好好学习下强大的 gdb~ 关于 gdb 的基本调试,基本已经掌握了,经常会使用的一些命令有: s----step n----next c-----continue p----print bt---backtrace b----break 等等
今天查找多进程调试的时候突然注意到 stop 命令,之前一直没有留意, 发现这个命令可以在多进程调试中起到作用
下面描述下多进程的调试
关于 gdb 调试多进程,很经典的一篇文章是 IBM developerworks 上面 的一篇: /developerworks/cn/linux/l-cn-gdbmp/index.html 详细内容见下面描述。
并在子进程代码设置断点。
此外还有 detach-on-fork 参数,指示 GDB 在 fork 之后是否断开(detach) 某个进程的调试,或者都交由 GDB 控制:
set detach-on-fork [on|off]
on: 断开调试 follow-fork-mode 指定的进程。 off: gdb 将控制父进程和子进程。follow-fork-mode 指定的进程
[root@tivf09 root]# pstree -H 6722
通过 pstree 察看进程
启动 GDB,attach 到该进程 用 GDB 连接进程
现在就可以调试了。一个新的问题是,子进程一直在运行,attach 上去 后都不知道运行到哪里了。有没有办法解决呢?
一个办法是,在要调试的子进程初始代码中,比如 main 函数开始处, 加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach 到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继 续执行下去。
VNC viewer:输入服务器
输入密码: VNC viewer:输入密码 登录成功,界面和服务器本地桌面上一样:
VNC viewer
下面我们来修改 RIM_Oracle_Agent.9i 脚本,使它看起来像下面这样: #!/bin/sh export DISPLAY=tivf09:1.0; xterm -e gdb RIM_Oracle_Agent.binary 如果你的程序在 exec 的时候还传入了参数,可以改成: #!/bin/sh export DISPLAY=tivf09:1.0; xterm -e gdb --args RIM_Oracle_Agent.binary $@
[root@tivf09 root]#
Vncserver 是一个 Perl 脚本,用来启动 Xvnc(X VNC server)。X client 应用,比如 xterm,VNC viewer 都是和它通信的。如上所示,我们可 以使用的 DISPLAY 值为 tivf09:1。现在就可以从本地机器使用 VNC viewer 连接过去:
New ''tivf09:1 (root)'' desktop is tivf09:1
Starting applications specified in /root/.vnc/xstartup Log file is /root/.vnc/tivf09:1.log
[root@tivf09 root]#
} }
当 attach 到进程后,在该段代码之后设上断点,再把该文件删除就 OK 了。当然你也可以采用其他的条件或形式,只要这个条件可以设置/检 测即可。
Attach 进程方法还是很方便的,它能够应付各种各样复杂的进程系统, 比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的 就是加入一小段代码。
至于这段代码所采用的条件,看你的偏好了。比如我们可以检查一个指 定的环境变量的值,或者检查一个特定的文件存不存在。以文件为例, 其形式可以如下:
void debug_wait(char *tag_file) {
while(1) {
if (tag_file 存在) 睡眠一段时间;
else break;
attach 方法首先要找到待调试进程的 pid,一般是通过 ps 相关命令,例 如 pstree、ps –aux | grep 进程名称等等,然后通过 attach 关联到相 应的进程。
下面分别是一些介绍文章: GDB 是 linux 系统上常用的 c/c++ 调试工具,功能十分强大。对于较 为复杂的系统,比如多进程系统,如何使用 GDB 调试呢?考虑下面这 个三进程系统: 进程
将被调试,另一个进程置于暂停(suspended)状态。
注意,最好使用 GDB 6.6 或以上版本,如果你使用的是 GDB6.4,就只 有 follow-fork-mode 模式。
follow-fork-mode/detach-on-fork 的使用还是比较简单的,但由于其系 统内核/gdb 版本限制,我们只能在符合要求的系统上才能使用。而且, 由于 follow-fork-mode 的调试必然是从父进程开始的,对于 fork 多次, 以至于出现孙进程或曾孙进程的系统,例如上图 3 进程系统,调试起来 并不方便。
GDB wrapper 很多时候,父进程 fork 出子进程,子进程会紧接着调用 exec 族函数 来执行新的代码。对于这种情况,我们也可以使用 gdb wrapper 方法。 它的优点是不用添加额外代码。
其基本原理是以 gdb 调用待执行代码作为一个新的整体来被 exec 函数 执行,使得待执行代码始终处于 gdb 的控制中,这样我们自然能够调试 该子进程代码。
就会跳出一个终端窗口:
终端
如果你是在一台远程 linux 服务器上调试,那么可以使用 VNC(Virtual Network Computing) viewer 从本地机器连接到服务器上使用 xterm。 在此之前,需要在你的本地机器上安装 VNC viewer,在服务器上安装 并启动 VNC server。大多数 linux 发行版都预装了 vnc-server 软件包, 所以我们可以直接运行 vncserver 命令。注意,第一次运行 vncserver 时会提示输入密码,用作 VNC viewer 从客户端连接时的密码。可以在 VNC server 机器上使用 vncpasswd 命令修改密码。 [root@tivf09 root]# vncserver
nobody 6722 6721 0 05:57 ?