Summary of Linux programming segment errors (segmentation error)

Source: Internet
Author: User

Recently, I used C for some learning and development in Linux. However, due to lack of experience, there are many problems. A paragraph error is a headache for me. However, at present, there are few segment errors when writing a code of around one thousand lines, or even if it appears, it is easy to find and process it out.

So what is a segment error? Why is it a problem? And how to find out the segment errors in the program and how to avoid segment errors?

On the one hand, I want to make a summary for my own learning. On the other hand, since I have not found a problem that comprehensively introduces this although it is a "special problem", let's make a discussion. Next we will discuss "segmentation faults" from the above questions.

Directory

1. What is a segment error?
2. Why is a segment error so "troublesome "?
3. What are the common errors in programming?
4. How can I find and handle segment errors in the program?

Body

1. What is a segment error?

The following is the definition from answers.com:
Quote:

A
Segmentation fault (often shortened to segfault) is a participant Error
Condition that can occur during the operation of computer software. In
Short, a segmentation fault occurs when a program attempts to access
Memory location that it is not allowed to access, or attempts to access
A memory location in a way that is not allowed (e.g., attempts to write
To a read-only location, or to overwrite part of the operating system ).
Systems Based on processors like the Motorola 68000 tend to refer
These events as address or bus errors.

Segmentation is one
Approach to memory management and protection in the operating system.
It has been superseded by paging for most purposes, but much of
Terminology of segmentation is still used, "segmentation fault" being
An example. Some operating systems still have segmentation at some
Logical level although paging is used as the main memory management
Policy.

On Unix-like operating systems, a process that accesses
Invalid Memory es the SIGSEGV signal. on Microsoft Windows,
Process that accesses invalid memory instances es
Status_access_violation exception.

In addition, here there is a basic contrast to the Chinese interpretation, from the http://www.linux999.org/html_ SQL /3/132559.htm
Quote:

Institute
A segment error means that the accessed memory exceeds the memory space of the program provided by the system. Generally, this value is saved by GDTR, which is a 48-bit register, the 32-bit is saved and pointed by it
In the gdt table, the last 13 BITs are saved to the corresponding gdt subscript, and the last three bits include whether the program is in memory and the running level of the program in the CPU, gdt is a table in 64-bit units,
This table stores the code segment for running the program, the starting address of the data segment, the corresponding segment limit and page switch, the program running level, and the memory granularity. Once a program is out of bounds
The CPU will generate corresponding exception protection, so segmentation fault will appear

According to the above explanation, the segment error should be the access to the inaccessible memory. The memory zone either does not exist or is protected by the system.

2. Why is segment error so troublesome?

Medium
China's Linux Forum has an excellent post: Segment fault
Forever pain "(http://www.linuxforum.net/forum/gshowflat.php? Cat = &
Board = Program & number = 193239 & page = 2 & view = collapsed & SB = 5 & O = All & fpart = 1 & Vc = 1)
In the topic post, the author wrote:
Quote:

Segment fault has been a headache for many c programmers for many years. Pointers are good, but with the use of pointers, this powerful demon is born.

Segment fault is widely used in the world because it is closely related to the non-null parameter pointers of all the basic functions in the glibc library.

I don't know when a glibc library capable of processing null will be born!

As a last resort, I have made clothes for a lot of functions to prevent the glibc function from being infected by null, resulting in my mem access error, I still don't know that the null virus has eroded my body.

Segment fault forever pain ......

Many netizens have followed the post to discuss why segmentation faults is so "painful", especially for server programs. To improve efficiency, it is necessary to minimize the "judgment and handling" of unnecessary segment errors, but there may be hidden risks of segment errors if you do not check them.

So how to deal with this "trouble?
Just as people cannot be "perfect", the "computer language" created by people does not have a "perfect" solution.
Our better solution may be:

By studying previous experiences and development tools, we constantly try and research to find a more appropriate method to avoid, discover, and handle it. For some common areas, we can avoid them. For some "hidden" areas, we need to discover them and handle them in time to avoid hidden risks.

In the following example, we can use a specific experiment to illustrate the frequent occurrence of errors, and then give an example to find and find out the hidden places of such errors, and finally solve them.

3. What are the common errors in programming?

To conduct the following experiment, we need to prepare two tools: GCC and GDB.
I did an experiment in Ubuntu. installing these two things is relatively simple.
Quote:

Sudo apt-Get install gcc-4.0 libc6-dev
Sudo apt-Get install GDB

Now, let's start our experiment. Let's roughly split the class.

1) write data to the memory address protected by the System

Some memory is occupied by the kernel or is being used by other programs. To ensure normal operation of the system, it is protected by the system and cannot be accessed at will.

Example 1:

Code:
# Include
<Stdio. h> intmain () {int I = 0; scanf ("% d", I );/*
Shocould have used & I */printf ("% d/N", I); return 0 ;}
[Ctrl + A select all]

Compile and execute
Quote:

Falcon @ Falcon :~ /TEMP $ gcc-O segerr. c
Falcon @ Falcon :~ /TEMP $./segerr
10
Segment Error

At first glance, it seems that there is no problem. Isn't it just to read a data and then output it?

Let's debug it and see why?
Quote:

Falcon @ Falcon :~ /TEMP $ gcc-g-o segerr. c -- add-G option to view debugging information
Falcon @ Falcon :~ /TEMP $ GDB./segerr
Gnu gdb 6.4-Debian
Copyright 2005 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 "i486-linux-gnu"... using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1 ".

(GDB) l -- use L (list) to display our source code
1 # include <stdio. h>
2
3 int
4 main ()
5 {
6 int I = 0;
7
8 scanf ("% d", I);/* shocould have used & I */
9 printf ("% d/N", I );
10 return 0;
(GDB) B 8 -- use B (break) to set breakpoints
Breakpoint 1 at 0x80483b7: file segerr. C, line 8.
(GDB) p I -- print the value of variable I with P (print) [No, here the value of I is 0]
$1 = 0

(GDB) r -- run with R (run) until the breakpoint
Starting program:/home/Falcon/temp/segerr

Breakpoint 1, main () at segerr. C: 8
8 scanf ("% d", I);/* shocould have used & I */-- [try to write a value to address 0]
(GDB) n -- use N (next) to execute the next step.
10

Program received signal SIGSEGV, segmentation fault.
0xb7e9a1ca in _ io_vfscanf () from/lib/tls/i686/cmov/libc. so.6
(GDB) c -- we receive SIGSEGV above, and then use C (CONTINUE) to continue executing
Continuing.

Program terminated with signal SIGSEGV, segmentation fault.
The program no longer exists.
(GDB) Quit -- exit GDB

Sure enough
We accidentally wrote & I as I
At the beginning, I was initialized to 0. Didn't we try to store a value to memory address 0? In fact, in many cases, even if the initialization is not zero, the default value may be 0, so pay special attention to it.

Supplement:
You can use man 7 signal to view SIGSEGV information.
Quote:

Falcon @ Falcon :~ /TEMP $ MAN 7 signal | grep segv
Reformatting signal (7), please wait...
SIGSEGV 11 core Invalid Memory Reference

Example 2:

Code:
# Include <stdio. h> intmain () {char * P; P = NULL; * P = 'X'; printf ("% C", * P); Return 0 ;}
[Ctrl + A select all]

It is easy to find that this example also tries to write something to the memory address 0.

Here we use GDB to view the row where the segment error is located.
Quote:

Falcon @ Falcon :~ /TEMP $ gcc-g-o segerr. c
Falcon @ Falcon :~ /TEMP $ GDB./segerr
Gnu gdb 6.4-Debian
Copyright 2005 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 "i486-linux-gnu"... using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1 ".

(GDB) r -- run it directly. After a segment error is thrown, the row with a segment error is automatically displayed. This is a method to locate the segment error.
Starting program:/home/Falcon/temp/segerr

Program received signal SIGSEGV, segmentation fault.
0x08048516 in main () at segerr. C: 10
10 * P = 'X ';
(GDB)

2) Out-of-memory (array out-of-bounds, inconsistent variable types, etc)

Example 3:

Code:
# Include <stdio. h> intmain () {char test [1]; printf ("% C", test [1000000000]); Return 0 ;}
[Ctrl + A select all]

Here is an extreme example, but sometimes it may occur, which is an obvious array out-of-bounds problem.
Or this address does not exist at all.

Example 4:

Code:
# Include <stdio. h> intmain () {int B = 10; printf ("% s/n", B); Return 0 ;}
[Ctrl + A select all]

What is the problem when we try to output an integer as a string?
Because you are not familiar with debugging dynamic link libraries
I just found the source code of printf.
Quote:

Declaration part:
Int Pos = 0, cnt_printed_chars = 0, I;
Unsigned char * chptr;
Va_list AP;
% S format Control Section:
Case's ':
Chptr = va_arg (AP, unsigned char *);
I = 0;
While (chptr [I])
{...
Cnt_printed_chars ++;
Putchar (chptr [I ++]);
}

Zi
Let's take a look at the problem. When printing a string, it actually prints all the characters starting from an address. But when you want to print an integer as a string, this integer is treated as a location
And then printf prints characters starting from this address to guide/0 at a certain position. Therefore, if this integer indicates that the address does not exist or cannot be accessed, the access is not allowed.
Memory -- segmentation fault.

Similarly, there are also formats such as sprintf.
For example, if you try to output or store the char or Int type in % s, for example:

Code:
# Include
<Stdio. h> # include <string. h> char c = 'C'; int I = 10; char
Buf [100]; printf ("% s", C );
// Try to output the char type in string format. The characters here are interpreted as integers and then addresses. The reason is as follows: printf ("% s ",
I); // try to output the int type memset (BUF, 0,100) according to the string; sprintf (BUF, "% s ",
C); // try to convert the char type to memset (BUF, 0,100) according to the string format; sprintf (BUF, "% s", I );
// Try to convert int type to string type
[Ctrl + A select all]

3) Others

In fact, the general reasons are the same, that is, the definition of segment errors. However, more error-prone areas must be accumulated by yourself, without discovering them, or absorbing the experience accumulated by our predecessors, and be careful not to happen again.

For example:

<1> after defining the pointer, remember to initialize it. When using the pointer, remember to judge whether it is null.
<2> whether the array is initialized when an array is used, whether the array subscript is out of bounds, and whether the array element exists.
<3> the variable format control is reasonable During Variable Processing.

Another good example:

In a multi-threaded programming example, I defined a thread array.
# Define thread_max_num
Pthread_t thread [thread_max_num];
Each thread is created with pthread_create, and then pthread_join is used to wait for the end of the thread.

Gang
At the beginning, I will wait directly. When the threads are successfully created, pthread_join can successfully wait for the end of each thread. However, once the thread creation fails, pthread_join will be used.
Wait for a thread that does not exist to access the memory that cannot be accessed, which leads to a segment error. Later, through continuous debugging and thinking, in addition, I got help from the information on the network and found the above
Causes and solutions:

Before creating a thread, initialize our thread array and determine whether the thread is our initial value while waiting for the end of the thread.
If yes, it indicates that our thread has not been created successfully, so it cannot be pulled. Otherwise, memory space that does not exist or is inaccessible will be released.

The above shows several common errors, so that it is easy to avoid pulling when encountering them. However, sometimes people may also be negligent, or even frequently encounter the above problems or other common problems, so for some large-scale programs, how to track and locate the segment errors in the program is a skill to be mastered.

4. How can I find a segment error in a program?

A netizen made a comprehensive summary of this. Besides thanking him, I gave the address. The article is named "debugging of a segment error bug" (http://www.cublog.cn/u/5251/showart.php? Id = 173718.

My common debugging methods include:

1) output (printf) Information in key parts of the program, so that the possible location of segment errors in the code can be tracked

To facilitate this debugging method, you can use the Conditional compilation command # ifdef debug and # endif to include the printf function. You can view the debugging information by adding the-ddebug parameter during compilation. If you do not add this parameter for debugging, you can.

2) use GDB for debugging. When a segment error occurs, the system automatically stops and displays the row and row number of the error.

This
It should be very common. If you need to debug with GDB, remember to add the-G parameter during compilation to display debugging information. For this, creative use of Block Error bug debugging by netizens
This method allows us to dynamically obtain the possible location of a segment error when executing the program: trigger the system to call GDB by capturing the SIGSEGV signal to output debugging information. If you add
The Conditional compilation mentioned above makes debugging and pulling of segment errors very convenient.

3) There is also a catchsegv command
You can view the help information.
Quote:

Catch segmentation faults in programs

This is used to get a segment error, but some items in register are printed and "I don't understand it ".

Here, the "Preliminary Summary" is almost complete. Thank you for your improper or even incorrect expression!

Reference [the specific address has been shown in the previous article]:

1. Segment error Definition
Ansers.com

Http://www.answers.com

Definition of "segmentation fault"

Http://www.faqs.org/qa/qa-673.html

2. What is a paragraph Error

Http://www.linux999.org/html_ SQL /3/132559.htm

3. Segment fault: eternal pain

Http://www.linuxforum.net/forum/gshowflat.php? Cat = & board = Program & number = 193239 & page = 2 & view = collapsed & SB = 5 & O = All & fpart =

4. Debugging of segment errors and bugs

Http://www.cublog.cn/u/5251/showart.php? Id = 173718

Postscript

Although I felt that I did not write anything, it took a few hours to search for materials and type data. However, it is worthwhile to sum up. I would like to discuss it with you, you are also welcome to correct the incorrect or even incorrect content in the article.

 

 Original article address

Http://hi.baidu.com/lifeibest/blog/item/47c246e78d44ad2db93820a3.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.