Analysis of core files with gdb and examples of common gdb command operation

** 1. Overview**
In practical software development projects, it is unavoidable that problems arise in the program. I still remember the first time I met the procedure after I joined the work. Previous experience tells me that the more panicked we are, the more unsolvable the problem will be. We need to calm ourselves down before we find solutions to procedural problems.
Friends who develop under Linux must have dealt with core files. When you see your own program running after core, many people are panicked, as if the sky is about to collapse. Actually, we don't have to. As long as we master the method of debugging core files with gdb, we can still locate program problems quickly and eliminate bugs in one fell swoop. For more information on Linux core files, read this article: http://www.cnblogs.com/dongzhiquan/archive/2012/01/20/2328355.html.
Taking a practical program as an example, this paper introduces the methods and steps of analyzing core files with gdb, and demonstrates the operation methods of common GDB commands. If you want to know more about the relevant GDB commands, please Baidu.

2. Examples

/**********************************************************************
* Copyright (C)2015, Zhou Zhaoxiong.
*
* File name: GdbDebug.c
* Document Identification: None
* Content Summary: Gdb Command Demonstration Program
* Other Notes: None
* Current version: V1.0
* Author: Zhou Zhaoxiong
* Completion date: 20151008
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Data type redefinition
typedef unsigned char       UINT8;
typedef signed   int        INT32;
typedef unsigned int        UINT32;


// Function declaration
void Sleep(UINT32 iCountMs);
void PrintInfo(void);
INT32 main();


/**********************************************************************
* Function description: main function
* Input parameters: none
* Output parameters: none
* Return value: None
* Other Notes: None
* Modify date version number Modifier Modify content
* -------------------------------------------------------------------
* 20151008       V1.0     Zhou Zhaoxiong      Establish
***********************************************************************/
INT32 main()
{
    PrintInfo();   // Output message on screen

    return 0;
}


/**********************************************************************
 * Function description: Output message on screen
 * Input parameters: none
 * Output parameters: none
 * Return value: None
 * Other Notes: None
 * Modify date version number Modifier Modify content
 * ----------------------------------------------------------------------
 * 20151008            V1.0        Zhou Zhaoxiong        Establish
 ************************************************************************/
void PrintInfo(void)
{
    UINT32 iLoopFlag = 0;
    UINT32 iSum      = 0;
    UINT32 iLen      = 0;
    UINT8 *pCtrStr   = NULL;

    iLen = strlen(pCtrStr);

    for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // Print message iLen times
    {
        printf("PrintInfo: hello, world!\n");

        iSum = iSum + iLoopFlag;

        Sleep(10 * 1000);   // Print every 10s
    }

    return;
}


/**********************************************************************
* Function Description: Program Hibernation
* Input parameter: iCountMs - dormancy time (in ms)
* Output parameters: none
* Return value: None
* Other Notes: None
* Modify date version number Modifier Modify content
* ------------------------------------------------------------------
* 20151008         V1.0     Zhou Zhaoxiong          Establish
********************************************************************/
void Sleep(UINT32 iCountMs)
{
    struct timeval t_timeout = {0};

    if (iCountMs < 1000)
    {
        t_timeout.tv_sec = 0;
        t_timeout.tv_usec = iCountMs * 1000;
    }
    else
    {
        t_timeout.tv_sec = iCountMs / 1000;
        t_timeout.tv_usec = (iCountMs % 1000) * 1000;
    }
    select(0, NULL, NULL, NULL, &t_timeout);   // Call select function blocker
}

** 3. Analysis of core files with gdb**
After compiling the program with the command "g C c-g-o GdbDebug GdbDebug.c" on Linux, running the command "GdbDebug", we found that the core file appeared in the current directory. The process of analyzing core files using the gdb command is as follows:

~/zhouzhaoxiong/zzx/GdbDebug> gdb GdbDebug core     -- start-up gdb Yes core Analysis of documents
GNU gdb (GDB) SUSE (7.3-0.6.1)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug...done.
Core was generated by `GdbDebug'.
Program terminated with signal 11, Segmentation fault.
#0  0x00007f4a736f9812 in __strlen_sse2 () from /lib64/libc.so.6
(gdb) where          -- Look at where the program went wrong
#0  0x00007f4a736f9812 in __strlen_sse2 () from /lib64/libc.so.6
#10x000000040061a in PrintInfo () at GdbDebug.c: 64 -- you can see the problem on line 64 of the GdbDebug.c file
#2  0x00000000004005e5 in main () at GdbDebug.c:41
(gdb) b 41           -- stay GdbDebug.c Line 41 of the document establishes a breakpoint
Breakpoint 1 at 0x4005e0: file GdbDebug.c, line 41.
(gdb) b 64           -- stay GdbDebug.c Line 64 of the document establishes breakpoints
Breakpoint 2 at 0x400611: file GdbDebug.c, line 64.
(gdb) info b         -- Display breakpoint information
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005e0 in main at GdbDebug.c:41
2       breakpoint     keep y   0x0000000000400611 in PrintInfo at GdbDebug.c:64
(gdb) r              -- Function GdbDebug
Starting program: /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug 

Breakpoint 1, main () at GdbDebug.c:41
41          PrintInfo();   // Output message on screen
(gdb) n             -- Execute the next step

Breakpoint 2, PrintInfo () at GdbDebug.c:64
64              iLen = strlen(pCtrStr);
(gdb) p iLen        -- Printing(output)iLen Value
$1 = 0
(gdb) p iLoopFlag   -- Printing(output)iLoopFlag Value
$2 = 0
(gdb) c             -- Continue execution     
Continuing.

Program received signal SIGSEGV, Segmentation fault.    -- program core Dropped
0x00007ffff7ae9812 in __strlen_sse2 () from /lib64/libc.so.6
(gdb) q             -- Sign out gdb
A debugging session is active.

        Inferior 1 [process 26640] will be killed.

Quit anyway? (y or n) y
~/zhouzhaoxiong/zzx/GdbDebug>

From the above analysis, we can see that when line 64 of the GdbDebug.c file is executed, the program core is dropped. At this time, careful analysis of the program, found that the pCtrStr pointer is empty. When the length of a non-existent pointer is taken, the program crashes because the address cannot be found. The modification is also very simple, just let the pCtrStr pointer point to the specific address.

** 4. Common examples of gdb command operations**
The modified code is as follows:

/**********************************************************************
* Copyright (C)2015, Zhou Zhaoxiong.
*
* File name: GdbDebug.c
* Document Identification: None
* Content Summary: Gdb Command Demonstration Program
* Other Notes: None
* Current version: V1.0
* Author: Zhou Zhaoxiong
* Completion date: 20151008
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Data type redefinition
typedef unsigned char       UINT8;
typedef signed   int        INT32;
typedef unsigned int        UINT32;


// Function declaration
void Sleep(UINT32 iCountMs);
void PrintInfo(void);
INT32 main();


/**********************************************************************
* Function description: main function
* Input parameters: none
* Output parameters: none
* Return value: None
* Other Notes: None
* Modify date version number Modifier Modify content
* -------------------------------------------------------------------
* 20151008       V1.0    Zhou Zhaoxiong       Establish
***********************************************************************/
INT32 main()
{
    PrintInfo();   // Output message on screen

    return 0;
}


/**********************************************************************
 * Function description: Output message on screen
 * Input parameters: none
 * Output parameters: none
 * Return value: None
 * Other Notes: None
 * Modify date version number Modifier Modify content
 * ----------------------------------------------------------------------
 * 20151008           V1.0         Zhou Zhaoxiong        Establish
 ************************************************************************/
void PrintInfo(void)
{
    UINT32 iLoopFlag = 0;
    UINT32 iSum      = 0;
    UINT32 iLen      = 0;
    UINT8 *pCtrStr   = "hello, world!";  // Modified this line of code

    iLen = strlen(pCtrStr);

    for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // Print message iLen times
    {
        printf("PrintInfo: hello, world!\n");

        iSum = iSum + iLoopFlag;

        Sleep(10 * 1000);   // Print every 10s
    }

    return;
}


/**********************************************************************
* Function Description: Program Hibernation
* Input parameter: iCountMs - dormancy time (in ms)
* Output parameters: none
* Return value: None
* Other Notes: None
* Modify date version number Modifier Modify content
* ------------------------------------------------------------------
* 20151008         V1.0     Zhou Zhaoxiong          Establish
********************************************************************/
void Sleep(UINT32 iCountMs)
{
    struct timeval t_timeout = {0};

    if (iCountMs < 1000)
    {
        t_timeout.tv_sec = 0;
        t_timeout.tv_usec = iCountMs * 1000;
    }
    else
    {
        t_timeout.tv_sec = iCountMs / 1000;
        t_timeout.tv_usec = (iCountMs % 1000) * 1000;
    }
    select(0, NULL, NULL, NULL, &t_timeout);   // Call select function blocker

After compiling and running, the program is normal, indicating that the problem has been solved by us. Here are some examples of common gdb commands:

~/zhouzhaoxiong/zzx/GdbDebug> gdb GdbDebug    -- start-up gdb debugging
GNU gdb (GDB) SUSE (7.3-0.6.1)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug...done.
(gdb) b 64     -- stay GdbDebug.c Line 64 of the document establishes breakpoints
Breakpoint 1 at 0x400611: file GdbDebug.c, line 64.
(gdb) b 72     -- stay GdbDebug.c Line 72 of the document establishes a breakpoint
Breakpoint 2 at 0x400637: file GdbDebug.c, line 72.
(gdb) info b   -- Display breakpoint information
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400611 in PrintInfo at GdbDebug.c:64
2       breakpoint     keep y   0x0000000000400637 in PrintInfo at GdbDebug.c:72
(gdb) r        -- Function GdbDebug
Starting program: /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug 

Breakpoint 1, PrintInfo () at GdbDebug.c:64
64              iLen = strlen(pCtrStr);
(gdb) p iLen    -- Printing(output)iLen Value
$1 = 0
(gdb) n         -- Execute the next step
66              for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // Print message iLen times
(gdb) n         -- Execute the next step
68              printf("PrintInfo: hello, world!\n");
(gdb) p iLoopFlag   -- Printing(output)iLoopFlag Value
$2 = 0
(gdb) p iLen    -- Printing(output)iLen Value
$3 = 13
(gdb) n         -- Execute the next step
PrintInfo: hello, world!    -- Output of the program
70                      iSum = iSum + iLoopFlag;
(gdb) p iSum    -- Printing(output)iSum Value
$4 = 0
(gdb) n        -- Execute the next step

Breakpoint 2, PrintInfo () at GdbDebug.c:72
72                      Sleep(10 * 1000);   // Print every 10s
(gdb) n      
66              for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // Print message iLen times
(gdb) p iLoopFlag
$5 = 0
(gdb) n
68              printf("PrintInfo: hello, world!\n");
(gdb) p iLoopFlag
$6 = 1
(gdb) n
PrintInfo: hello, world!
70                      iSum = iSum + iLoopFlag;
(gdb) p iSum
$7 = 0
(gdb) n

Breakpoint 2, PrintInfo () at GdbDebug.c:72
72                      Sleep(10 * 1000);   // Print every 10s
(gdb) p iSum
$8 = 1
(gdb) finish        -- Run until the function returns
Run till exit from #0  PrintInfo () at GdbDebug.c:72
PrintInfo: hello, world!

Breakpoint 2, PrintInfo () at GdbDebug.c:72
72                      Sleep(10 * 1000);   // Print every 10s
(gdb) c           -- Continue execution 
Continuing.
PrintInfo: hello, world!

Breakpoint 2, PrintInfo () at GdbDebug.c:72
72                      Sleep(10 * 1000);   // Print every 10s
(gdb) bt            -- Print all information about the current function call stack
#0  PrintInfo () at GdbDebug.c:72
#1  0x00000000004005e5 in main () at GdbDebug.c:41
(gdb) q              -- Sign out gdb
A debugging session is active.

        Inferior 1 [process 26685] will be killed.

Quit anyway? (y or n) y
~/zhouzhaoxiong/zzx/GdbDebug> 

As a tool for debugging C/C++ programs under Linux, we must be proficient in the use of gdb.

Keywords: Linux Session

Added by webtech123 on Thu, 23 May 2019 01:57:35 +0300