Debugging program bugs with gdb

Posted by leo.bonnafe on Thu, 30 Dec 2021 17:06:58 +0100

1. Experimental purpose

By debugging a problematic program, proficient in using vi, mastering gcc compilation commands and gdb debugging commands
Through the tracking and debugging of problematic programs, the ability to find and solve problems is further improved

2. Experimental contents

(1) Using the vi editor, enter the following code into a file named greet.c. This code originally meant to output the strings defined in the main function in reverse order, but the result showed no output.

#include<stdio.h>
int display1(char *string);
int display2(char *string);

int main()
{
	char string[] = "Embedded Linux";
	display1 (string);
	display2 (string);
}
int display1 (char *string)
{
	printf ("The original string is %s \n",string);//%s represents a placeholder for a string, and display1 directly outputs a string
}
int display2 (char *string1)//Variable does not have the same name
{
	char *string2;/*A character pointer (the pointer is the memory address). All actual data types, whether integer, floating point, character,
	Or other data types, the value type of the corresponding pointer is the same, which is a long hexadecimal number representing the memory address.

    The only difference between pointers of different data types is that the data types of variables or constants pointed to by the pointer are different.*/
	int size,i;
	size = strlen (string1);/*strlen Sizeof is a function and sizeof is a unary operator.

strlen It is used to calculate the length of the specified string str, but does not include the closing character (i.e. null character).
The keyword sizeof is a unary operator. The parameters can be array, pointer, type, object, function, etc
strlen Precautions during use:

strlen Only char * can be used as a parameter and must end with '\ 0'. In other words: strlen can only calculate the length of a string.

sizeof Precautions during use:

1 For direct calls to sizeof, if it is the first address of the array, sizeof will output the size of the address space occupied by the array (in bytes).
If it is a pointer, the byte width of the address in the system is output, i.e. (bit width / 8).*/
	string2 = (char *) malloc (size + 1);/*If you want to store the number of people in the whole school, there will be insufficient memory;
	When we open up an array of the number of people in the whole school and enter the size of the number of people in a class, there will be a waste of memory.
In order to solve the above problems, we introduce malloc function.
malloc Is a dynamic memory allocation function, which is used to apply for a continuous memory block area of specified size and return the address of the allocated memory area in void * type
malloc Function prototype
extern void *malloc(unsigned int num_bytes);
It means that the allocation length is num_bytes memory block
 Header file #include < malloc h>
malloc Function return value
 If the allocation is successful, a pointer to the allocated memory is returned; otherwise, a NULL pointer is returned.

malloc Precautions for using functions
malloc The function returns a typeless pointer, which must be cast to the required type when used.
**((knocking on the blackboard) key: when using malloc to open up space, the space must be released after use. If it is not released, it will cause memory leakage.
Do not move the pointer in the space opened up by using malloc function,
Once moved, there may be a mismatch between the requested space and the released space
 Use form
malloc Only open up space, do not carry out type checking, but carry out strong conversion of types when using.
mallo The function actually returns a typeless pointer, which must be preceded by a pointer type cast before it can be used
 Before using malloc function, we must calculate the number of bytes. Malloc opens up the space for the number of bytes required by users.
If you apply for space many times, how does the system do not reuse the space?
After opening up a space with malloc, the system will make a mark (0 or 1) before the space,
When malloc function opens up a space, if it is marked as 0, it will be opened here. If it is 1, it indicates that this space is being used.
free function
 Function: release the memory space allocated by malloc (or calloc, realloc) function to pointer variables.
Note: after use, the pointer variable must point to NULL again to prevent the occurrence of dangling pointer (invalid pointer) and effectively avoid wrong operation.
free After releasing space, the function changes the flag in front of memory to 0, and in order to prevent data leakage, it will fill the released space with cd.
*/
	for (i = 0; i < size; i++)
	{
		string2[size - i] = string1[i];/*Under the action of the for loop, the head of string1 is copied to the tail of string2 in turn
		string1 The first one of is given to the last one of string2*/
	}
	string2[size+1] = ' ';//Add an empty character at the end of string2
	printf("The string afterward is %s\n",string2);
}

(2) When compiling this code with gcc, pay attention to adding the "- g" option to facilitate subsequent debugging. This option means "include standard debugging information in the executable program"
(3) Run the generated executable file and observe the running results
(4) Use gdb debugger to find out the error step by step by setting breakpoints and single-step tracking.
(5) Correct the error, change the source program and get the correct results.

3. Experimental steps

(1) Create a new file greet.c in the working directory and start with vi: vi greet.c
(2) Enter the above code in vi
(3) Save and exit in vi using the command ": wq"
(4) Compile with gcc: gcc -g greet.c -o greet
(5) Run greet and use the command ". / greet". The output is:
The original string is Embedded Linux
The string afterward is
It can be seen that the program can not output in reverse order
(6) Start gdb debugging: gdb greet
(7) To view the source code, use the command "l"
(8) Set the breakpoint at line 30 (at the for loop) and use the command "b 30"
(9) Set the breakpoint at line 33 (at the printf function) and use the command "b 33"
(10) To view breakpoint settings, use the command "info b"
(11) Run the code using the command "r"
(12) Step through the code using the command "n"
(13) To view the pause point variable value, use the command "p string2[size - i]"
(14) Continue to step the code several times and check that the value of string2[size-i] is correct
(15) To continue the program, use the command "c"
(16) The program stops running before printf. At this time, check string2[0] and string2[1] successively. It is found that string2[0] is not correctly assigned, and the subsequent assignments are correct. At this time, locate line 31 of the program and find that the reason for the error of the program running result is "size-1". Because I can only be increased to "size-i", so string2[0] It can never be assigned and kept NULL, so no result can be output
(17) Exit gdb and use the command "q"
(18) Re edit greet.c and change "string2[size - i] = string1[i]" to "string2[size - i - 1] = string1[i];" that will do
(19) Recompile with gcc: gcc -g greet.c -o greet
(20) View run results:. / greet
The original string is Embedded Linux
The string afterward is xuniL deddedbmE
At this time, the output result is correct

4. Experimental results

The original program with errors is debugged by gdb to find out the problem, modify the source code, and output the results of the correct inverted display string

Topics: Linux