Ошибка сегментирования core dumped

Не всегда программы в Linux запускаются как положено. Иногда, в силу разных причин программа вместо нормальной работы выдает ошибку. Но нам не нужна

Не всегда программы в Linux запускаются как положено. Иногда, в силу разных причин программа вместо нормальной работы выдает ошибку. Но нам не нужна ошибка, нам нужна программа, вернее, та функция, которую она должна выполнять. Сегодня мы поговорим об одной из самых серьезных и непонятных ошибок. Это ошибка сегментации Ubuntu. Если такая ошибка происходит только один раз, то на нее можно не обращать внимания, но если это регулярное явление нужно что-то делать.

Конечно, случается эта проблема не только в Ubuntu, а во всех Linux дистрибутивах, поэтому наша инструкция будет актуальна для них тоже. Но сосредоточимся мы в основном на Ubuntu. Рассмотрим что такое ошибка сегментирования linux, почему она возникает, а также как с этим бороться и что делать.

Что такое ошибка сегментации?

Ошибка сегментации, Segmentation fault, или Segfault, или SIGSEGV в Ubuntu и других Unix подобных дистрибутивах, означает ошибку работы с памятью. Когда вы получаете эту ошибку, это значит, что срабатывает системный механизм защиты памяти, потому что программа попыталась получить доступ или записать данные в ту часть памяти, к которой у нее нет прав обращаться.

Чтобы понять почему так происходит, давайте рассмотрим как устроена работа с памятью в Linux, я попытаюсь все упростить, но приблизительно так оно и работает.

Допустим, в вашей системе есть 6 Гигабайт оперативной памяти, каждой программе нужно выделить определенную область, куда будет записана она сама, ее данные и новые данные, которые она будет создавать. Чтобы дать возможность каждой из запущенных программ использовать все шесть гигабайт памяти был придуман механизм виртуального адресного пространства. Создается виртуальное пространство очень большого размера, а из него уже выделяется по 6 Гб для каждой программы. Если интересно, это адресное пространство можно найти в файле /proc/kcore, только не вздумайте никуда его копировать.

Выделенное адресное пространство для программы называется сегментом. Как только программа попытается записать или прочитать данные не из своего сегмента, ядро отправит ей сигнал SIGSEGV и программа завершится с нашей ошибкой. Более того, каждый сегмент поделен на секции, в некоторые из них запись невозможна, другие нельзя выполнять, если программа и тут попытается сделать что-то запрещенное, мы опять получим ошибку сегментации Ubuntu.

Почему возникает ошибка сегментации?

И зачем бы это порядочной программе лезть, куда ей не положено? Да в принципе, незачем. Это происходит из-за ошибки при написании программ или несовместимых версиях библиотек и ПО. Часто эта ошибка встречается в программах на Си или C++. В этом языке программисты могут вручную работать с памятью, а язык со своей стороны не контролирует, чтобы они это делали правильно, поэтому одно неверное обращение к памяти может обрушить программу.

Почему может возникать эта ошибка при несовместимости библиотек? По той же причине — неверному обращению к памяти. Представим, что у нас есть библиотека linux (набор функций), в которой есть функция, которая выполняет определенную задачу. Для работы нашей функции нужны данные, поэтому при вызове ей нужно передать строку. Наша старая версия библиотеки ожидает, что длина строки будет до 256 символов. Но программа была обновлена формат записи поменялся, и теперь она передает библиотеке строку размером 512 символов. Если обновить программу, но оставить старую версию библиотеки, то при передаче такой строки 256 символов запишутся нормально в подготовленное место, а вот вторые 256 перезапишут данные программы, и возможно, попытаются выйти за пределы сегмента, тогда и будет ошибка сегментирования linux.

Что делать если возникла ошибка сегментирования?

Если вы думаете, что это ошибка в программе, то вам остается только отправить отчет об ошибке разработчикам. Но вы все-таки еще можете попытаться что-то сделать.

Например, если падает с ошибкой сегментации неизвестная программа, то мы можем решить что это вина разработчиков, но если с такой ошибкой падает chrome или firefox при запуске возникает вопрос, может мы делаем что-то не так? Ведь это уже хорошо протестированные программы.

Первое, что нужно сделать — это обновить систему до самой последней версии, возможно, был баг и его уже исправили, а может у вас установлены старые версии библиотек и обновление решит проблему. В Ubuntu это делается так:

sudo apt update
sudo apt full-upgrade

Если это не помогло, нужно обнулить настройки программы до значений по умолчанию, возможно, удалить кэш. Настройки программ в Linux обычно содержатся в домашней папке, скрытых подкаталогах с именем программы. Также, настройки и кэш могут содержаться в каталогах ~/.config и ~/.cache. Просто удалите папки программы и попробуйте снова ее запустить. Если и это не помогло, вы можете попробовать полностью удалить программу, а потом снова ее установить, возможно, какие-нибудь зависимости были повреждены:

sudo apt remove пакет_программы
sudo apt autoremove
sudo apt install пакет_программы

Если есть возможность, попробуйте установить программу из другого источника, например, не из PPA, а более старую версию, из официальных репозиториев.

Когда вы все это выполнили, скорее всего, проблема не в вашем дистрибутиве, а в самой программе. Нужно отправлять отчет разработчикам. В Ubuntu это можно сделать с помощью программы apport-bug. Обычно Ubuntu предлагает это сделать сразу, после того как программа завершилась с ошибкой сегментирования. Если же ошибка сегментирования Ubuntu встречается не в системной программе, то вам придется самим искать разработчиков и вручную описывать что произошло.

Чтобы помочь разработчикам решить проблему, недостаточно отправить им только сообщение что вы поймали Segmentation Fault, нужно подробно описать проблему, действия, которые вы выполняли перед этим, так чтобы разработчик мог их воспроизвести. Также, желательно прикрепить к отчету последние функции, которые вызывала программа (стек вызовов функций), это может очень сильно помочь разработчикам.

Рассмотрим, как его получить. Это не так уж сложно. Сначала запустите вашу программу, затем узнайте ее PID с помощью команды:

pgrep программа

Дальше запускаем отладчик gdb:

sudo gdb -q

Подключаемся к программе:

(gdb) attach ваш_pid

После подключения программа станет на паузу, продолжаем ее выполнение командой:

(gdb) continue

segfault

Затем вам осталось только вызвать ошибку:

segfault1

И набрать команду, которая выведет стек последних вызовов:

(gdb) backtrace

Вывод этой команды и нужно отправлять разработчикам. Чтобы отключиться от программы и выйти наберите:

(gdb) detach
(gdb) quit

Дальше остается отправить отчет и ждать исправления ошибки. Если вы не уверены, что ошибка в программе, можете поспрашивать на форумах. Когда у вас есть стек вызовов, уже можно попытаться, если не понять в чем проблема, то попытаться узнать, не сталкивался ли с подобной проблемой еще кто-то.

Выводы

Теперь у вас есть приблизительный план действий, что нужно делать, когда появляется ошибка сегментирования сделан дамп памяти ubuntu. Если вы знаете другие способы решить эту проблему, напишите в комментариях!

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

A segmentation fault (sometimes known as a segfault) happens when your program tries to access memory that it is not permitted to access.In other words, when your program attempts to access memory that exceeds the boundaries set by the operating system for your program.And it is a common circumstance that causes programs to crash; it is frequently related with a file called core.

Program memory is divided into different segments:

  • a text segment for program instructions
  • a data segment for variables and arrays defined at compile time
  • a stack segment for temporary (or automatic) variables defined in subroutines and functions
  • a heap segment for variables allocated during runtime by functions, such as malloc (in C) and allocate (in Fortran).

When a reference to a variable falls beyond the segment where that variable exists, or when a write is attempted to a place that is in a read-only segment, a segfault occurs. In reality, segfaults are nearly typically caused by attempting to read or write a non-existent array member, failing to correctly define a pointer before using it, or (in C applications) inadvertently using the value of a variable as an address (see the scan example below).

*Calling memset(), for example, would cause a program to segfault:

memset((char *)0x0, 1, 100);

*The three examples below show the most frequent sorts of array-related segfaults:

Case A

/* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */
int foo[1000]; for (int i = 0; i <= 1000 ; i++) foo[i] = i;

Case B

/* Illegal memory access if value of n is not in the range 0, 1, ... 999 */ 
int n; int foo[1000]; for (int i = 0; i < n ; i++) foo[i] = i;

Case C

/* Illegal memory access because no memory is allocated for foo2 */
float *foo, *foo2; foo = (float*)malloc(1000); foo2[0] = 1.0;
  • In case A, array foo is defined for index = 0, 1, 2, … 999. However, in the last iteration of the for loop, the program tries to access foo[1000]. This will result in a segfault if that memory location lies outside the memory segment where foo resides. Even if it doesn’t cause a segfault, it is still a bug.
  • In case B, integer n could be any random value. As in case A, if it is not in the range 0, 1, … 999, it might cause a segfault. Whether it does or not, it is certainly a bug.
  • In case C, allocation of memory for variable foo2 has been overlooked, so foo2 will point to a random location in memory. Accessing foo2[0] will likely result in a segfault.

*Another typical programming issue that causes segfaults is a failure to use pointers properly. The C function scanf(), for example, requires the address of a variable as its second parameter; hence, the following will very certainly cause the program to fail with a segfault:

int foo = 0; scanf("%d", foo); 
/* Note missing & sign ; correct usage would have been &foo */

Although the variable foo may be created at memory position 1000, the preceding function call would attempt to read integer values into memory location 0 in accordance with the definition of foo.

A segfault occurs when a software attempts to operate on a memory region in an unauthorized manner (for example, attempts to write a read-only location would result in a segfault).When your application runs out of stack space, segfaults can occur. This might be due to your shell setting the stack size limit too low, rather than a fault in your software.

Dangling Pointers point to something that no longer exists.
A dangling pointer is an example of this.

char *ptr = NULL;
{
char c;
ptr = &c; //After the block is over, ptr will be a dangling pointer.
}

When the block concludes, the scope of variable c expires. Because it now points to something that doesn’t exist, the ‘ptr’ will become a dangling pointer.

But when you try to access memory that doesn’t belong to you or when you try to write to a read-only area, you get a segmentation fault.

char *str ="Testing Seg fault.";
*str= "I hate Seg fault :( ";

The’str’ will be made a constant by the compiler. You are altering the read-only part when you try to update the value, resulting in a segmentation fault.So there’s a clear distinction between a segmentation fault and dangling pointers.

A segmentation fault (sometimes known as a segfault) happens when your program tries to access memory that it is not permitted to access.In other words, when your program attempts to access memory that exceeds the boundaries set by the operating system for your program.And it is a common circumstance that causes programs to crash; it is frequently related with a file called core.

Program memory is divided into different segments:

  • a text segment for program instructions
  • a data segment for variables and arrays defined at compile time
  • a stack segment for temporary (or automatic) variables defined in subroutines and functions
  • a heap segment for variables allocated during runtime by functions, such as malloc (in C) and allocate (in Fortran).

When a reference to a variable falls beyond the segment where that variable exists, or when a write is attempted to a place that is in a read-only segment, a segfault occurs. In reality, segfaults are nearly typically caused by attempting to read or write a non-existent array member, failing to correctly define a pointer before using it, or (in C applications) inadvertently using the value of a variable as an address (see the scan example below).

*Calling memset(), for example, would cause a program to segfault:

memset((char *)0x0, 1, 100);

*The three examples below show the most frequent sorts of array-related segfaults:

Case A

/* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */
int foo[1000]; for (int i = 0; i <= 1000 ; i++) foo[i] = i;

Case B

/* Illegal memory access if value of n is not in the range 0, 1, ... 999 */ 
int n; int foo[1000]; for (int i = 0; i < n ; i++) foo[i] = i;

Case C

/* Illegal memory access because no memory is allocated for foo2 */
float *foo, *foo2; foo = (float*)malloc(1000); foo2[0] = 1.0;
  • In case A, array foo is defined for index = 0, 1, 2, … 999. However, in the last iteration of the for loop, the program tries to access foo[1000]. This will result in a segfault if that memory location lies outside the memory segment where foo resides. Even if it doesn’t cause a segfault, it is still a bug.
  • In case B, integer n could be any random value. As in case A, if it is not in the range 0, 1, … 999, it might cause a segfault. Whether it does or not, it is certainly a bug.
  • In case C, allocation of memory for variable foo2 has been overlooked, so foo2 will point to a random location in memory. Accessing foo2[0] will likely result in a segfault.

*Another typical programming issue that causes segfaults is a failure to use pointers properly. The C function scanf(), for example, requires the address of a variable as its second parameter; hence, the following will very certainly cause the program to fail with a segfault:

int foo = 0; scanf("%d", foo); 
/* Note missing & sign ; correct usage would have been &foo */

Although the variable foo may be created at memory position 1000, the preceding function call would attempt to read integer values into memory location 0 in accordance with the definition of foo.

A segfault occurs when a software attempts to operate on a memory region in an unauthorized manner (for example, attempts to write a read-only location would result in a segfault).When your application runs out of stack space, segfaults can occur. This might be due to your shell setting the stack size limit too low, rather than a fault in your software.

Dangling Pointers point to something that no longer exists.
A dangling pointer is an example of this.

char *ptr = NULL;
{
char c;
ptr = &c; //After the block is over, ptr will be a dangling pointer.
}

When the block concludes, the scope of variable c expires. Because it now points to something that doesn’t exist, the ‘ptr’ will become a dangling pointer.

But when you try to access memory that doesn’t belong to you or when you try to write to a read-only area, you get a segmentation fault.

char *str ="Testing Seg fault.";
*str= "I hate Seg fault :( ";

The’str’ will be made a constant by the compiler. You are altering the read-only part when you try to update the value, resulting in a segmentation fault.So there’s a clear distinction between a segmentation fault and dangling pointers.

The core file is normally called core and is located in the current working directory of the process. However, there is a long list of reasons why a core file would not be generated, and it may be located somewhere else entirely, under a different name. See the core.5 man page for details:

DESCRIPTION

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. This image
can be used in a debugger (e.g., gdb(1)) to inspect the state of the
program at the time that it terminated.
A list of the signals which
cause a process to dump core can be found in signal(7).

There are various circumstances in which a core dump file is not produced:

   *  The process does not have permission to write the core file.  (By
      default, the core file is called core or core.pid, where pid is
      the ID of the process that dumped core, and is created in the
      current working directory.  See below for details on naming.) 
      Writing the core file will fail if the directory in which it is to
      be created is nonwritable, or if a file with the same name exists
      and is not writable or is not a regular file (e.g., it is a
      directory or a symbolic link).
   *  A (writable, regular) file with the same name as would be used for
      the core dump already exists, but there is more than one hard link
      to that file.
   *  The filesystem where the core dump file would be created is full;
      or has run out of inodes; or is mounted read-only; or the user has
      reached their quota for the filesystem.
   *  The directory in which the core dump file is to be created does
      not exist.
   *  The RLIMIT_CORE (core file size) or RLIMIT_FSIZE (file size)
      resource limits for the process are set to zero; see getrlimit(2)
      and the documentation of the shell's ulimit command (limit in
      csh(1)).
   *  The binary being executed by the process does not have read
      permission enabled.
   *  The process is executing a set-user-ID (set-group-ID) program that
      is owned by a user (group) other than the real user (group) ID of
      the process, or the process is executing a program that has file
      capabilities (see capabilities(7)).  (However, see the description
      of the prctl(2) PR_SET_DUMPABLE operation, and the description of
      the /proc/sys/fs/suid_dumpable file in proc(5).)
   *  (Since Linux 3.7) The kernel was configured without the
      CONFIG_COREDUMP option.

In addition, a core dump may exclude part of the address space of the
process if the madvise(2) MADV_DONTDUMP flag was employed.

Naming of core dump files

By default, a core dump file is named core, but the
/proc/sys/kernel/core_pattern file (since Linux 2.6 and 2.4.21) can
be set to define a template that is used to name core dump files.
The template can contain % specifiers which are substituted by the
following values when a core file is created:

       %%  a single % character
       %c  core file size soft resource limit of crashing process (since
           Linux 2.6.24)
       %d  dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE
           (since Linux 3.7)
       %e  executable filename (without path prefix)
       %E  pathname of executable, with slashes ('/') replaced by
           exclamation marks ('!') (since Linux 3.0).
       %g  (numeric) real GID of dumped process
       %h  hostname (same as nodename returned by uname(2))
       %i  TID of thread that triggered core dump, as seen in the PID
           namespace in which the thread resides (since Linux 3.18)
       %I  TID of thread that triggered core dump, as seen in the
           initial PID namespace (since Linux 3.18)
       %p  PID of dumped process, as seen in the PID namespace in which
           the process resides
       %P  PID of dumped process, as seen in the initial PID namespace
           (since Linux 3.12)
       %s  number of signal causing dump
       %t  time of dump, expressed as seconds since the Epoch,
           1970-01-01 00:00:00 +0000 (UTC)
       %u  (numeric) real UID of dumped process

What does it mean?

See AU: What is a segmentation fault? post and also this post which have some examples how reproduce it, SO: What is segmentation fault?.

The simplest description I can come with (may be not the perfect):

The program tried to access a memory area out side its own section. Operating system blocks it.

Some cases: Reading value with uninitialized pointer, Going out of range in an array, Function call (when backward compatibility not maintained), …

However, it is not always easy find the cause with large programs or those which relay on other project lib’s. And most of the cases end up with a bug report, either for target program or one of its dependencies (either upstream project or downstream distribution package).

How can I resolve this issue?

  • Fire a bug report

    If you didn’t make any custom configuration/setup and you all updates installed. fire a bug report, see How do I report a bug?

    If open source supported by Ubuntu use ubuntu-bug (apport-bug). For 3rd party closed source, check their help pages how to report bugs and collect related data.

  • Take initiative to debug

    If you you have even a little programming background, it is recommended that you try your best to resolve it yourself. There many bug reports out there inactive for years. At least, you may be able to collect enough debug data that help resolve the issue when reporting it.

    That’s means that you are breaking the user abstraction level and opening the black box! (FLOSS actually has transparent box).

Some Useful Tools for Debugging

Some … I mean there are many other useful tools out there that you gonna find when you dig in more.

  1. apport-bug logs / core dump / backtrace

    If you don’t have an error message before segmentation fault. Run it with --save option and look for back-trace log:

    apport-bug program-cmd --save bug-report_output.txt
    
  2. gdb backtrace / debuging source code

    If it didn’t work, use gdb:

    $ gdb program-cmd
    (gdb) run
    (gdb) backtrace
    

    If you get any error message, check the web, launchpad and in upstream project bug tracker if there any similar cases.

    For some advanced users or who are following a c/c++ learning path, they could download the corresponding -dbg symbols packages. Then you can use gdb to trace program flow through the source and get the exact function/instruction that raise the runtime error.

    For Ubuntu(Debian) based distributions, source code of a package can be downloaded using:

    apt-get source <package-name>
    
  3. strace system call tracing

    Another tool that may help is strace, I like it. It’s really a powerful tool.

    It presents itself:

    In the simplest case strace runs the specified command until it exits. It intercepts and records the system calls which are called by a
    process and the signals which are received by a process. The name of each system call, its arguments and its return value are printed on
    standard error or to the file specified with the -o option.

    strace is a useful diagnostic, instructional, and debugging tool. System administrators, diagnosticians and trouble-shooters will find it
    invaluable for solving problems with programs for which the source is not readily available since they do not need to be recompiled in
    order to trace them. Students, hackers and the overly-curious will find that a great deal can be learned about a system and its system
    calls by tracing even ordinary programs. And programmers will find that since system calls and signals are events that happen at the
    user/kernel interface, a close examination of this boundary is very useful for bug isolation, sanity checking and attempting to capture
    race conditions.

    Source: man strace

  4. ltrace dynamic library call tracing

    ltrace is a program that simply runs the specified command until
    it
    exits. It intercepts and records the dynamic library calls which are
    called by the executed process and the signals which are received by
    that process. It can also intercept and print the system calls exe‐
    cuted by the program.

    Its use is very similar to strace(1).

    Source: man ltrace

Understanding and solving errors are essential skills for any Linux administrator. The most common errors you will get are: “no such file or directory found” or “unable to access or permission denied”. If you are a Linux administrator, it is mandatory to know how to detect and solve segmentation faults. In this article, we will explain what segmentation fault is, what causes them, and how to detect or troubleshoot them. So let’s get started.

What Is a Segmentation Fault?

A segmentation fault is nothing but the error that occurs due to failed attempts to access Linux OS’s memory regions. These types of faults are detected by the kernel. Once detected, the process is immediately terminated, and a “segmentation violation signal” or “segmentation fault” is issued. 

We can find most segmentation faults in lower-level languages like C (the most commonly used/ fundamental language in both LINUX and UNIX). It allows a great deal on memory allocation and usage. Hence, developers can have full control over the memory allocation. 

What Causes a Segmentation Fault? 

In the Linux or kernel operating system, the following are the conditions that cause a segmentation fault:

  • Segmentation Violation Mapping Error (SEGV_MAPERR): This is the error that occurs when you want to access memory outside the application that requires an address space. 
  • Segmentation Violation Access Error (SEGV_ACCERR): This is the error that occurs when you want to access memory where the application does not have permission or write source codes on read-only memory space.

Sometimes we assume that these two conditions cause major problems, but that’s not always true. There might be chances of getting errors through referencing NULL values, freed pointers available for the reference memory areas, non-initialized parameters, and StackOverflow.

Examples That Generate Segmentation Faults in Linux

Here, we are going to explain a few code snippets that generate the segmentation default in Linux:

void main (void) {
   char *buffer;  /* Non initialized buffer */
   buffer[0] = 0; /* Trying to assign 0 to its first position will cause a segmentation fault */
}

We can now run and compile them on Linux kernel as follows:

$ gcc -o seg_fault -ggdb seg_fault.c

Output:

Segmentation fault (core dumped)

In the above example, ulimit dumps the process memory on errors, and the compiling done with the help of GCC or -ggtb options, adds debug information on the resulting binary.

In addition, we can also enable get debug information and core dumping where the error occurred as shown in the below example:

$ gdb ./seg_fault /var/crash/core.seg_fault

Output:

... <snip> ...
Reading symbols from ./seg_fault...
[New LWP 6291]
Core was generated by `./seg_fault'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055ea4064c135 in main () at seg_fault.c:4
4               buffer[0] = 0;

Note: However, if you don’t have to debug information, you can still identify the errors with the help of the name of the function, and values where we are getting errors.

How to Detect a Segmentation Fault

Till now, we have seen a few examples where we get errors. In this section, we will explain how to diagnose/detect the segmentation fault.

Using a debugger, you might detect segmentation faults. There are various kinds of debuggers available, but the most often used debuggers are GDB or -ggtb. GDB is a well-known GNU debugger that helps us view the backtrace of the core file, which is dumped by the program. 

Whenever a segmentation fault occurs in the program, it usually dumps the memory content at the time of the core file crash process. Start your debugger, GDB, with the “gdb core” command. Then, use the “backtrace” command to check for the program crash. 

If you are unable to detect the segmentation fault using the above solution, try to run your program under “debugger” control. Then, go through the source code, one code line or one code function at a time. To perform this task, all you need to do is compile your program codes without optimization, and use the “-g” flag to find out the errors. 

Let us explain the simple steps required to identify segFault inside GDB:

  1. Make sure you have enabled the debugger mode (-g flag should also be a part of the GCC line). It looks like this:

gcc -g -o segfault segfault.c

  1. Then load the file into the gdb format:

  1. For the sample code, use this navigation to identify the codes that cause SegFault:

  1. Then, run your program: Starting program: /home/pi/segfault

program received signal SIGSEGV, Segmentation fault.

The following image illustrates the above steps:

Identify segFault inside GDB illustration

How to Prevent Segmentation Faults in Linux?

When you write a program using pointers, memory allocators, or references, make sure that all the memory accessories are within the boundary and compile with proper access restrictions. 

The below are the important things which you should take care of them to avoid segmentation faults:

  • Using gdb debugger to track the source of the problem while using dynamic memory location.
  • Make sure that you have installed or configured the correct hardware or software components.
  • Maintaining type consistency throughout the program code and the function parameters that call convention values will reduce the Segfault.
  • Always make sure that all operating system dependencies are installed inside the jail.
  • Stop using conditional statements in recursive functions.
  • Turn on the core dumping support services (especially Apache) to prevent the segmentation fault in the Linux program.

These tips are very important as they improve code robustness and security services. 

Final Take

If you are a Linux developer, you might have gone through the segmentation fault scenarios many times. In this post, we have tried to brief you about SegFault, given real-time examples, explained the causes for the SegFault, and discussed how to detect and prevent segmentation faults. 

We hope this blog may help a few Linux communities, Linux administrators, and Linux experts worldwide who want to master the core concepts of the Linux kernel system. 

Fault (technology)
Linux kernel
Segmentation fault
Memory (storage engine)
shell
operating system

Opinions expressed by DZone contributors are their own.

Improve Article

Save Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Core Dump/Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.” 
     

    • When a piece of code tries to do read and write operation in a read only location in memory or freed block of memory, it is known as core dump.
    • It is an error indicating memory corruption.

    Common segmentation fault scenarios: 
     

    • Modifying a string literal : 
      The below program may crash (gives segmentation fault error) because the line *(str+1) = ‘n’ tries to write a read only memory. 
       

    C++

    #include <iostream>

    using namespace std;

    int main()

    {

       char *str;

       str = "GfG";    

       *(str + 1) = 'n';

       return 0;

    }

    C

    int main()

    {

       char *str;

       str = "GfG";    

       *(str+1) = 'n';

       return 0;

    }

    Abnormal termination of program.

    Refer Storage for Strings in C for details 
     

    • Accessing an address that is freed : 
      Here in the below code, the pointer p is dereferenced after freeing the memory block, which is not allowed by the compiler. So it produces the error segment fault or abnormal program termination at runtime. 
      Example: 
       

    C++

    #include <iostream>

    using namespace std;

    int main(void)

    {

        int* p = (int*) malloc(8*sizeof(int));

        *p = 100;

        free(p);

        *p = 110;

        return 0;

    }

    C

    #include <stdio.h>

    #include<alloc.h>

    int main(void)

    {

        int* p = malloc(8);

        *p = 100;

        free(p);

        *p = 110;

        return 0;

    }

    Output: 
     

    Abnormal termination of program.
    • Accessing out of array index bounds : 
       

    CPP

    #include <iostream>

    using namespace std;

    int main()

    {

       int arr[2];

       arr[3] = 10; 

       return 0;

    }

    C

    #include <stdio.h>

    int main(void)

    {

       int arr[2];

       arr[3] = 10; 

       return (0);

    }

    Output: 
     

    Abnormal termination of program.
    • Improper use of scanf() : 
      scanf() function expects address of a variable as an input. Here in this program n takes 
      value of 2 and assume it’s address as 1000. If we pass n to scanf(), input fetched from STDIN is placed in invalid memory 2 which should be 1000 instead. It’s a memory corruption leading to Segmentation fault. 
       

    C++

    #include <iostream>

    using namespace std;

    int main()

    {

       int n = 2;

       cin >> " " >> n;

       return 0;

    }

    C

    #include <stdio.h>

    int main()

    {

       int n = 2;

       scanf(" ",n);

       return 0;

    }

    Output: 
     

    Abnormal termination of program.
    • Stack Overflow 
      It’s not a pointer related problem even code may not have single pointer. It’s because of recursive function gets called repeatedly which eats up all the stack memory resulting in stack overflow. Running out of memory on the stack is also a type of memory corruption. It can be resolved by having a base condition to return from the recursive function.
       
    • Dereferencing uninitialized pointer 
      A pointer must point to valid memory before accessing it. 
       

    C++14

    #include <iostream>

    using namespace std;

    int main()

    {

        int* p;

        cout << *p;

        return 0;

    }

    C

    #include <stdio.h>

    int main()

    {

       int *p;

       printf("%d",*p);

       return 0;

    }

    This article is contributed by Bishal Kumar Dubey. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
    Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
     


    0

    4

    Здравствуйте.
    Система: CentOS 7 64x. При выполнении
    (gdb) bt full:

    #0  0x080e38f2 in _mm_set_epi32 ()
    No symbol table info available.
    #1  0xdfffffef in ?? ()
    No symbol table info available.
    #2  0xddfecb7f in ?? ()
    No symbol table info available.
    #3  0xbffaffff in ?? ()
    No symbol table info available.
    #4  0x08098331 in world_horse_initialize () at world_horse.c:318
            land_path = "../../data/horse/personality.csv", '00' <repeats 223 times>
            i = 0
    #5  0x08088662 in sv_initialize (max_world_num=100) at sv.c:167
    No locals.
    #6  0x080a39c6 in main_initialize () at main.c:158
    No locals.
    #7  0x080e68bc in svbase_initialize ()
    No symbol table info available.
    #8  0x080a36c7 in main (argc=1, argv=0xbffff754) at main.c:51
    No locals.
    

    (gdb) info frame

    Stack level 0, frame at 0xbfff29d8:
     eip = 0x80e38f2 in _mm_set_epi32; saved eip 0xdfffffef
     called by frame at 0xbfff29dc
     Arglist at 0xbfff29d0, args: 
     Locals at 0xbfff29d0, Previous frame's sp is 0xbfff29d8
     Saved registers:
      eip at 0xbfff29d4
    

    Если все правильно понимаю, то ошибка происходит при вызове метода _mm_set_epi32() который относится к Module x86intrin::sse2 — инструкции Intel. Могу быть не прав. При открытии бинарника в IDA был найден участок кода, который вызывает ошибку (1 строка):

    mm_set_epi32();
      _mm_store_si128((__m128i *)&v34, a1);
      mm_load_si128();
      _mm_store_si128((__m128i *)&v36, a1);
      mm_load_si128();
      _mm_store_si128((__m128i *)&v35, a1);
    

    Метод: int gen_rand_all(__m128i vallue) <- int gen_rand32(__m128i vallue).
    То есть, данная часть кода предназначена для генерации случайных Int значений посредством инструкций Intel (но снова, могу ошибаться). В поле flags информации о процессорах поддержка sse2 имеется. Без каких-либо вариантов в чем может быть проблема (грешу на библиотеки, т.к. приложении достаточно старое — 2008-2010 годов). Прошу помощи, если есть желающие, то дам удаленку, либо сам файл приложения для пробного запускаанализа, за результат само собой будет оплата.

    Понравилась статья? Поделить с друзьями:

    Читайте также:

  • Ошибка сегментации это
  • Ошибка сегментации debian
  • Ошибка се 34878 0 ps4 что делать
  • Ошибка се 34788 0 пс4
  • Ошибка сдс нужен сервис

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии