Ошибка сегментирования стек памяти сброшен на диск ubuntu

Не всегда программы в 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. Если вы знаете другие способы решить эту проблему, напишите в комментариях!

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Creative Commons License

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

я написал вот такую программку:

//includes
#include <iostream>
#include <chrono>
#include <string>
#include <ctime>

//namespaces
using namespace std;
using namespace chrono;

//defines
#define RETURN return 0

//main
int main() {
    setlocale(LC_ALL,"ru"); //locale
    const auto _BEFORE_ = high_resolution_clock::now(); //start timer (for time account)
    srand(time(0));

    //Create Array
    int CountArrayIn_arr2D = 2;
    int CountElementsIn_arr1D = 3;
    int **arr2D = new int*[CountArrayIn_arr2D];

    //Generate Array
    for(int i = 0; i < CountArrayIn_arr2D; i++) {
        for(int j = 0; j < CountElementsIn_arr1D; j++) {
            arr2D[i][j] = rand() % 30 + 1;
        }
    }

    //Print Array
    for(int i = 0; i < CountArrayIn_arr2D; i++) {
        for(int j = 0; j < CountElementsIn_arr1D; j++) {
            cout<<"33[34m"<<arr2D[i][j]<<"33[0mt";
        }
        cout<<endl;
    }


    /*Clean memory*/
    for(int i = 0; i < CountArrayIn_arr2D; i++) {
        delete[] arr2D[i];
    }
    delete[] arr2D;

    //time account
    const auto _AFTER_ = high_resolution_clock::now();
    const float TIME_FOR_PROGRAM = duration_cast<milliseconds>(_AFTER_-_BEFORE_).count();
    cout<<"nn Programm completed in "<<TIME_FOR_PROGRAM<<"ms"<<endl;
    RETURN;
}

и пишет: запуск программы(не компиляция, а запуск) на Ubuntu

у меня 2 вопроса.
1) что значит стек сброшен на диск? на жесткий диск? удалится ли он самостоятельно? если нет то как удалить?
2) как это решить и почему это вообще произошло?

задан 29 окт 2019 в 14:44

Данил Перелыгин's user avatar

Данил ПерелыгинДанил Перелыгин

1301 золотой знак1 серебряный знак8 бронзовых знаков

2

«Стек памяти сброшен на диск» — это [весьма-а вольный] перевод фразы «Core dumped». На диске в текущем каталоге создаётся файл с именем «core». Сам он не удалится, но он — самый обычный файл, который вы можете удалить когда захотите.

Файл core также сам по себе является кратчайшим путём к ответу на вопрос номер 2. Если ваш бинарник собран с опцией компилятора «-g», то вы можете запустить отладчик с командной строкой в виде «gdb -c core main.exe». Отладчик автоматически окажется на той строке, которая вызвала segmentation fault. О работе в gdb рекомендую почитать его документацию, она обширна и исчерпывающа.

ответ дан 29 окт 2019 в 15:03

user_587's user avatar

user_587user_587

2,5311 золотой знак11 серебряных знаков20 бронзовых знаков

5

У вас явная ошибка работы с памятью. Вызов new происходит один раз, а вызов delete?


Здесь происходит выделение массива указателей на int:

int **arr2D = new int*[CountArrayIn_arr2D];

Чтобы получить двумерный массив, нужно еще в каждый указатель выделить свой блок памяти:

for (int i = 0; i < CountArrayIn_arr2D; i++) 
{
    arr2D[i] = new int[CountElementsIn_arr1D];
//             ^^^^^^^

    for (int j = 0; j < CountElementsIn_arr1D; j++) 
    {
        // делаем что нужно
    }
}

ответ дан 29 окт 2019 в 14:51

Bogdan's user avatar

1

чел, ты забыл объявить элементы массивов в массиве)

ответ дан 29 окт 2019 в 14:55

jbc dgb's user avatar

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

  • Печать

Страницы: [1]   Вниз

Тема: Ошибка сегментирования (стек памяти сброшен на диск) [Решено]  (Прочитано 10990 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн
DANNNNN

Привет всем.
Есть программа. Она устанавливается из архива, который предварительно скачивается и после устанавливается.

Программа очень специфичная. Ты ей подсовываешь файл с командами, она его рассчитывает ( математического уклона программа) и выдаёт файл типа out.
И вот вчера при попытке запустить программу она выдаёт:

dan@dan-B450-AORUS-PRO:~/opt/2$ $GAUSS_EXEDIR/g16 NiFeSi2New33.inp
 Unable to open input file "NiFeSi2New33.inp" or "NiFeSi2New33.inp".
Ошибка сегментирования (стек памяти сброшен на диск)
Естественно у меня всего один файл в папке из которой происходит запуск.
Что я делал. Я на создавал кучу входных файлов ( вот этот 3-ий был) и всё  равно прога почему-то видит какой-то второй такой- же файл.  :D

Я обновлял Ubuntu, я перестановил программу поверх старой. Ничего не помогает(.
Помогите кто чем может.

« Последнее редактирование: 18 Марта 2020, 11:41:50 от zg_nico »


Оффлайн
bezbo

Ошибка сегментирования (стек памяти сброшен на диск)

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

Помогите кто чем может

вам остается только отправить отчет об ошибке разработчикам

или запустите программу отладчиком sudo gdb -q


Оффлайн
ReNzRv

И вот вчера

До этого система обновлялась?
Автоматическое обновление системы включено в настройках?


Оффлайн
DANNNNN

Проблема решилась(

Очень странно. Но я взял файл, который до этого запускался и немного изменил в неём параметры на те которые нужны. И всё заработало.

До этого файлы были созданы как копии того файла, который был создан на другом ПК и перенесён на этот комп через флэшку. Все копии этого файла и выдавали ошибку, не смотря на то, что некоторые из них также я переносил и на другие диски, там редактриовали переносил обратно.

Что это было- не понятно.
Короче ошибка в файле О_о.

Системе обновлялась конечно же.

P.S. До написание сюда я просидел часов 5 над проблемой.

« Последнее редактирование: 16 Ноября 2019, 10:18:29 от DANNNNN »


Оффлайн
andytux

«Разруха в головах, а не в клозетах.»

перенесён на этот комп через флэшку. …Короче ошибка в файле

Права на файл.


  • Печать

Страницы: [1]   Вверх

я написал вот такую программку:

//includes
#include <iostream>
#include <chrono>
#include <string>
#include <ctime>

//namespaces
using namespace std;
using namespace chrono;

//defines
#define RETURN return 0

//main
int main() {
    setlocale(LC_ALL,"ru"); //locale
    const auto _BEFORE_ = high_resolution_clock::now(); //start timer (for time account)
    srand(time(0));

    //Create Array
    int CountArrayIn_arr2D = 2;
    int CountElementsIn_arr1D = 3;
    int **arr2D = new int*[CountArrayIn_arr2D];

    //Generate Array
    for(int i = 0; i < CountArrayIn_arr2D; i++) {
        for(int j = 0; j < CountElementsIn_arr1D; j++) {
            arr2D[i][j] = rand() % 30 + 1;
        }
    }

    //Print Array
    for(int i = 0; i < CountArrayIn_arr2D; i++) {
        for(int j = 0; j < CountElementsIn_arr1D; j++) {
            cout<<"33[34m"<<arr2D[i][j]<<"33[0mt";
        }
        cout<<endl;
    }


    /*Clean memory*/
    for(int i = 0; i < CountArrayIn_arr2D; i++) {
        delete[] arr2D[i];
    }
    delete[] arr2D;

    //time account
    const auto _AFTER_ = high_resolution_clock::now();
    const float TIME_FOR_PROGRAM = duration_cast<milliseconds>(_AFTER_-_BEFORE_).count();
    cout<<"nn Programm completed in "<<TIME_FOR_PROGRAM<<"ms"<<endl;
    RETURN;
}

и пишет: запуск программы(не компиляция, а запуск) на Ubuntu

у меня 2 вопроса.
1) что значит стек сброшен на диск? на жесткий диск? удалится ли он самостоятельно? если нет то как удалить?
2) как это решить и почему это вообще произошло?

Ответы (3 шт):

У вас явная ошибка работы с памятью. Вызов new происходит один раз, а вызов delete?


Здесь происходит выделение массива указателей на int:

int **arr2D = new int*[CountArrayIn_arr2D];

Чтобы получить двумерный массив, нужно еще в каждый указатель выделить свой блок памяти:

for (int i = 0; i < CountArrayIn_arr2D; i++) 
{
    arr2D[i] = new int[CountElementsIn_arr1D];
//             ^^^^^^^

    for (int j = 0; j < CountElementsIn_arr1D; j++) 
    {
        // делаем что нужно
    }
}

→ Ссылка

Автор решения: Alexander Prokoshev

«Стек памяти сброшен на диск» — это [весьма-а вольный] перевод фразы «Core dumped». На диске в текущем каталоге создаётся файл с именем «core». Сам он не удалится, но он — самый обычный файл, который вы можете удалить когда захотите.

Файл core также сам по себе является кратчайшим путём к ответу на вопрос номер 2. Если ваш бинарник собран с опцией компилятора «-g», то вы можете запустить отладчик с командной строкой в виде «gdb -c core main.exe». Отладчик автоматически окажется на той строке, которая вызвала segmentation fault. О работе в gdb рекомендую почитать его документацию, она обширна и исчерпывающа.

→ Ссылка

Возможно, вам также будет интересно:

  • Ошибка сдк 80040005 работа программы будет прекращена
  • Ошибка сегментирования стек памяти сброшен на диск manjaro
  • Ошибка сд карты сд карта повреждена замените ее
  • Ошибка сегментирования стек памяти сброшен на диск linux
  • Ошибка сд карты нет доступа вот блиц

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

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