one, paragraph error 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 with 64 bits in one unit. In this table, you save the code snippet that the program runs and the starting address of the data segment, as well as information about the corresponding segment limit, the page exchange, the program run level, the granularity of the memory, and so on. Once a program has crossed access, the CPU will have the corresponding exception protection, so segmentation fault appeared. Second, the reasonThe following types of practices in programming tend to lead to segment errors, which are basically caused by using pointers incorrectly
1) access to the system data area, especially to system-protected memory address write data The most common is to give a pointer to 0 address
2) memory out of bounds (array out of bounds, variable type inconsistent, etc.) access to areas of memory that do not belong to you3) Other
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 Third, the solution
When we write programs in C/s + + language, most of the memory management work needs us to do.
How to quickly locate these "segment errors" statements/ * DUMMY.C
* Test for end error in memory area with access address 0
*/
#include <stdio.h>
void Dummy (void);
Int
Main (void)
{
Dummy ();
return 0;
}//main
void Dummy (void)
{
Access to memory area with address 0
unsigned char* pstr = 0x00;
*pstr = 0x00;
}An attempt was made to manipulate an area of memory where the address is 0, which is usually an inaccessible restricted area and an error occurred. Compile run:
$./a.out
Segment error,1. Use GDB to step through a segment error:
You need an executable program with debugging information, with the parameters of "-g-rdynamic" compiled, and then debug with GDB to run the newly compiled program, the following steps:
$ gcc-g-rdynamic D.C
$ gdb./a.out
GNU GDB 6.5
Copyright (C) 2006 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.
Type "Show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "Show warranty" for details.
This GDB is configured as "I686-pc-linux-gnu" ... Using host libthread_db Library "/lib/libthread_db.so.1".
(GDB) R
Starting program:/a.out
Program received signal SIGSEGV, segmentation fault.
0x08048524 in Dummy_ () at D.c:4
4 *ptr = 0x00;
(GDB)
The 4th line of the D.C file is found without the need for step-by-step debugging.
The discovery process was ended by receiving a SIGSEGV signal. Through further documentation (man 7 signal),
SIGSEGV default handler action is to print "segment error" error message, and produce a core file, resulting in method two. 2. Analyze the core file:
What is a core file? The default action of certain signals is to cause a process to terminate and produce a core dump file,
A disk file containing an image of the process's memory at the time of termination.
A list of the signals which cause a process to dump core can is found in signal (7). The above data is excerpted from man page (man 5 core). Sometimes in order to reduce the number of pull-rubbish files on the system, the creation of the core file is forbidden,
Limit the size of the system's core file to 512K size $ ulimit-c 0
$ ulimit-c 1000
$ ulimit-c 1000
$./a.out
Segment error (Core dumped)
$ ls
A.out Core D.C F.C g.c pango.c test_iconv.c test_regex.ccore file finally produced, GDB debugs: $ gdb./a.out Core
GNU GDB 6.5
Copyright (C) 2006 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.
Type "Show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "Show warranty" for details.
This GDB is configured as "I686-pc-linux-gnu" ... Using host libthread_db Library "/lib/libthread_db.so.1".
Warning:can ' t read pathname for LOAD map: input/Output error.
Reading symbols From/lib/libc.so.6...done.
Loaded symbols for/lib/libc.so.6
Reading symbols From/lib/ld-linux.so.2...done.
Loaded symbols for/lib/ld-linux.so.2
Core is generated by './a.out '.
Program terminated with signal one, segmentation fault.
#0 0x08048524 in Dummy_ () at D.c:4
4 *ptr = 0x00;windows system under the IE, sometimes open some Web pages, there will be "runtime error", this time if it happens that your machine is installed on the Windows compiler,
It will pop up a dialog box asking if you are debugging, if you choose Yes, the compiler will be opened and into the debug state to start debugging.
How do you do this under Linux? Let it call gdb in SIGSEGV's handler, and the third method was born: 3. Start debugging on Segment error: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
void dump (int signo)
{
Char buf[1024];
Char cmd[1024];
File* FH;
snprintf (buf, sizeof (BUF),
"/proc/%d/cmdline", Getpid ());
if (!FH = fopen (buf, "R"))
Exit (0);
if (!fgets (buf, sizeof (BUF), FH))
Exit (0);
Fclose (FH);
if (Buf[strlen (buf-1)] = ' + ')
Buf[strlen (BUF)-1] = ' + ';
snprintf (cmd, sizeof (CMD),
"GdB%s%d", buf, Getpid ());
System (CMD);
Exit (0);
}//dump
void
Dummy (void)
{
unsigned char* ptr = 0x00;
*ptr = 0x00;
}//dummy
Int
Main (void)
{
Signal (SIGSEGV, &dump);
Dummy ();
return 0;
}//main compile run effect as follows: $ gcc-g-rdynamic F.C
$./a.out
GNU GDB 6.5
Copyright (C) 2006 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.
Type "Show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "Show warranty" for details.
This GDB is configured as "I686-pc-linux-gnu" ... Using host libthread_db Library "/lib/libthread_db.so.1".
Attaching to Program:/home/xiaosuo/test/a.out, Process 9563
Reading symbols From/lib/libc.so.6...done.
Loaded symbols for/lib/libc.so.6
Reading symbols From/lib/ld-linux.so.2...done.
Loaded symbols for/lib/ld-linux.so.2
0xffffe410 in __kernel_vsyscall ()
(GDB) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7ee4b53 in Waitpid () from/lib/libc.so.6
#2 0xb7e925c9 in strtold_l () from/lib/libc.so.6
#3 0x08048830 in Dump (signo=11) at f.c:22
#4 <signal Handler Called>
#5 0x0804884c in Dummy_ () at f.c:31
#6 0x08048886 in Main () at f.c:38 above is done on the premise that there is gdb on the system, if not? In fact, GLIBC provides such a function cluster that can dump the contents of the stack,
See/usr/include/execinfo.h (These functions do not provide a man page, no wonder we can not find it), but also through the GNU manual to learn.
4. Analysis using BackTrace and Objdump:
The rewritten code is as follows:
#i nclude <execinfo.h>
#i nclude <stdio.h>
#i nclude <stdlib.h>
#i nclude <signal.h>
void
Dummy_ (void)
{
unsigned char *ptr = 0x00;
*ptr = 0x00;
}
void dump (int signo)
{
void *array[10];
size_t size;
Char **strings;
size_t i;
Size = BackTrace (array, 10);
strings = Backtrace_symbols (array, size);
printf ("obtained%ZD stack s.\n", size);
for (i = 0; i < size; i++)
printf ("%s\n", Strings[i]);
Free (strings);
Exit (0);
}
Int
Main (void)
{
Signal (SIGSEGV, &dump);
Dummy_ ();
return 0;
}
The results of the compilation run are as follows:
$ gcc-g-rdynamic g.c
$./a.out
Obtained 5 stack S.
./a.out (dump+0x19) [0X80486C2]
[0xffffe420]
./a.out (MAIN+0X35) [0x804876f]
/lib/libc.so.6 (__libc_start_main+0xe6) [0xb7e02866]
./a.out [0x8048601]
Using the Objdump disassembler, find the address 0x804876f corresponding code location:
$ objdump-d a.out
8048765:e8-FE FF FF call 804856c <[email protected]>
804876A:E8 FF FF call 8048694 <dummy_>
804876f:b8 xx xx $0x0,%eax
8048774:C9 Leav Original: http://tech.diannaodian.com/dw/lin/2012/0604/180621.html
Common Linux segment Errors and workarounds