Debug method for segment error (segmentation fault) under Linux

Source: Internet
Author: User
Tags signal handler strlen

When we write programs in C/s + + language, most of the memory management work needs us to do. In fact, memory management is a relatively tedious task, no matter how smart you are, the experience is rich, will inevitably make small mistakes here, and often these errors are so simple and easy to eliminate. But manual "Bug-Removing" (debug) is often inefficient and annoying, and this article will talk about how to quickly locate these "segment errors" in the Error "segment error", a memory access violation.     Here are a few of the debugging methods described below for a program that has a segment error: 1 dummy_function (void) 2 {3 unsigned char *ptr = 0x00;     4 *ptr = 0x00;    5} 6 7 int main (void) 8 {9 dummy_function ();    0 return; 12} as a skilled C + + programmer, the above code bug should be very clear, because it is trying to manipulate the memory area of the address 0, and this memory area is usually inaccessible to the restricted area, of course, there will be an error. We tried to compile and run it: [email protected] Test $. The/a.out segment error was expected, it went wrong and exited. 1. Use GDB to step through the segment error: This method is also known to the general public and widely used methods, first we need a debugging information with the executable program, so we add "-g-rdynamic" parameters to compile, and then use GDB debugging to run the newly compiled program, the following steps: [email protected] Test $ gcc-g-rdynamic d.c[email protected] Test $ gdb./a.outgnu gdb 6.5Copyright (c) 2006 F  Ree software Foundation, inc.gdb is free software, covered by the GNU general public License, and your arewelcome 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 is configured as "I686-pc-linux-gnu" ... Using host libthread_db Library "/lib/libthread_db.so.1". (GDB) rstarting program:/home/xiaosuo/test/a.outprogram received signal SIGSEGV, segmentation fault.0x08048524 in dummy _function () at d.c:44 *ptr = 0x00; (gdb) Oh?! It doesn't seem like we're going to need to debug. The 4th line of the D.C file is actually so simple. From here we also find that the process is ended by receiving a SIGSEGV signal. With further documentation (man 7 signal), we know that the SIGSEGV default handler action is to print "segment error" error message and produce a core file, thus we have another method two. 2. Analyzing the core file: What is the core file? The default action of certain signals is to cause a process to terminate and produce a core dump file, a disk file Contai  Ning 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). Oddly enough, I didn't find the core file on my system. Later, recalled in order to reduce the system on the number of pull rubbish files (I am a bit neat, this is one of the reasons I like Gentoo), prohibit the creation of core files, see the following is true, the size of the system's core file is limited to 512K size, and then try: [Email protected] Test $ ulimit-c0[email protected] test $ ulimit-c 1000[email protected] Test $ ulimit-c 1000[email protected] Test $./a.out Segment Error (core dumped) [email protected] test $ lsa.out Core D.C F.C G.c Pang  O.C test_iconv.c Test_regex.ccore File finally produced, debug with GDB to see it: [email protected] Test $ gdb./a.out Coregnu gdb 6.5Copyright (C) 2006 free software Foundation, inc.gdb are free software, covered by the GNU general public License, and you arewelcom E 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 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.6reading symbols from/lib/ld-linux.so.2...done. Loaded symbols For/lib/ld-linux.so.2core was Generated by './a.out '. Program terminated with signal one, segmentation fault. #0 0x08048524 in Dummy_function () at d.c:44 *ptr = 0 x00; Wow, good calendar harm, or a step to locate the wrong location, admire the Linux/unix system of this kind of design. Then consider, before using the Windows system of IE, sometimes open some Web pages, there will be "runtime error", this time if it happens to your machine is also installed on the Windows compiler, he will pop up a dialog box, ask you whether to debug, if you choose Yes, The compiler will be opened and put into the debug state to start debugging. How do you do this under Linux? My brain was spinning so fast that, having it call GDB in SIGSEGV's handler, the third method was born: 3. Start debugging on Segment error: #include <stdio.h> #include <stdlib.h>#        Include <signal.h> #include <string.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] = = ' \ n ') Buf[strlen (BUF)-1] = ' + ';        snprintf (cmd, sizeof (CMD), "GdB%s%d", buf, Getpid ());        System (CMD);        Exit (0);} Voiddummy_function (void) {unsigned char *ptr = 0x00;        *ptr = 0x00;}        Intmain (void) {signal (SIGSEGV, &dump);        Dummy_function (); return 0;} The compile run effect is as follows: [email protected] Test $ gcc-g-rdynamic f.c[email protected] Test $./a.outgnu gdb 6.5Copyright (c) 2 006 Free Software Foundation, inc.gdb are free software, covered by the GNU general public License, and your arewelcome to C Hange 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 9563Reading symbols from/lib/libc.so.6...done. Loaded symbols for/lib/libc.so.6reading symbols from/lib/ld-linux.so.2...done. Loaded symbols for/lib/ld-linux.so.20xffffe410 in __kernel_vsyscall () (GDB) bt#0 0xffffe410 in __kernel_vsyscall () #1 0 xb7eE4b53 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_function () at F.c:31#6 0x08048886 in Main () at F.c:3 How about 8? Isn't it still cool? The above methods are in the system on the premise of GDB, if not? In fact, GLIBC provides us with this kind of function to dump the contents of the cluster, see/usr/include/execinfo.h (These functions do not provide a man page, no wonder we can't find), you can also learn through the GNU manual. 4. Analyze with BackTrace and objdump: Rewrite the code as follows: #include <execinfo.h> #include <stdio.h> #include <stdlib.h>#        Include <signal.h> voiddummy_function (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 frames.\n", size);        for (i = 0; i < size; i++) printf ("%s\n", Strings[i]);        Free (strings);        Exit (0);} Intmain (void) {        Signal (SIGSEGV, &dump);        Dummy_function (); return 0;} The results of the compilation run are as follows: [email protected] Test $ gcc-g-rdynamic g.c[email protected] Test $./a.outobtained 5 Stack frames. /a.out (dump+0x19) [0x80486c2][0xffffe420]./a.out (MAIN+0X35) [0x804876f]/lib/libc.so.6 (__libc_start_main+0xe6) [ 0xb7e02866]./a.out [0x8048601] This time you may be a little disappointed, do not seem to give enough information to mark the error, not urgent, first see what can be analyzed, with the Objdump disassembly program, find the address 0x804876f corresponding code location: [ Email protected] Test $ objdump-d a.out 8048765:e8 the FE FF FF call 804856c <[email protec          ted]> 804876A:E8 FF FF FF call 8048694 <dummy_function> 804876f:b8 00 00 00 00 mov $0x0,%eax 8048774:c9 leave we still found out in which function (dummy_function) error, the information is not very complete, but there is always better than nothing! PostScript: the This paper gives some methods to analyze "segment error", do not think this is the same as Mr. Kong Yiji's "back" word four, because each method has its own scope of application and applicable environment, please use as appropriate, or as directed by the Doctor. Note: A segment error occurs when you print a number but with%s.

  

Debug method for segment error (segmentation fault) under Linux

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.