gdb debugging usage command under Linux (reproduced)

Reprinted from: http://blog.csdn.net/keith_bb/article/details/55216039

I have been writing opencv programs on the Fedora platform, and I need to debug the program. The main debugging tool is gdb. Gdb provides the following functions:

  • 1. Set a breakpoint in the program, and pause at the breakpoint when Debugging
  • 2. You can monitor a variable and use the print function to print the value of the variable
  • 3. The program can be executed step-by-step
  • 4. Modify the value of a variable at runtime
  • 5. Trace the path
  • 6. Thread switching, etc. 
    The following is an introduction to using gdb debugging for C\C++ programs with OpenCV.

1. gdb installation

First check if gdb is already installed on your computer

gdb --version
  • 1

If gdb already exists, you will get the following result: 
write picture description here 
If the version number of gdb is not given, you need to download it manually

sudo apt-get install gdb #针对Ubuntu系统
sudo dnf install gdb #针对Fedora系统
  • 1
  • 2

2. gcc\g++ compilation basis

In the previous article "Opencv: Two Ways to Compile OpenCV Programs under Linux, g++, cmake" introduced the basic content of gcc\g++ compilation. When you need to use gdb to debug the code, you need to add -g to the gcc\g++ compilation option. options, as follows:

g++ -g `pkg-config opencv --cflags` opencv.cpp  -o opencv `pkg-config opencv --libs`  
  • 1

The opencv executable file generated in this way can be directly debugged with gdb. 
You can directly enter gdb+ program name on the command line to enter debugging. Here, use the program in "Opencv Learning (31) Image Edge Pixel Filling Estimation CopyMakeBorder()" Demo, its code looks like this:

/*程序说明
 *当按下按键‘c’代表使用BORDER_CONSTANT
 *RNG生成的随机数作为像素值进行填充
 *当按下按键‘r’代表使用BORDER_REPLICATE
 *图像扩充的边框由原图像边缘像素的值进行填充
 */

#include <opencv2/imgproc.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;
using namespace cv;

//声明全局变量
Mat srcImage, dstImage;
int g_top, g_bottom, g_left, g_right;
int borderType;
Scalar value;
String windowName = "copyMakeBorder Demo";
RNG rng(12345);

int main()
{
    int c;

    srcImage = imread("dog.jpg");

    //判断图像是否加载成功
    if(srcImage.empty())
    {
        cout << "图像加载失败!" << endl;
        return -1;
    }
    else
        cout << "图像记载成功" << endl << endl;
    imshow("原图像", srcImage);

    //程序使用说明
    printf("\n \t copyMakeBorder Demo: \n");
    printf("\t --------------------\n");
    printf("**Press 'c' to set the border to a random constant value \n");
    printf("**Press 'r' to set the border to be replicated \n");
    printf("**Press 'ESC' to exit the program \n");

    //创建窗口
    namedWindow(windowName, WINDOW_AUTOSIZE);

    //初始化边框参数
    g_top = (int)(0.05*srcImage.rows);
    g_bottom = (int)(0.05*srcImage.rows);
    g_left = (int)(0.05*srcImage.cols);
    g_right = (int)(0.05*srcImage.cols);

    //显示初始图像
    dstImage = srcImage;    
    imshow(windowName, dstImage);

    while(true)
    {
        c = waitKey(500);

        if((char)c == 27)   //c为ESC程序退出
        {break;}
        else if((char)c == 'c')
        {borderType = BORDER_CONSTANT;}
        else if((char)c == 'r')
        {borderType = BORDER_REPLICATE;}

        value = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        copyMakeBorder(srcImage, dstImage, g_top, g_bottom, g_left, g_right, borderType, value);

        imshow(windowName, dstImage);
    }

    return 0;
}
  • Use g++ to compile the program as follows
g++ -g `pkg-config opencv --cflags` copyMakeBorder.cpp -o copyMakeBorder `pkg-config opencv --libs` 
  • Generate an executable file named copyMakeBorder in the program folder, enter the gdb debugging state below, and directly enter gdb + program name:
gdb copyMakeBorder
  • write picture description here

3.gdb debugging basic commands

After entering gdb, you can directly enter the corresponding command after (gdb) to debug.

3.1 list command

The list command can be written as l to list the code of the debugged program. Its specific usage includes:

  • list+lineNumber(中间有空格) 
    可以打印出行第lineNumber行周围的源程序,如:
(gdb)list 45
  • 其打印结果如下: 

write picture description here

  • list 打印函数名称为Function的函数上下文的源程序,如下
(gdb) list main
  • 结果如下: 

write picture description here

  • list 输出当前行后面的代码,如
(gdb) list
  • write picture description here
  • list -显示当前行前面的代码
(gdb) list -
  • 1

write picture description here

针对前面介绍的四种情况,在执行完一个命令后不输入任何命令,gdb会默认执行上一个命令

3.2 run命令

在gdb中运行程序使用run命令,在程序运行前可以设置程序的工作远景如:

  • 程序运行参数

    可以通过set args执行运行时的参数,针对的是main函数有如下书写格式时的程序

int main(int argc, char** argv)
{
    ...
}
- 程序运行环境
path < dir >可设定程序的运行路径;how paths可查看程序的运行路径;set environment varname [=value]用于设置环境变量;show environment [varname]用于查看环境变量。
![这里写图片描述](https://img-blog.csdn.net/20170215204054254?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2VpdGhfYmI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

  • 工作目录 
    cd < dir >相当于在终端中输入的cd命令;pwd命令用于显示当前所在目录 
    write picture description here
  • 输入输出 
    info terminal用于显示程序用到的终端模式;gdb中也可以使用重定向控制程序输出如:run>outfile; tty命令可以指定输入输出设备终端,如:tty /dev/ttyS1.

3.3 break命令

在使用gdb调试时使用break命令来设置断点,有如下几种方法:

  • break < function > 
    在进入指定的函数function时既停止运行,C++中可以使用class::function或function(type, type)格式来指定函数名称
  • break < lineNumber> 
    在指定的代码行打断点
  • break +offset/break -offset 
    在当前行的前面或后面的offset行打断点,offset为自然数
  • break filename:lineNumber 
    在名称为filename的文件中的第lineNumber行打断点
  • break filename:function 
    在名称为filename的文件中的function函数入口处打断点
  • break *address 
    在程序运行的内存地址处打断点
  • break 
    在下一条命令处停止运行
  • break … if < condition> 
    在处理某些循环体中可使用此方法进行调试,其中…可以是上述的break lineNumber、break +offset/break -offset中的参数,其中condition表示条件,在条件成立时程序即停止运行,如设置break if i=100表示当i为100时程序停止运行。 
    查看断点时,也可以使用info命令如info breakpoints [n]、info break [n]其中n 表示断点号来查看断点信息。 
    如下: 
    write picture description here

可以通过delete命令删除所有的断点,如下: 
write picture description here

3.4 逐步调试

使用gdb工具调试可以使用next命令单步执行程序代码,next的单步不会进入函数的内部,与next对应的step命令则在单步执行一个函数时进入函数内部,类似于VC++中的step into.其用法如下

  • next < count> 
    单步跟踪,如果有函数调用不会进入函数,如果后面不加count表示一条一条的执行,加count表示执行后面的count条指令,
(gdb) next 5
  • write picture description here 

- step < count> 
单步跟踪,如果有函数调用则进入该函数(进入该函数前提是此函数编译有Debug信息),与next类似,其不加count表示一条一条执行,加上count表示自当前行开始执行count条代码指令 
- set step-mode 
set step-mode on用于打开step-mode模式,这样在进行单步跟踪时,程序不会因为没有debug信息而不停止运行,这很有利于查看机器码,可以通过set step-mode off关闭step-mode模式 
- finish 
运行程序直到当前函数完成并打印函数返回时的堆栈地址和返回值及参数值等信息。 
- until 
运行程序直到退出循环体 
- stepi(缩写si)和nexti(缩写ni) 
stepi和nexti用于单步跟踪一条及其指令,一条程序代码有可能由数条机器指令完成,stepi和nexi可以单步执行机器指令。

3.5 continue命令

当程序遇到断点停止运行后可以使用continue命令恢复程序的运行到下一个断点或直到程序结束,其具体用法如下:

  • continue [ignore-count] 
    continue也可缩写为c,fg命令与continue命令相同,故上述continue可以使用c或fg代替,如下: 
    write picture description here

3.6 print命令

print可以缩写为p,可以通过print命令查看参数或程序运行数据

(gdb) break 53
Breakpoint 1 at 0x80490a7: file copyMakeBorder.cpp, line 53.
(gdb) break 54
Breakpoint 2 at 0x80490f3: file copyMakeBorder.cpp, line 54.
(gdb) break 55
Breakpoint 3 at 0x8049129: file copyMakeBorder.cpp, line 55.
(gdb) break 56
Breakpoint 4 at 0x804915f: file copyMakeBorder.cpp, line 56.
(gdb) r
Starting program: /home/keith/program/opencv/opencv学习(三十一)之图像边框/copyMakeBorder 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
[New Thread 0xb543fb40 (LWP 11484)]
图像记载成功

[New Thread 0xb470db40 (LWP 11485)]
[New Thread 0xb3dffb40 (LWP 11486)]

     copyMakeBorder Demo: 
     --------------------
**Press 'c' to set the border to a random constant value 
**Press 'r' to set the border to be replicated 
**Press 'ESC' to exit the program 

Thread 1 "copyMakeBorder" hit Breakpoint 1, main () at copyMakeBorder.cpp:53
53      g_top = (int)(0.05*srcImage.rows);
(gdb) continue
Continuing.

Thread 1 "copyMakeBorder" hit Breakpoint 2, main () at copyMakeBorder.cpp:54
54      g_bottom = (int)(0.05*srcImage.rows);
(gdb) p g_top
$1 = 20
(gdb) p g_bottom
$2 = 0
(gdb) continue 
Continuing.

Thread 1 "copyMakeBorder" hit Breakpoint 3, main () at copyMakeBorder.cpp:55
55      g_left = (int)(0.05*srcImage.cols);
(gdb) p g_bottom 
$3 = 20
(gdb) 
  • 部分截图如下: 

write picture description here 
值得注意的是print输出可以指定输出格式

  • x按16进制格式显示变量
  • d按十进制显示变量
  • u按十六进制格式显示无符号整形
  • o按八进制格式显示变量
  • t按二进制格式显示变量
  • c按字符格式显示变量
  • f按浮点数格式显示变量 
    可以使用display命令设置一些自动显示的变量,当程序暂停运行或单步跟踪时,这些变量会自动显示 
    write picture description here 
    如果要修改变量的值也可以使用print命令如
print g_top = 24
  • 使用print查看程序运行时的数据时,每一个print都会被gdb记录下来并且以 (美元符号)1、(美元符号)2…这样的方式为每一个print命令编号,我们可以使用这个编号来访问以前的表达式如: 

write picture description here

3.7 watch命令

watch命令一般来观察某个表达式(变量也可视为一种表达式)的值是否发生了变化,如果由变化则程序立即停止运行,其具体用法如下:

  • watch < expr> 
    为表达式(变量)expr设置一个观察点一旦其数值由变化,程序立即停止运行
  • rwatch < expr> 
    当表达式expr被读时,程序立即停止运行
  • awatch < expr> 
    当表达式expr的值被读或被写时程序立即停止运行
  • info watchpoints 
    列出当前所设置的所有观察点

3.8 return命令

如果在函数中设置了调试断点,在断点后还有语句没有执行完,这个时候我们可以使用return命令强制函数忽略还没有执行的语句并返回。可以直接使用return命令用于取消当前函数的执行并立即返回函数值,也可以指定表达式如 return < expression>那么该表达式的值会被作为函数的返回值。

3.9 info命令

info命令可以用来在调试时查看寄存器、断点、观察点和信号等信息。其用法如下:

  • info registers:查看除了浮点寄存器以外的寄存器
  • info all-registers: 查看所有的寄存器包括浮点寄存器
  • info registers < registersName>: View the specified registers
  • info break: View all breakpoint information
  • info watchpoints: View all watchpoints currently set
  • info signals info handle: see which signals are being detected by gdb
  • info line: View the address of the source code in memory
  • info threads: You can view multithreading

3.10 run and quit commands

run (abbreviated r) and quit (abbreviated q) can respectively start running the program and exit gdb debugging

3.11 Other commands

  • whatis or ptype show the type of the variable
  • bt display function call path

This article refers to many blogs. These commands of gdb can only be used skillfully. Of course, these commands do not fully list the gdb commands. You can view the help of all gdb commands through the help command. 
Reference blog:  
http://blog.csdn.net/21cnbao/article/details/7385161  
http://blog.csdn.net/yeyuangen/article/details/6825542  
http://www.cnblogs.com/kunhu/p /3603268.html


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325734647&siteId=291194637