c&c++--Segment Error (segmentation fault)

Source: Internet
Author: User
Tags sprintf


Segment error in C/C + + (segmentation fault)


Segment fault can be popular in the world, is the basic function of the GLIBC library and the default parameter pointer is not NULL has a close relationship.
From: http://oss.lzu.edu.cn/blog/article.php?uid_7/tid_700.html#comment

Background
Recently in Linux under the use of C to do some learning and development, but due to lack of experience, a lot of problems. and paragraph error is a problem that makes me very headache. However, currently writing a 1000 line or so of the code, there are few errors, or even if it appears, it is easy to find out, and deal with it.

Then what is a paragraph error? What's a problem with a segment error? And how to find the segment error in the program and how to avoid a segment error?

On the one hand in order to give their own study to make a summary, on the other hand because so far did not find a more comprehensive introduction of this although is "frequently asked QUESTIONS" problem, so I will make a point. The following is a few questions from the above to explore the "segmentation faults" bar.

Directory
1. What is a segment error?
2. Why is the paragraph wrong so "troublesome"?
3. What are some of the areas where the error is usually encountered during programming?
4. How do I find a segment error in my program and dispose of it?

Body
1. What is a segment error?
Here is the definition from answers.com:
A segmentation fault (often shortened to segfault) are a particular error condition that can occur during the operation of Computer software. In short, a segmentation fault occurs if a program attempts to access a memory location that it's not allowed to access , or attempts to access a memory-location in a-a-is-not-allowed (e.g., attempts to write-to-a read-only location, O R to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.

Segmentation is one approach to memory management and protection in the operating system. It had been superseded by paging for most purposes, but much of the terminology of segmentation was still used, "Segmentati On fault "being an example. Some operating systems still has 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 receives the SIGSEGV signal. On Microsoft Windows, a process of that accesses invalid memory receives the status_access_violation exception.

In addition, here is a basically contrasting Chinese explanation, from http://www.linux999.org/html_sql/3/132559.htm
The so-called segment error means that the memory accessed exceeds the memory space given to the program by the system, usually this value is saved by GDTR, which is a 48-bit register, where 32 bits are saved by the GDT that it points to, and the last 13 bits are stored accordingly to the GDT, The last 3 bits include whether the program is in memory and the program's operating level in the CPU, and the GDT that points to is a table of 64 bits in a single unit, in this table It saves the code snippet that the program runs and the starting address of the data segment, as well as information about the corresponding segment limit and page Exchange, the program run level, and the granularity of the memory. Once a program has crossed access, the CPU will have a corresponding exception protection, so segmentation fault appeared

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

2. Why is the mistake so troublesome?
China Linux Forum has an elite post "Segment Fault's Eternal 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 writes:
Writing programs for many years, Segment fault is a headache for many C programmers tips. Pointers are good things, but the same powerful demon is born with the use of pointers.

Segment fault can be popular in the world, is the basic function of the GLIBC library and the default parameter pointer is not NULL has a close relationship.

I don't know when I can have a glibc library capable of handling null.

Last resort, I've made clothes for a lot of functions, avoiding the GLIBC function being null to infect, causing my mem access error, and I don't know null the virus is already eroding my body.

Segment Fault Forever Pain ...

Behind a lot of netizens are thread, discussed segmentation faults why so "pain", especially for the server program, is very headache, in order to improve efficiency, to minimize some unnecessary section error "judgment and processing", but do not check and there may be a hidden danger of a paragraph error.

So how do you deal with this "trouble"?
Just as people cannot be "perfect", the "computer language" created by people also has no "perfect" solution.
Our better solution might be to:

By learning from previous experiences and developing tools, try and study constantly to find out more appropriate ways to avoid, discover and deal with it. For some common places, we can avoid, for some "hidden" places, we have to find it, we must deal with in time to avoid leaving hidden trouble.

Below we can use specific experiments to cite some of the areas where errors are often found, and then give examples to find and find out where such errors hide, and finally disposed of.

3. What are some of the areas where the error is usually encountered during programming?
In order to perform the following experiments, we need to prepare two tools, one is GCC, the other is GDB
I was doing the experiment under Ubuntu, installing these two things is relatively simple
sudo apt-get install gcc-4.0 Libc6-dev
sudo apt-get install gdb

OK, let's get into our experiment and we'll get a rough break on the class

1) write data to the memory address that is protected by the system
Some memory is used by the kernel or other programs are in use, in order to ensure that the system works properly, it will be protected by the system, and can not be arbitrarily accessed.
Example 1:

Code:
#include <stdio.h>
int main () {
int i=0;
scanf ("%d", I);
printf ("%d\n", I);
return 0;
}
Compile and execute a bit
$ gcc-o Segerr segerr.c
$./segerr
10
Segment Error
At first glance, it seems that there is no problem oh, just read a data and then give the output?

Let's debug it and see what the reason is.
$ gcc-g-o segerr segerr.c-plus-G option to view debug information
$ gdb./segerr
(GDB) L--Display our source code with the L (list)
1 #i nclude <stdio.h>
2
3 int
4 Main ()
5 {
6 int i = 0;
7
8 scanf ("%d", I);
9 printf ("%d\n", I);
return 0;
(GDB) B 8--Set breakpoints with B (break)
Breakpoint 1 at 0x80483b7:file segerr.c, line 8.
(GDB) P I--print the value of the variable I with P (print) [see No, here I is the value of 0 Oh]
$ = 0

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

Breakpoint 1, Main () at Segerr.c:8
8 scanf ("%d", I); --[attempt to write a value to address 0]
(GDB) N--performs the next step with N (next)
10

Program received signal SIGSEGV, segmentation fault.
0xb7e9a1ca in _io_vfscanf () from/lib/tls/i686/cmov/libc.so.6
(GDB) C--we received the SIGSEGV on it, and then we continued with C (continue)
Continuing.

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

Sure enough
We "accidentally" wrote &i I.
And we just started initializing I to 0, so we're not trying to store a value for memory address 0? In fact, in many cases, even if you do not initialize to zero, the default may be 0, so pay special attention.

Add:
You can view SIGSEGV information through the Man 7 signal.
$ Man 7 Signal | grep SEGV
Reformatting signal (7), please wait ...
SIGSEGV Core Invalid Memory Reference

Example 2:
Code:
#include <stdio.h>
int main () {
Char *p;
p = NULL;
*p = ' x ';
printf ("%c", *p);
return 0;
}
It's easy to see that this example is also trying to write something to memory address 0.

Here we look at the row where the segment error is through GDB
$ gcc-g-O segerr segerr.c
$ gdb./segerr
(GDB) R--run directly, we see the throw segment error, automatically shows the occurrence of a segment error line, this is a way to find out the segment error
Starting program:/home/falcon/temp/segerr

Program received signal SIGSEGV, segmentation fault.
0x08048516 in Main () at Segerr.c:10
Ten *p = ' x ';
(GDB)

2) memory out of bounds (array out of bounds, variable type inconsistent, etc.)
Example 3:
Code:
#include <stdio.h>
int main () {
Char test[1];
printf ("%c", test[1000000000]);
return 0;
}
This is an extreme example, but sometimes it can happen, it's an obvious problem with the array out of bounds, or the address doesn't exist at all.

Example 4:
Code:
#include <stdio.h>
int main () {
int B = 10;
printf ("%s\n", b);
return 0;
}
We're trying to output an integer as a string, what's the problem?
Since I am not yet familiar with debugging dynamic link libraries, I just found the following declaration section of the source code for printf:
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 + +]);
}

Take a closer look at the problem, when you print a string, you actually print all the characters at the beginning of an address, but when you want to print the integer as a string, the integer is treated as an address, and printf starts to print the character from the address until the value in a position is. Therefore, if the integer represents an address that does not exist or is inaccessible, it is natural to access the memory--segmentation fault that should not be accessed.

Similarly, there are format control issues such as: sprintf
For example, try to export or store the char or int as%s, as follows:
Code:
#include <stdio.h>
#include <string.h>
int main () {
Char c= ' C ';
int i=10;
Char buf[100];
printf ("%s", c); Attempt to output char type in string format, here the word inode is interpreted as an integer,
Explain it again to the address, so the reason is the same as the above example
printf ("%s", I); Attempting to export int as String
memset (buf, 0, 100);
sprintf (buf, "%s", c); An attempt was made to convert a char type in string format
memset (buf, 0, 100);
sprintf (buf, "%s", I);//attempt to convert int as String
}


3) Other
In fact, the reason is the same, is the definition of the wrong paragraph. But more error-prone places to accumulate, not to find, or to absorb the experience accumulated by predecessors, and to avoid recurrence.
For example:
<1> Remember to initialize when the pointer is defined and remember to determine if it is null when used
<2> whether the array is initialized when it is used, whether the array subscript is out of bounds, whether the array element exists, etc.
<3> whether the variable's format control is reasonable when the variable is processed

One more good example:

I'm doing a multithreaded programming example, defining a thread array
#define Thread_max_num
pthread_t Thread[thread_max_num];
Create each thread with Pthread_create, and then use Pthread_join to wait for the thread to end

In the beginning I just wait, when the creation of the thread is successful, pthread_join can wait for each thread to end, but once the creation of the thread fails, the Pthread_join to wait for the non-existent thread, there will naturally be access to inaccessible memory situation, This leads to the occurrence of segment errors, and later, through constant debugging and thinking, and getting the information on the network to help, found the above reasons and solutions:

Before creating the thread, initialize our thread array and, at the end of the waiting thread, determine if the thread is our initial value
If so, it means that our thread has not been created successfully, so we cannot wait for the pull. Otherwise, there will be free memory space that does not exist or is inaccessible.

There are a number of common areas where errors occur, so it is easy to avoid pulling when encountering them. However, people sometimes must be negligent, and may even often appear above the problem or other common problems, so for some large-scale program, how to track and find the program in the wrong position is a skill to grasp the pull.

4. How do I find a segment error in my program?
There is a netizen to this to do a more comprehensive summary, in addition to thank him, I took the address to get over. The article is called "section error Bug Debug" (http://www.cublog.cn/u/5251/showart.php?id=173718), it should be said to be very comprehensive.

And my usual debugging methods are:
1) output (printf) information in key parts of the program, so that you can track the possible location of a segment error in your code
In order to facilitate the use of this debugging method, you can use the conditional compilation directive #ifdef Debug and #endif the printf function to include, compile the time with the-ddebug parameter can see debugging information. Conversely, do not add this parameter to debug it can.

2) debugging with GDB, where it runs to the wrong segment, it automatically stops and displays the line and line number of the error
This should be very common, if you need to debug with GDB, remember in the compile time with the-G parameter, used to display debugging information, for this, the user in the "Paragraph Error bug debugging" Article creative use of such methods, This allows us to dynamically capture the possible location of a segment error when executing a program: The SIGSEGV signal is used to trigger the system call GDB to output debug information. If we add the above-mentioned conditional compilation, then we can make the debugging of the section error very convenient.

3) There is also a CATCHSEGV command
By looking at the Help information, you can see
Catch segmentation faults in programs

This thing is used to catch a segment error, it is loaded with a pre-written library (/lib/libsegfault.so) through the dynamic loader (ld-linux.so) preload mechanism (preload), which captures error messages for broken errors.
Here, the "primary summary" is almost complete pull. Welcome to the point where the expression of improper or even wrong place, first thanked!


References [specific address in the above article has been given pull]:
1. Definition of segment Error
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's 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 section Error bugs
http://www.cublog.cn/u/5251/showart.php?id=173718

Postscript
Although the feeling did not write anything, but including looking for information and typing, but also spent a few hours, but summed up is also worth it, welcome to communicate and discuss with me, but also welcome to the article to express improper or even wrong place to correct.

c&c++--Segment Error (segmentation fault)

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.