Не всегда программы в 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

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

И набрать команду, которая выведет стек последних вызовов:
(gdb) backtrace
Вывод этой команды и нужно отправлять разработчикам. Чтобы отключиться от программы и выйти наберите:
(gdb) detach
(gdb) quit
Дальше остается отправить отчет и ждать исправления ошибки. Если вы не уверены, что ошибка в программе, можете поспрашивать на форумах. Когда у вас есть стек вызовов, уже можно попытаться, если не понять в чем проблема, то попытаться узнать, не сталкивался ли с подобной проблемой еще кто-то.
Выводы
Теперь у вас есть приблизительный план действий, что нужно делать, когда появляется ошибка сегментирования сделан дамп памяти ubuntu. Если вы знаете другие способы решить эту проблему, напишите в комментариях!

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
|
ppdisk 7 / 7 / 3 Регистрация: 07.06.2015 Сообщений: 22 |
||||
|
1 |
||||
|
07.06.2015, 18:04. Показов 1150. Ответов 2 Метки нет (Все метки)
День добрый, только начинаю осваивать QT. Написал маленькую программу, но при работе вылетает с ошибкой Segmentation fault. Ошибка происходит при вызове «run->setEnabled(true);» в моём самодельном слоте
__________________
0 |
|
187 / 172 / 38 Регистрация: 03.08.2012 Сообщений: 596 |
|
|
07.06.2015, 19:07 |
2 |
|
Не удивительно. В конструкторе вы создаете локальную переменную run и ее же создаете. А в слоте используете член класса run и пытаетесь получить к нему доступ, а доступа к нему нету, т.к. память под него не выделена и обьект не создан
1 |
|
7 / 7 / 3 Регистрация: 07.06.2015 Сообщений: 22 |
|
|
07.06.2015, 20:03 [ТС] |
3 |
|
Действительно, перенёс объявление переменных в заголовочный файл, и всё заработало! Спасибо!
0 |
После успешной компиляции glxwin, во-время запуска, Deodar вывел такую информацию.
coderaiser@cloudcmd:~/deodar$ node deodar
Segmentation fault (core dumped)
Посмотрев под отладчиком, обратил внимание, что node падает на вызове x11clip.start. Видимо, проблема в модуле x11clip.
Да, там (в x11clip.start) нигде нет проверок на возвращение кода ошибки и если скажем OpenDisplay вернуло NULL то дальнейшие вызовы запросто могут вызвать SegFault. Отчего это может произойти в вашем случае не знаю, надо смотреть в gdb какой именно вызов вернул NULL.
Кстати, как крайний вариант можно не использовать системный клипборд, для этого в файле deodar.js после require(x11clip) переопределяются clioboardGet/Set чтобы просто в переменой хранить текст.
А может дело в том, что у вас другой компилятор (не зря же он ругался на то, на что мой не ругается) и это на что то влияет, что то не инициализируется например… Кстати, у меня же 64 битная система, только на ней могу тестировать.
Copy link
Contributor
Author
У меня тоже x64, может быть можно сделать работу с x11clip опциональной? Насколько это важный модуль? В принципе, можно было бы, действительно, попробовать использовать этот модуль (например в try...catch), а, если не получается, перейти к полифилу, который проемулирует работу модуля, или к заглушке, которая урежет функционал, но оставит рабочим файловый менеджер.
логично.
к сожалению оно написано на С++, эта часть связаная с клипбордом, поэтому try/catch JavaScript на него не действуют. поэтому не ясно как отловить из скрипта глюк сишного кода. разве что наставить там сишных try/catch и if(NULL). но я то надеялся, что там просто нечему ломаться. вот тут вопрос, x11clip падает, а glxwin устроен похожим образом, создаётся окно, запускается цикл XNextEvent, он у вас работает? Вы не попробовали в deodar.js отключить вызовы x11clip? это буквально 5 строчек.
Мож там какая то фундаментальная проблема, например у вас не XWindow а Wayland )
Copy link
Contributor
Author
Пробовал переписать функцию start в x11clip таким образом:
Handle<Value> start(const Arguments& a) { try { XClipStart(); } catch (int error) { } HandleScope scope; return scope.Close(String::New("started")); }
Deodar упал всё-равно с той же ошибкой. После того, как закоментировал строчки в файле deodar.js:
x11clip.start() x11clip.mainLoop()
Приложение упало с новой ошибкой:
/home/coderaiser/deodar/intervision/display.js:53 dnaof(this, undefined, fonts[f].name, fontSize, fonts[f].extra_x, fonts[f].tu ^ TypeError: Cannot read property 'name' of undefined at X.TGLXVision.can.init (/home/coderaiser/deodar/intervision/display.js:53:33) at dnaof (/home/coderaiser/deodar/dnaof/dnaof.js:43:29) at X.TDeodar.can.init (/home/coderaiser/deodar/deodar.js:192:2) at Function.X.create (/home/coderaiser/deodar/dnaof/dnaof.js:24:35) at Object.<anonymous> (/home/coderaiser/deodar/deodar.js:196:17) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.runMain [as _onTimeout] (module.js:497:10)
за последние дни я много изменений внёс, попробуйте обновить все модули через git pull
(я пока не знаю как сделать чтобы одной командой все обновлялись)
и в файле deodar.js в строке 107 замените
var useX11clipboard = true
на
var useX11clipboard = false
x11clip совсем не будет загружаться тогда.
со шрифтами тоже должна проблема уйти вроде. (в вашем случае, кажется, это из за того что вы обновили deodar и не обновили intervision или наоборот)
кстати, у меня есть репозиторий называется x11clipboard (не x11clip) там маленькая програмка на чистом С. на её основе потом написан x11clip node module. можно её попробовать скомпилить и запустить из под GDB и станет ясно где крэш является.
Copy link
Contributor
Author
Обновил модули:
- glxwin
- x11clip
- dnaof
- intervision
Поменял useX11clipboard, сейчас ошибка выглядит таким образом:
/home/coderaiser/deodar/intervision/display.js:34 if (fontPath.indexOf('/'+fontHints[i].name) >= 0) ^ TypeError: Cannot call method 'indexOf' of undefined at X.TGLXVision.can.init (/home/coderaiser/deodar/intervision/display.js:34:16) at dnaof (/home/coderaiser/deodar/dnaof/dnaof.js:43:29) at X.TDeodar.can.init (/home/coderaiser/deodar/deodar.js:214:2) at Function.X.create (/home/coderaiser/deodar/dnaof/dnaof.js:24:35) at Object.taskDeodarCreate (/home/coderaiser/deodar/deodar.js:219:18) at X.TChain.can.next (/home/coderaiser/deodar/file/chain.js:48:5) at processImmediate [as _immediateCallback] (timers.js:330:15)
gdb показывает следующую информацию при запуске скомпилированного с флагом -g файла x11clipboard/x11copy:
(gdb) r Starting program: /home/coderaiser/deodar/x11clipboard/x11copy Program received signal SIGSEGV, Segmentation fault. 0x080486f4 in main (argc=1, argv=0xbffff774) at x11copy.c:37 37 int N = DefaultScreen(display); (gdb)
Со шрифтом боле менее ясно, как то надо вам повнимательнее глянуть как програма получает имя шрифта (а это полный путь к файлу шрифта). Не понятно, почему она их не видит, может пермиссии или пути, как вариант скопировать файл шрифта в папку деодара (скажем DejaVuMono или Andale_Mono.ttf) проверитьправа и указать в display.js прям полный путь скажем за одну строчку до той которая ошибку выдаёт.
Как я и думал функция подключения к X-Server не срабатывает, скорее всего не DefaultScreen(), а та что перед ней. Может опять права доступа, или ещё что. К сожалению удалёно не пресдавляю как помочь. В-принципе операция подключения к X-Window Server самая простая. Если вам не лень, может попробуете разобраться по функции, глянуть простейшие hello-world-ы для оконного приложения, считать текстовый код ошибки. У меня сейчас к сожалению мало времени, чтобы переписать с полной обработкой ошибок.
Copy link
Contributor
Author
Добавил обработку ошибки в display.js.
Возможно ли использовать стандартный шрифт, или не назначать его вовсе?
Насколько Deodar завязан на X window? Возможна ли его частичная (хотя бы) функциональность без Иксов?
Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 16:36, 24 августа 2017.
Ошибка сегментации (англ. Segmentation fault, сокр. segfault, жарг. сегфолт) — ошибка программного обеспечения, возникающая при попытке обращения к недоступным для записи участкам памяти либо при попытке изменения памяти запрещённым способом.
Сегментная адресация памяти является одним из подходов к управлению и защите памяти в операционной системе. Для большинства целей она была вытеснена страничной памятью, однако в документациях по традиции используют термин «Ошибка сегментации». Некоторые операционные системы до сих пор используют сегментацию на некоторых логических уровнях, а страничная память используется в качестве основной политики управления памятью.
Сегментная адресация памяти является одним из подходов к управлению и защите памяти в операционной системе. Для большинства целей она была вытеснена страничной памятью, однако в документациях по традиции используют термин «Ошибка сегментации». Некоторые операционные системы до сих пор используют сегментацию на некоторых логических уровнях, а страничная память используется в качестве основной политики управления памятью.
Общие понятия
Сегментная адресация памяти — схема логической адресации памяти компьютера в архитектуре x86. Линейный адрес конкретной ячейки памяти, который в некоторых режимах работы процессора будет совпадать с физическим адресом, делится на две части: сегмент и смещение. Сегментом называется условно выделенная область адресного пространства определённого размера, а смещением — адрес ячейки памяти относительно начала сегмента. Базой сегмента называется линейный адрес (адрес относительно всего объёма памяти), который указывает на начало сегмента в адресном пространстве. В результате получается сегментный (логический) адрес, который соответствует линейному адресу база сегмента+смещение и который выставляется процессором на шину адреса.
Ошибка сегментации происходит , когда программа пытается получить доступ к месту памяти, на которое она не имеет права доступа, или пытается получить доступ к ячейке памяти таким образом, каким не допускается условиями системы.
Термин «сегментация» применяется в разных сферах вычислительной техники. В контексте обсуждаемой темы, термин используется с 1950 года , и относится к адресное пространству программы. Таким образом, при попытке чтения за пределами адресного пространства программы или запись на фрагмент, предназначенного только для чтения сегмента адресного пространства, приводит к ошибке сегментации, отсюда и название.
В системах, использующих аппаратные средства сегментации памяти для обеспечения виртуальной памяти, сбой сегментации возникает, когда оборудование системы обнаруживает попытку программы обратиться к несуществующему сегменту, и пытается сослаться на место вне границ сегмента, или сослаться на место на которое у нее нет разрешений.
В системах , использующих только пейджинг недопустимая страница, как правило, ведет к сегментации, ошибки сегментации или ошибки страницы, в виду устройства алгоритмов системы виртуальной памяти.
Страницы — это области физической памяти фиксированного размера, мельчайшая и неделимая единица памяти, которой может оперировать ОС.
На аппаратном уровне, неисправность возникает по причине реагирования блока управления памяти (MMU) на неправомерный доступ к памяти.
На уровне операционной системы эта ошибка ловится и сигнал передается в блок «offending process», где эта ошибка обрабатывается:
- В UNIX-подобных операционных системах процесс, обращающийся к недействительным участкам памяти, получает сигнал «SIGSEGV».
- В Microsoft Windows, процесс, получающий доступ к недействительным участкам памяти, создаёт исключение «STATUS_ACCESS_VIOLATION», и, как правило, предлагает запустить отладчик приложения Dr. Watson, которая показывает пользователю окно с предложением отправить отчет об ошибке Microsoft.
Суммирую можно сказать, когда пользовательский процесс хочет обратиться к памяти, то он просит MMU переадресовать его. Но если полученный адрес ошибочен, — находится вне пределов физического сегмента, или если сегмент не имеет нужных прав (попытка записи в read only-сегмент), — то ОС по умолчанию отправляет сигнал SIGSEGV, что приводит к прерыванию выполнения процесса и выдаче сообщения “segmentation fault”.
Причины сегментации
Наиболее распространенные причины ошибки сегментации:
- Разыменование нулевых указателей
- Попытка доступа к несуществующему адресу памяти (за пределами адресного пространства процесса)
- Попытка доступа к памяти программой, которая не имеет права на эту часть памяти
- Попытка записи в память, предназначенной только для чтения
Причины зачастую вызваны ошибками программирования, которые приводят к ошибкам связанными с памятью:
- Создание операций с разыменованым указателем или создание неинициализированного указателя (указатель, который указывает на случайный адрес памяти)
- Разыменование или возложение на освобожденной указатель (использование оборванного указателя, который указывает на память, которая была освобождена или перераспределена).
- Переполнение буфера
- Переполнение стека
- Попытка выполнить программу, которая не компилируется правильно. (Некоторые компиляторы будут выводить исполняемый файл , несмотря на наличие ошибок во время компиляции.)
Пример Segmentation Fault
Рассмотрим пример кода на ANSI C, который приводит к ошибке сегментации вследствие присутствия квалификатора Сonst — type:
const char *s = "hello world"; *(char *)s = 'H';
Когда программа, содержащая этот код, скомпилирована, строка «hello world» размещена в секции программы с бинарной пометкой «только для чтения». При запуске операционная система помещает её с другими строками и константами в сегмент памяти, предназначенный только для чтения. После запуска переменная s указывает на адрес строки, а попытка присвоить значение символьной константы H через переменную в памяти приводит к ошибке сегментации.
Компиляция и запуск таких программ на OpenBSD 4.0 вызывает следующую ошибку выполнения:
$ gcc segfault.c -g -o segfault $ ./segfault Segmentation fault
Вывод отладчика gdb:
Program received signal SIGSEGV, Segmentation fault. 0x1c0005c2 in main () at segfault.c:6 6 *s = 'H';
В отличие от этого, gcc 4.1.1 на GNU/Linux возвращает ошибку ещё во время компиляции:
$ gcc segfault.c -g -o segfault segfault.c: In function ‘main’: segfault.c:4: error: assignment of read-only location
Условия, при которых происходят нарушения сегментации, и способы их проявления зависят от операционной системы.
Этот пример кода создаёт нулевой указатель и пытается присвоить значение по несуществующему адресу. Это вызывает ошибки сегментации во время выполнения программы на многих системах.
int* ptr = (int*)0; *ptr = 1;
Ещё один способ вызвать ошибку сегментации заключается в том, чтобы вызвать функцию main рекурсивно, что приведёт к переполнению стека:
Обычно, ошибка сегментации происходит потому что: указатель или нулевой, или указывает на произвольный участок памяти (возможно, потому что не был инициализирован), или указывает на удаленный участок памяти. Например:
char* p1 = NULL; /* инициализирован как нулевой, в чем нет ничего плохого, но на многих системах он не может быть разыменован */ char* p2; /* вообще не инициализирован */ char* p3 = (char *)malloc(20); /* хорошо, участок памяти выделен */ free(p3); /* но теперь его больше нет */
Теперь разыменование любого из этих указателей может вызвать ошибку сегментации.
Также, при использовании массивов, если случайно указать в качестве размера массива неинициализированную переменную. Вот пример:
int main()
{
int const nmax=10;
int i,n,a[n];
}
Такая ошибка не прослеживается G++ при компоновке, но при запуске приложения вызовет ошибку сегментации.
Видеопример Segmentation Fault на примере C:
Источники
- wiki info about Segmentation Fault
- wiki Segmentation_fault
- Почему возникает ошибка сегментации
- Segmentation Fault
Операционные системы |
|||||
|---|---|---|---|---|---|
| Общая информация |
|
||||
| Ядро |
|
||||
| Управление процессами |
|
||||
| Управление памятью |
|
||||
| Память для хранения Файловые системы |
|
||||
| Список |
|
||||
| Прочее |
|
- Печать
Страницы: [1] Вниз
Тема: Ошибка сегментирования (стек памяти сброшен на диск) [Решено] (Прочитано 9080 раз)
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-ий был) и всё равно прога почему-то видит какой-то второй такой- же файл. 
Я обновлял 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] Вверх
Вводная
C является «небезопасным» («unmanaged») языком, поэтому программы могут «вылетать» — аварийно завершать работу без сохранения данных пользователя, сообщения об ошибке и т.п. — стоит только, например, залезть в не инициализированную память. Например:
void fall()
{
char * s = "short_text";
sprintf(s,"This is very long text");
}
или
void fall()
{
int * pointer = NULL;
*pointer = 13;
}
Всем было бы лучше, если бы мы могли «отловить» падение программы — точно так же, как в java ловим исключения — и выполнить хоть что-то перед тем, как программа упадет (сохранить документ пользователя, вывести диалог с сообщением об ошибке и т.п.)
Общего решения задача не имеет, так как C не имеет собственной модели обработки исключений, связанных с работой с памятью. Тем не менее, мы рассмотрим два способа, использующих особенности операционной системы, вызвавшей исключение.
Есть 2 класса:
1) UI
//UI.h
#ifndef UI_H
#define UI_H
#include <map>
#include <string>
#include <FL/Fl_Button.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Widget.H>
using namespace std;
class App;
class Calculator;
class UI {
public:
Fl_Window *flWindow;
map< string, Fl_Box* > flBox;
map< string, Fl_Button*> flButtons;
Fl_Output *output;
App *app;
Calculator *calc;
UI(App* app);
void startWindow();
void endWindow();
void createUI();
static void resetOutputCb(Fl_Widget *w, void *data);
void changeOutputValue();
void prepareOutput(string& insertedValue, bool isNewAction);
};
#endif /* UI_H */
2) Calculator:
//Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <string>
#include <FL/Fl_Widget.H>
using namespace std;
class UI;
class Calculator {
public:
Calculator(UI *ui);
UI *ui;
string leftOperand;
string action;
string rightOperand;
static void clickButtonCb(Fl_Widget *w, void *data);
bool isNewAction(string action);
private:
void makeCalc(bool isNewValue);
double plus(double x, double y);
};
#endif /* CALCULATOR_H */
Класс UI инициализирует класс Calсulator и передает ему указатель на самого себя:
UI::UI(App *app) {
this->app = app;
this->calc = new Calculator(this);
}
Класс Calculator в свою очередь записывает указатель на UI в одно из своих свойств:
Calculator::Calculator(UI *ui) :
leftOperand("0"),
rightOperand(""),
action("") {
this->ui = ui;
}
}
Однако теперь при попытке вызвать из Calculator метод класса UI:
void UI::prepareOutput(string& insertedValue, bool isNewAction) {
if (calc->action != "" && !isNewAction) { // странно, что при calc->action != "" ошибки нет
if (calc->rightOperand == "0") {
calc->rightOperand = "";
}
calc->rightOperand = insertedValue; // НО ВОТ ТУТ Возникает ошибка при работе с calc->rightOperand
} else if (!isNewAction) {
if (calc->leftOperand == "0") {
calc->leftOperand = "";
}
calc->leftOperand = insertedValue;
}
if (isNewAction && calc->rightOperand == "" && calc->action != "" && insertedValue != "=") {
calc->action = insertedValue;
}
}
возникает ошибка:
Segmentation fault; core dumped;
Такая же возникает ошибка, если в классе Calculator сделать что-то вроде :
string str = this->ui->calc->leftOperand; // Segmentation fault; core dumped
При дебаге в переменных видны “странные” для меня значения, ведь ожидаются простые строки:
Почему возникает эта ошибка и как ее исправить?
Не запускается сервер
Ошибка segmentation fault (core dumped)
Есть данный код на СИ, суть в том, чтобы в двумерном массиве с помощью потоков (Linux) найти самую большую последовательность чисел по возрастанию. При компиляции всё хорошо, а как запускаю программу появляется ошибка Segmentation fault (core dumped)
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
void random1(int arr[5][100]) {
int i,j;
for(i=0; i<5;i )
{
for(j=0; j<100;j )
{
arr[i][j]=rand()0;
printf("%dt", arr[i][j]);
}
printf("n");
}
printf("n");
}
void* thread_func1(int arr[5][100]){
int buffer = 1, maxbuffer=0, max=0, minElement=0, maxElement;
int i,j;
for(i=0;i<5;i )
{
for(j=0;j<100;j )
{
if(arr[i][j 1]>arr[i][j])
{
buffer ;
max=buffer;
if(maxbuffer<max)
{
maxbuffer = max;
maxElement = arr[i][j 1];
}
}
if(arr[i][j 1]<=arr[i][j])
{
max=buffer;
if(maxbuffer<max)
{ maxbuffer = max;
maxElement = arr[i][j 1];
}
buffer = 1;
}
}
minElement = (maxElement 1)-maxbuffer;
for( i = minElement; i<=maxElement; i )
{
printf("%dt", arr[i][j]);
}
}
}
int main() {
int A[5][100];
int stime;
stime=time(NULL);
srand(stime);
random1(A);
pthread_t k1,k2;
pthread_create(&k1, NULL, (void*)thread_func1,(int*)A);
pthread_join(k1,NULL);
printf("%ld",k1);
exit (0);
}
Еще один пример реализации функции thread_func1, но там тоже выходит эта ошибка
void* thread_func1(int arr[5][100]){
int start=0, lenght=1, max_start=0, max_lenght=0;
int i,j;
for(i=0;i<5;i ){
for(j=0;j<100;j ){
for(int k=j 1;k<100;k )
{
if(arr[i][j]<arr[i][k])
lenght ;
else{
if(lenght>max_lenght)
max_lenght= lenght, max_start=start;
start = k, lenght = 1;
}
}
}
}
for(i = max_start; i<max_start max_lenght; i ){
for (j=max_start; i<max_start max_lenght; i ){
printf("%p", arr[i][j]);}}}
Ошибка:segmentation fault (core dumped): как можно исправить (shared memory) c
Ошибка слишком проста – Вы пытаетесь обращаться к объекту, который не создали
std::queue<std::string>* str = (std::queue<std::string>*)shmat(ShmID, 0, 0);
то есть, str указывает на память, но что там… а кто его знает. Если обычную структуру так можно размещать, то с классы нужно только через конструктор.
// получим указатель на память
void *p = shmat(ShmID, 0, 0);
// используем placement new для создания объекта по месту
std::queue<std::string> * str = new(p)std::queue<std::string>();
после такого изменения уже не падает. Но нужно не забыть вызвать деструктор (delete str;). И видимо его нужно вызвать только в одном из процессов. И самое главное – не вызвать его тогда, когда ещё другой процесс использует его.
Также нужно аккуратно посинхронизировать обращения к памяти, а то может быть очень весело – std::queue не ожидает, что он работает с разных процессов.
Способ 1: seh
Если Вы используете OS Windows в качестве целевой ОС и Visual C в качестве компилятора, то Вы можете использовать
— расширение языка С от Microsoft, позволяющее отлавливать любые исключения, происходящие в программе.
Общий синтаксис обработки исключений выглядит следующим образом:
__try
{
segfault1();
}
__except( condition1 )
{
// обработка исключения, если condition1 == EXCEPTION_EXECUTE_HANDLER.
// в condition1 может (должен) быть вызов метода, проверяющего
// тип исключения, и возвращающего EXCEPTION_EXECUTE_HANDLER
// если тип исключения соответствует тому, что мы хотим обработать
}
__except( condition2 )
{
// еще один обработчик
}
__finally
{
// то, что выполнится если ни один из обработчиков не почешется
}
Вот «работающий пример» — «скопируй и вставь в Visual Studio»
#include <stdio.h>
#include <windows.h>
#include <excpt.h>
int memento() // обработка Segfault
{
MessageBoxA(NULL,"Memento Mori","Exception catched!",NULL);
return 0;
}
void fall() // генерация segfault
{
int* p = 0x00000000;
*p = 13;
}
int main(int argc, char *argv[])
{
__try
{
fall();
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
memento();
}
}
Мне лично не удалось заставить заработать __finally (поэтому я и написал __except с кодом проверки, который всегда работает), но это, возможно, кривизна моих рук.
Данная методика, при всей ее привлекательности, имеет ряд минусов:
- Один компилятор. Одна ОС. Не «чистый С ». Если Вы хотите работать без средств MS — Вы не сможете использовать эту методику
- Один поток — одна таблица. Если Вы напишете конструкцию из __try… __except, внутри __try запустите другой поток и, не выходя из __try второй поток вызовет segfault, то… ничего не произойдет, программа упадет «как обычно». Потому, что на каждый поток нужно писать отдельный обработчик SEH.
Минусов оказалось настолько много, что приходится искать второе решение.
Способ 2: posix — сигналы
Способ рассчитан на то, что в момент падения программа получает POSIX-сообщение SIGSEGV. Это безусловно так во всех UNIX-системах, но это фактически так (хотя никто не гарантировал, windows — не posix-совместима) и в windows тоже.
Методика простая — мы должны написать обработчик сообщения SIGSEGV, в котором программа совершит «прощальные действия» и, наконец, упадет:
void posix_death_signal(int signum)
{
memento(); // прощальные действия
signal(signum, SIG_DFL); // перепосылка сигнала
exit(3); //выход из программы. Если не сделать этого, то обработчик будет вызываться бесконечно.
}
после чего мы должны зарегистрировать этот обработчик:
signal(SIGSEGV, posix_death_signal);
Вот готовый пример:
#include <stdio.h>
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <signal.h>
int memento()
{
int a=0;
MessageBoxA(NULL,"Memento mori","POSIX Signal",NULL);
return 0;
}
void fall()
{
int* p = 0x00000000;
*p = 13;
}
void posix_death_signal(int signum)
{
memento();
signal(signum, SIG_DFL);
exit(3);
}
int main(int argc, char *argv[])
{
signal(SIGSEGV, posix_death_signal);
fall();
}
В отличие от SEH, это работает всегда: решение «многопоточное» (вы можете уронить программу в любом потоке, обработчик запустится в любом случае) и «кроссплатформенное» — работает под любым компилятором, и под любой POSIX-совместимой ОС.
-
#1
- OS
-
Linux
- Amx Mod X
-
AMXX 1.8.3-dev
- Билд
-
Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
ReHLDS version: 3.4.0.664-dev Build date: 10:46:45 Sep 19 2018 (1621)
Build from: https://github.com/dreamstalker/rehlds/commit/83f53fb
- ReGamedll
-
ReGameDLL version: 5.7.0.313-dev Build date: 08:39:22 Sep 9 2018
Build from: https://github.com/s1lentq/ReGameDLL_CS/commit/e924a26
- Metamod
-
Metamod-r v1.3.0.128, API (5:13)
Metamod-r build: 17:47:54 Aug 24 2018
Metamod-r from: https://github.com/theAsmodai/metamod-r/commit/0cf2f70
- Meta модули
-
[ 1] VoiceTranscoder RUN - VoiceTranscoder.so v2017RC3 ini ANY ANY
[ 2] AMX Mod X RUN - amxmodx_mm_i386.so v1.9.0.5221 ini Start ANY
[ 3] Reunion RUN - reunion_mm_i386.so v0.1.0.92 ini Start Never
[ 4] ReAuthCheck RUN - reauthcheck_mm_i386.so v0.1.6 ini Start Never
[ 5] WHBlocker RUN - whblocker_mm_i386.so v1.5.695 ini Chlvl ANY
[ 6] SoftBlocker RUN - softblocker_mm_i386.so v1.1g ini ANY Never
[ 7] ReSemiclip RUN - resemiclip_mm_i386.so v2.3.9 ini Chlvl ANY
[ 8] ReSRDetector RUN - resrdetector_mm_i386.so v0.1.0 ini Chlvl ANY
[ 9] ReAPI RUN - reapi_amxx_i386.so v5.6.0.158-dev pl2 ANY Never
[10] CStrike RUN - cstrike_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
[11] CSX RUN - csx_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
[12] Fun RUN - fun_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
[13] Engine RUN - engine_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
[14] FakeMeta RUN - fakemeta_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
[15] ReAimDetector RUN - reaimdetector_amxx_i386.so v0.2.2 pl2 ANY Never
[16] Ham Sandwich RUN - hamsandwich_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
[17] MySQL RUN - mysql_amxx_i386.so v1.9.0.5221 pl2 ANY ANY
17 plugins, 17 running
- Плагины
-
[ 13] Admin Votes 1.9.0.5221 AMXX Dev Team adminvote.amxx running
[ 14] Pause Plugins 1.9.0.5221 AMXX Dev Team pausecfg.amxx running
[ 15] Stats Configuration 1.9.0.5221 AMXX Dev Team statscfg.amxx running
[ 16] Restrict Weapons 1.9.0.5221 AMXX Dev Team restmenu.amxx running
[ 17] CSStatsX SQL 0.7.4 serfreeman1337 csstatsx_sql.am running
[ 18] AES: StatsX 0.5 Vega serfreeman1337 aes_statsx_cstr running
[ 19] StatsX 1.9.0.5221 AMXX Dev Team statsx.amxx running
[ 20] Announcer Killstreak 2.0 Jumper & mx?! killsound.amxx running
[ 21] [ReAPI] Admin Models 0.0.2 Vaqtincha reapi_adminvipm running
[ 22] Smoke: HealthNade 0.0.3 wopox1337 smkhlndvip.amxx running
[ 23] [ReAPI]No Team Flash 1.0 ReHLDS Team notmflashvip.am running
[ 24] molodejj_damager 1.1 sector damagervipz.amx debug
[ 25] PrizeAwp 0.1 Demonx prizeawp.amxx running
[ 26] [ReAPI] AimEspFix VIP 1.0 ? fix_vip_tab.amx running
[ 27] Prize Knife 0.1 Safety1st knifeflags.amxx running
[ 28] [ReAPI] AdminFreeLook 1.0 ReHLDS Team adminfreelook.a running
[ 29] Show Motd 0.1 unnamed motdpriv.amxx running
[ 30] Show IP 1.0 $uicid3 amx_ip.amxx running
[ 31] antikill 1.0 Portugal antikill.amxx running
[ 32] Masofke.eu Signed Scre 1.0 ThE_ChOSeN_OnE msfk_snapshot.a running
[ 33] Advanced Gag 1.9.0 neygomon amx_gag.amxx running
[ 34] AFK Control 1.4.1 [Rnd neygomon afk_control.amx running
[ 35] Random Skies 1.1 tuty randomskies.amx running
[ 36] ReAimDetector API 0.2.2 ReHLDS Team reaimdetector.a running
[ 37] Knife warmup 0.1 Subb98 knife_warmup.am debug
[ 38] Auto Demo Recorder 2.2.1 F@nt0M demo_recorder.a running
[ 39] Radio Hudmsg Block 1.0 AcE radiohudmsgbloc running
[ 40] Adverts 1.0 pUzzlik adverts_message running
[ 41] Dead Messages 2.0 maFFyoZZyk dead.amxx debug
[ 42] Music Connect 1.1 Leo_[BH] music_connect.a running
[ 43] Real Damage [ReApi] 2.0 Leo_[BH] real_damage.amx running
[ 44] unknown unknown unknown ShowChangerName running
[ 45] Bestplayer 0.2 Huntai bestplayer.amxx running
[ 46] [ReAPI] AWPoff 1.4.3 PAffAEJIkA :3 awp_off.amxx running
[ 47] Rat Bomb 1.0 Seroff mfsc4mdl.amxx running
[ 48] C4 Timer 0.1 Lightman bombtimer.amxx running
[ 49] resetscore(ReAPI) 1.0 Phantom resetscore.amxx running
[ 50] Killer ScreenFade 0.0.5 Vaqtincha reapi_killer_sc running
[ 51] unknown unknown unknown mg_sound.amxx running
[ 52] AFK Bomb Transfer 0.4 VEN afkbombtransfer running
[ 53] Team menu 1.1 NobodyInTeam teammenu.amxx running
[ 54] Icon Color 1.0 AcE icon_color.amxx running
[ 55] Pop Grenades 1.2 EFFx/HamletEagle GrenadePop.amxx running
[ 56] Map Manager: Core 3.0.0 Mistrick map_manager_cor running
[ 57] Map Manager: Scheduler 0.1.0 Mistrick map_manager_sch running
[ 58] Map Manager: Rtv 0.0.4 Mistrick map_manager_rtv running
[ 59] Map Manager: Nominatio 0.0.8 Mistrick map_manager_nom running
[ 60] Map Manager: BlockList 0.0.3 Mistrick map_manager_blo running
[ 61] Map Manager: Online so 0.0.2 Mistrick map_manager_onl running
[ 62] Map Manager: Effects 0.0.8 Mistrick map_manager_eff running
[ 63] Map Manager: Informer 0.0.5 Mistrick map_manager_inf running
[ 64] Map Manager: Advanced 0.0.4 Mistrick map_manager_adv running
[ 65] [ReVIP] System Core 2.5 free pUzzlik re_vip_core.amx running
[ 66] [ReVIP] Menu 2.5 free pUzzlik re_vip_menu.amx running
[ 67] [ReVIP] Connected Info 2.5 free pUzzlik re_vip_connect_ running
[ 68] [ReVIP] Tab Info 2.5 free pUzzlik re_vip_tab_info running
[ 69] [ReVIP] Add HP 2.5 free pUzzlik re_vip_hp_add.a running
[ 70] Advanced Experience Sy 0.5 Vega serfreeman1337 aes_main.amxx running
[ 71] AES: CStrike Addon 0.5 Vega serfreeman1337 aes_exp_cstrike running
71 plugins, 71 running
- Amxx Модули
-
Currently loaded modules:
name version author status
ReAPI 5.6.0.158- Asmodai & s1lent running
CStrike 1.9.0.5221 AMX Mod X Dev Team running
CSX 1.9.0.5221 AMX Mod X Dev Team running
Fun 1.9.0.5221 AMX Mod X Dev Team running
Engine 1.9.0.5221 AMX Mod X Dev Team running
FakeMeta 1.9.0.5221 AMX Mod X Dev Team running
ReAimDetector 0.2.2 ReHLDS Team running
nVault 1.9.0.5221 AMX Mod X Dev Team running
Ham Sandwich 1.9.0.5221 AMX Mod X Dev Team running
MySQL 1.9.0.5221 AMX Mod X Dev Team running
10 modules
- Ошибка
Драсьте в общем сервер работал 3 дня сегодня захожу проверить открыл консоль и вот такая вот ошибка честно говоря даже не предстовляю с чем это связанно и как это решить если сервер может упасть раз в 2-3 дня самое обидное то что он не падает а просто повисает и не сробатывает авто подьём сервера у меня если сервер упал или VPS упал то сервер сам поднимется а тут повисание хз чё делать жду вашых предложений
) Сервер стоит на Debain 7 x64 стоит заметить что в логах ошибок не было замеченно
AMXMODX У МЕНЯ 1.9 last version
-
#2
Рассмотрим случай, если сервер даже не запускается.
- Первым делом открываем параметры запуска, и отключаем amxmodx. Перезапускаем сервер, смотрим консоль. Если проблема исчезла, значит ошибку вызывают плагины, их очередность загрузки или их конфликт. Открываем plugins.ini и отключаем плагины по очереди, ставя перед названием плагина символ ;
- Если данный метод не помог, отключаем модули которые ставили отдельно. (чтобы узнать список модулей, наберите в консоли meta list)
[DOUBLEPOST=1540051368][/DOUBLEPOST]Но для начала попробуй, просто поставить в самый верх
[ 36] ReAimDetector API 0.2.2 ReHLDS Team reaimdetector.a running
-
#3
Более подробный лог скиньте
-
#4
Более подробный лог скиньте
Нету ошибок в логах только в консоли сервера
Segmentation fault
или вы про какието другие логи о каторых я не знаю?
kapangaIII
-
#5
unlimited сначала надо в ulimit, хотя вроде это и не особо то важно
# Setup debugging
if test "$DEBUG" -eq 1; then
#turn on core dumps :) (if possible)
echo "Enabling debug mode"
if test "`ulimit -c`" -eq 0 ; then
ulimit -c unlimited
fi
GDB_TEST=`$GDB -v`
if test -z "$GDB_TEST"; then
echo "Please install gdb first."
echo "goto http://www.gnu.org/software/gdb/ "
DEBUG=0 # turn off debugging cause gdb isn't installed
fi
fi
Берешь такой.
Скачиваешь core к себе на компутер.
Качаешь так же все основные библиотеки, amxmodx/metamod/engine ну и геймдлл всякие.
Потом берешь такой, включаешь wsl, открываешь gdb, смотришь дамп, открываешь идой нужную .so’шку и ищешь адрес где упало, смотришь что это за функция, благо сейчас есть гитхаб и с поиском, затем ищешь подобную функцию в плагинах.
-
#6
unlimited сначала надо в ulimit, хотя вроде это и не особо то важно
# Setup debugging if test "$DEBUG" -eq 1; then #turn on core dumps :) (if possible) echo "Enabling debug mode" if test "`ulimit -c`" -eq 0 ; then ulimit -c unlimited fi GDB_TEST=`$GDB -v` if test -z "$GDB_TEST"; then echo "Please install gdb first." echo "goto http://www.gnu.org/software/gdb/ " DEBUG=0 # turn off debugging cause gdb isn't installed fi fiБерешь такой.
Скачиваешь core к себе на компутер.
Качаешь так же все основные библиотеки, amxmodx/metamod/engine ну и геймдлл всякие.Потом берешь такой, включаешь wsl, открываешь gdb, смотришь дамп, открываешь идой нужную .so’шку и ищешь адрес где упало, смотришь что это за функция, благо сейчас есть гитхаб и с поиском, затем ищешь подобную функцию в плагинах.
Звучит это всё конечно красиво и обнадеживает на светлое будущее но я почти нифига не понял что ты написал хахахах сори первый раз сталкиваюсь с такой проблемой если у тебя будет немного свободного времени я был бы рад если бы ты мне показал обьяснил как там что делать могу дать зайти провериш иза чего у меня эта ошибка )
-
#7
Нету ошибок в логах только в консоли сервера
Segmentation fault
или вы про какието другие логи о каторых я не знаю?
Там лог должен быть больше, там указаны ошибки.
Посмотрите в дампе, как сказал пользователь выше
-
#8
В каком дампе ребят я даже не знаю где находятса эти дампы как их найти и т.д я знаю где логи сервера находятса и мне этого всегда хвотало )) скажите куда там нужно зайти чтоб найти эти дампы чтоб я хотяб знал иза какого плагина — модуля падает сервер xD сошки плюшки я хз что это вобще 
-
#9
В каком дампе ребят я даже не знаю где находятса эти дампы как их найти и т.д я знаю где логи сервера находятса и мне этого всегда хвотало )) скажите куда там нужно зайти чтоб найти эти дампы чтоб я хотяб знал иза какого плагина — модуля падает сервер xD сошки плюшки я хз что это вобще
![]()
Ну тогда живите с таким сервером.
-
#10
Ну тогда живите с таким сервером.
Спасибо очень полезнный совет ….
-
#12
Portugal, тебе ответ дали в первом же сообщении — Упал сервер с ошибкой в консоли Segmentation fault
отключай по 1 плагину и смотри
Бро сервер падает раз в 3 дня у меня нету времени по 70 плагинов по 1 проверять раз в 3 дня мне нужно чтобы кто нибуть помог сделать вот это ибо я в этом вобще не шарю это Потом берешь такой, включаешь wsl, открываешь gdb, смотришь дамп, открываешь идой нужную .so’шку и ищешь адрес где упало, смотришь что это за функция, благо сейчас есть гитхаб и с поиском, затем ищешь подобную функцию в плагинах. Заплочу 200рублей
kapangaIII
-
#13
отключай по 1 плагину и смотри
Ну а как он определит из-за чего падает?
Даже отбирание оружия сразу после спавна может привести к падению, причем может не падать дней 50, а потом резко начать падать каждый день и именно из-за стрипа оружия.[DOUBLEPOST=1540120304][/DOUBLEPOST]Покажи для начала строку запуска и файл hlds_run отредактируй так как написано выше.
-
#14
У меня скрипт запуска
#! /bin/bash
##################################################################################
# #
# Counter-Strike : 1.6 Launcher #
# #
# Author remake: neygomon #
# Original Code: Cr@zy #
# Contact: http://www.unserver.ru #
# #
# This program is free software: you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation, either version 3 of the License, or (at your option) #
# any later version. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
# details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program. If not, see http://www.gnu.org/licenses/. #
# #
# Usage: /etc/init.d/hlds_launcher {start|stop|status|restart|console|update} #
# - start: start the server #
# - stop: stop the server #
# - status: display the status of the server (down or up) #
# - restart: restart the server #
# - console: display the server console where you can enter commands. #
# To exit the console without stopping the server, press CTRL + A then D. #
# - update: update the server #
# #
##################################################################################
### BEGIN INIT INFO
# Provides: hlds
# Required-Start: $syslog $local_fs $network
# Required-Stop: $syslog $local_fs $network
# Should-Start: $remote_fs $named
# Should-Stop: $remote_fs $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start hlds Server
# Description: hlds Start Script
### END INIT INFO
# Game config
STEAM_LOGIN="anonymous" #Не менять:) HL1 сервера выкачиваются и с анонимуса:)
SCREEN_NAME="masofkepb" #Название screen-сессии
USER="root" #Пользователь, от которого будем запускать сервер. !!!От root запускать сервера не стоит!!!
DIR_STEAMCMD="/root/steamcmd" #root Директория steamCMD
DIR_ROOT="/root/hlds/server/masofkepb" #root Директория HLDS
DIR_GAME="$DIR_ROOT/cstrike" #Это не менять:)
DIR_LOG="/home/$USER"
DAEMON_GAME="hlds_run" #HLDS скрипт | Не менять:)
#Start Распределение серверов по ядрам процессора
USE_CORE="all" #Ядро, на котором запускать HLDS. 0 - первое ядро, 1 - второе ядро и тд. all - все ядра (дефолт значение)
#По умолчанию используются все ядра системы, но HLDS - однопроцессорное приложение.
#Поэтому данную настройку следует использовать в случае нескольких серверов, чтобы все сервера не легли на одно ядро.
#End Распределение серверов по ядрам процессора
MAXPLAYERS="32" #Количество слотов - 32 максимум ( HL1 limit:c )
SYS_TICRATE="800" #sys_ticrate
IP="185.80.129.141" #IP адрес сервера
PORT="27015" #Порт сервера
EXTRAPARAMS="-pingboost 2" #Дополнительные параметры запуска
PARAM_START="-game cstrike -port $PORT +ip $IP -maxplayers ${MAXPLAYERS} -debug +sys_ticrate $SYS_TICRATE +map de_dust2 ${EXTRAPARAMS}"
function start {
if [ ! -d $DIR_ROOT ]; then echo "ERROR: $DIR_ROOT is not a directory"; exit 1; fi
if [ ! -x $DIR_ROOT/$DAEMON_GAME ]; then echo "ERROR: $DIR_ROOT/$DAEMON_GAME does not exist or is not executable"; exit 1; fi
if status; then echo "$SCREEN_NAME is already running"; exit 1; fi
# Start game
echo "Start command : ${PARAM_START}"
if [ $USE_CORE = "all" ]
then
echo "HLDS use full proc"
else
echo "HLDS use $USE_CORE"
fi
if [ `whoami` = root ]
then
cd $DIR_ROOT
if [ $USE_CORE = "all" ]
then
INIT="screen -AmdS $SCREEN_NAME"
else
INIT="taskset -c $USE_CORE screen -AmdS $SCREEN_NAME"
fi
$INIT sudo -u $USER ./$DAEMON_GAME $PARAM_START
else
cd $DIR_ROOT
if [ $USE_CORE = "all" ]
then
screen -AmdS $SCREEN_NAME ./$DAEMON_GAME $PARAM_START
else
taskset -c $USE_CORE screen -AmdS $SCREEN_NAME ./$DAEMON_GAME $PARAM_START
fi
fi
}
function stop {
if ! status; then echo "$SCREEN_NAME could not be found. Probably not running."; exit 1; fi
screen -p 0 -S $SCREEN_NAME -X eval 'stuff "quit"15'
}
function status {
screen -ls | grep [.]$SCREEN_NAME[[:space:]] > /dev/null
}
function console {
if ! status; then echo "$SCREEN_NAME could not be found. Probably not running."; exit 1; fi
screen -r $(ps -ef | grep SCREEN | grep "$SCREEN_NAME" | grep -v grep | awk '{ print $2}')
}
function update {
# Create the game root
if [ ! -d $DIR_ROOT ]
then
echo "$DIR_ROOT does not exist, creating..."
if [ `whoami` = root ]
then
su - $USER -c "mkdir -p $DIR_ROOT";
else
mkdir -p "$DIR_ROOT"
fi
fi
# Update or install server
if [ `whoami` = root ]
then
su - $USER -c "cd $DIR_STEAMCMD ; ./steamcmd.sh $PARAM_UPDATE 2>&1"
else
cd $DIR_STEAMCMD
./steamcmd.sh $PARAM_UPDATE 2>&1
fi
# Check install server
if [ ! -d $DIR_GAME ]; then update; else echo "$SCREEN_NAME update or install successfully"; exit 1; fi
exit 1
}
function checker {
checktag="[Checker HLDS]"
checkresp=`quakestat -P -a2s $IP:$PORT | grep response`
if [ -n "$checkresp" ]
then
echo "$checktag Server $SCREEN_NAME *[No Response]*"
cd $DIR_LOG
time=`date +%X`
date=`date +%D`
printf "[$time - $date] Server $SCREEN_NAME *[No response]*n" >> checker.log
#stop
kill -9 `screen -list | grep "SCREEN_NAME" | awk {'print $1'} | cut -d . -f1`
screen -wipe > /dev/null
#sleep 2
killall hlds_linux
sleep 2
start
exit 1
fi
checkdown=`quakestat -P -a2s $IP:$PORT | grep DOWN`
if [ -n "$checkdown" ]
then
echo "$checktag Server $SCREEN_NAME *[DOWN]*"
cd $DIR_LOG
time=`date +%X`
date=`date +%D`
printf "[$time - $date] Server $SCREEN_NAME *[DOWN]*n" >> checker.log
#stop
if status; then kill -9 `screen -list | grep "SCREEN_NAME" | awk {'print $1'} | cut -d . -f1`; screen -wipe > /dev/null; fi
sleep 2
start
exit 1
fi
checkup=`quakestat -P -a2s $IP:$PORT | grep cstrike`
if [ -n "$checkup" ]
then
echo "$checktag Server $SCREEN_NAME *[RUN]*"
exit 1
fi
}
function usage {
echo "Usage: $0 {start|stop|status|restart|console|update|checker}"
echo "On console, press CTRL+A then D to stop the screen without stopping the server."
}
case "$1" in
start)
echo "Starting $SCREEN_NAME..."
start
sleep 5
echo "$SCREEN_NAME started successfully"
;;
stop)
echo "Stopping $SCREEN_NAME..."
stop
sleep 5
echo "$SCREEN_NAME stopped successfully"
;;
restart)
echo "Restarting $SCREEN_NAME..."
status && stop
sleep 5
start
sleep 5
echo "$SCREEN_NAME restarted successfully"
;;
status)
if status
then echo "$SCREEN_NAME is UP"
else echo "$SCREEN_NAME is DOWN"
fi
;;
console)
echo "Open console on $SCREEN_NAME..."
console
;;
update)
echo "Starting the $SCREEN_NAME update..."
update
;;
checker)
echo "Check running $SCREEN_NAME..."
checker
;;
*)
usage
exit 1
;;
esac
exit 0
[DOUBLEPOST=1540120648][/DOUBLEPOST]
Ну а как он определит из-за чего падает?
Даже отбирание оружия сразу после спавна может привести к падению, причем может не падать дней 50, а потом резко начать падать каждый день и именно из-за стрипа оружия.[DOUBLEPOST=1540120304][/DOUBLEPOST]Покажи для начала строку запуска и файл hlds_run отредактируй так как написано выше.
ВОТ HLDS_RUN файл
#!/bin/sh
#
# Copyright (c) 2002, Valve LLC. All rights reserved.
#
# a wrapper script for the main hl dedicated server binary.
# Performs auto-restarting of the server on crash. You can
# extend this to log crashes and more.
#
# setup the libraries, local dir first!
export LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH"
init() {
# Initialises the various variables
# Set up the defaults
GAME="valve"
DEBUG=0
RESTART="yes"
HL=./hlds_linux
HL_DETECT=1
TIMEOUT=10 # time to wait after a crash (in seconds)
CRASH_DEBUG_MSG="email debug.log to linux@valvesoftware.com"
GDB="gdb" # the gdb binary to run
DEBUG_LOG="debug.log"
PID_FILE=""
STEAM=""
STEAMERR=""
SIGINT_ACTION="quit 0" # exit normally on sig int
NO_TRAP=0
AUTO_UPDATE=""
BETA_VERSION=""
PARAMS=$*
# Remove any old default pid files
# Cant do this as they may be still running
#rm -f hlds.*.pid
# use the $FORCE environment variable if its set
if test -n "$FORCE" ; then
# Note: command line -binary will override this
HL=$FORCE
HL_DETECT=0
fi
while test $# -gt 0; do
case "$1" in
"-game")
GAME="$2"
shift ;;
"-debug")
DEBUG=1
# Ensure that PID_FILE is set
if test -z "$PID_FILE"; then
PID_FILE="hlds.$$.pid"
fi ;;
"-norestart")
RESTART="" ;;
"-pidfile")
PID_FILE="$2"
shift ;;
"-binary")
HL="$2"
HL_DETECT=0
shift ;;
"-timeout")
TIMEOUT="$2"
shift ;;
"-gdb")
GDB="$2"
shift ;;
"-debuglog")
DEBUG_LOG="$2"
shift ;;
"-autoupdate")
AUTO_UPDATE="yes"
STEAM="steamcmd/steamcmd.sh"
RESTART="yes" ;;
"-steamerr")
STEAMERR=1 ;;
"-ignoresigint")
SIGINT_ACTION="" ;;
"-notrap")
NO_TRAP=1 ;;
"-beta")
BETA_VERSION="$2"
shift ;;
"-help")
# quit with syntax
quit 2
;;
esac
shift
done
# Ensure we have a game specified
if test -z "$GAME"; then
echo "Unable to determine game type from command line."
quit 1
elif test ! -d "$GAME"; then
echo "Invalid game type '$GAME' sepecified."
quit 1
fi
#if test 0 -eq "$NO_TRAP"; then
# Set up the int handler
# N.B. Dont use SIGINT symbolic value
# as its just INT under ksh
#trap "$SIGINT_ACTION" 2
#fi
if test ! -f "$HL"; then
echo "Half-life binary '$HL' not found, exiting"
quit 1
elif test ! -x "$HL"; then
# Could try chmod but dont know what we will be
# chmoding so just fail.
echo "Half-life binary '$HL' not executable, exiting"
quit 1
fi
# Setup debugging
if test "$DEBUG" -eq 1; then
#turn on core dumps :) (if possible)
echo "Enabling debug mode"
if test "`ulimit -c`" -eq 0 ; then
ulimit -c 2000
fi
GDB_TEST=`$GDB -v`
if test -z "$GDB_TEST"; then
echo "Please install gdb first."
echo "goto http://www.gnu.org/software/gdb/ "
DEBUG=0 # turn off debugging cause gdb isn't installed
fi
fi
PID_IN_PARAMS="`echo $PARAMS | grep -e -pidfile`"
if test -z "$PID_IN_PARAMS" && test -n "$PID_FILE"; then
HL_CMD="$HL $PARAMS -pidfile $PID_FILE"
else
HL_CMD="$HL $PARAMS"
fi
}
syntax () {
# Prints script syntax
echo "Syntax:"
echo "$0 [-game <game>] [-debug] [-norestart] [-pidfile]"
echo " [-binary [hlds_linux]"
echo " [-timeout <number>] [-gdb <gdb>] [-autoupdate]"
echo " [-steamerr] [-ignoresigint] [-beta <version>]"
echo " [-debuglog <logname>]"
echo "Params:"
echo "-game <game> Specifies the <game> to run."
echo "-debug Run debugging on failed servers if possible."
echo "-debuglog <logname> Log debug output to this file."
echo "-norestart Don't attempt to restart failed servers."
echo "-pidfile <pidfile> Use the specified <pidfile> to store the server pid."
echo "-binary <binary> Use the specified binary ( no auto detection )."
echo "-timeout <number> Sleep for <number> seconds before restarting"
echo " a failed server."
echo "-gdb <gdb> Use <dbg> as the debugger of failed servers."
echo "-steamerr Quit on steam update failure."
echo "-beta <version> Make use of a beta version of this server from Steam"
echo "-ignoresigint Ignore signal INT ( prevents CTRL+C quitting"
echo " the script )."
echo "-notrap Don't use trap. This prevents automatic"
echo " removal of old lock files."
echo ""
echo "Note: All parameters specified as passed through to the server"
echo "including any not listed."
}
debugcore () {
# Debugs any core file if DEBUG is set and
# the exitcode is none 0
exitcode=$1
if test $exitcode -ne 0; then
if test -n "$DEBUG" ; then
echo "bt" > debug.cmds;
echo "info locals" >> debug.cmds;
echo "info sharedlibrary" >> debug.cmds
echo "info frame" >> debug.cmds; # works, but gives an error... must be last
echo "----------------------------------------------" >> $DEBUG_LOG
echo "CRASH: `date`" >> $DEBUG_LOG
echo "Start Line: $HL_CMD" >> $DEBUG_LOG
# check to see if a core was dumped
if test -f core ; then
CORE="core"
elif test -f core.`cat $PID_FILE`; then
CORE=core.`cat $PID_FILE`
elif test -f "$HL.core" ; then
CORE="$HL.core"
fi
if test -n "$CORE"; then
$GDB $HL $CORE -x debug.cmds -batch >> $DEBUG_LOG
fi
echo "End of crash report" >> $DEBUG_LOG
echo "----------------------------------------------" >> $DEBUG_LOG
echo $CRASH_DEBUG_MSG
rm debug.cmds
else
echo "Add "-debug" to the $0 command line to generate a debug.log to help with solving this problem"
fi
fi
}
update() {
updatesingle
}
updatesingle() {
# Run the steam update
# exits on failure if STEAMERR is set
if test -n "$AUTO_UPDATE"; then
if test -f "$STEAM"; then
echo "Updating server using Steam."
CMD="$STEAM +logon anonymous +force_install_dir .. +app_update 90 +quit";
if test -n "$BETA_VERSION"; then
CMD="$CMD -beta $BETA_VERSION";
fi
STEAMEXE=steamcmd $CMD
if test $? -ne 0; then
if test -n "$STEAMERR"; then
echo "`date`: Steam Update failed, exiting."
quit 1
else
echo "`date`: Steam Update failed, ignoring."
return 0
fi
fi
else
if test -n "$STEAMERR"; then
echo "Could not locate steam binary:$STEAM, exiting.";
quit 1
else
echo "Could not locate steam binary:$STEAM, ignoring.";
return 0
fi
fi
fi
return 1
}
run() {
# Runs the steam update and server
# Loops if RESTART is set
# Debugs if server failure is detected
# Note: if RESTART is not set then
# 1. DEBUG is set then the server is NOT exec'd
# 2. DEBUG is not set the the server is exec'd
if test -n "$RESTART" ; then
echo "Auto-restarting the server on crash"
#loop forever
while true
do
# Update if needed
update
# Run the server
$HL_CMD
retval=$?
if test $retval -eq 0; then
break; # if 0 is returned then just quit
fi
debugcore $retval
echo "`date`: Server restart in $TIMEOUT seconds"
# don't thrash the hard disk if the server dies, wait a little
sleep $TIMEOUT
done # while true
else
# Update if needed
update
# Run the server
if test "$DEBUG" -eq 0; then
# debug not requested we can exec
exec $HL_CMD
else
# debug requested we can't exec
$HL_CMD
debugcore $?
fi
fi
}
quit() {
# Exits with the give error code, 1
# if none specified.
# exit code 2 also prints syntax
exitcode="$1"
# default to failure
if test -z "$exitcode"; then
exitcode=1
fi
case "$exitcode" in
0)
echo "`date`: Server Quit" ;;
2)
syntax ;;
*)
echo "`date`: Server Failed" ;;
esac
# Remove pid file
if test -n "$PID_FILE" && test -f "$PID_FILE" ; then
# The specified pid file
rm -f $PID_FILE
fi
# reset SIGINT and then kill ourselves properly
trap - 2
kill -2 $$
}
# Initialise
init $*
# Run
run
# Quit normally
quit 0
-
#15
Ну а как он определит из-за чего падает?
Даже отбирание оружия сразу после спавна может привести к падению, причем может не падать дней 50, а потом резко начать падать каждый день и именно из-за стрипа оружия.[DOUBLEPOST=1540120304][/DOUBLEPOST]Покажи для начала строку запуска и файл hlds_run отредактируй так как написано выше.
По поводу отбирание оружия у меня есть карты 35hp_ там при спавне отбирает оружие + есть ещё плагин разминки то есть первый раунд всегда на ножах ещё есть плагин каторый заменяет стандартную модель авп ножа випам ну и замена моделей игрока админам випам . и вместо смока гранаты хилку даёт випам . вроде всё по заменам .[DOUBLEPOST=1540121924][/DOUBLEPOST]
Ну а как он определит из-за чего падает?
Даже отбирание оружия сразу после спавна может привести к падению, причем может не падать дней 50, а потом резко начать падать каждый день и именно из-за стрипа оружия.[DOUBLEPOST=1540120304][/DOUBLEPOST]Покажи для начала строку запуска и файл hlds_run отредактируй так как написано выше.
Плагины тестировал с ботами падений пр имне небыло пару дней назад включил сервер простоял 3 дня и упал , зашёл в консоль сервера а там эта ошибка :/
kapangaIII
-
#16
Так, ну со строкой запуска все понятно, там все в норме. Отредактируй то что просят еще и жди падений.
Остальное не тебе было адресовано.
-
#17
Так, ну со строкой запуска все понятно, там все в норме. Отредактируй то что просят еще и жди падений.
Остальное не тебе было адресовано.
Ты об этом?
Но для начала попробуй, просто поставить в самый верх
[ 36] ReAimDetector API 0.2.2 ReHLDS Team reaimdetector.a running
или об этом?
# Setup debugging
if test "$DEBUG" -eq 1; then
#turn on core dumps :) (if possible)
echo "Enabling debug mode"
if test "`ulimit -c`" -eq 0 ; then
ulimit -c unlimited
fi
GDB_TEST=`$GDB -v`
if test -z "$GDB_TEST"; then
echo "Please install gdb first."
echo "goto http://www.gnu.org/software/gdb/ "
DEBUG=0 # turn off debugging cause gdb isn't installed
fi
fi
Если о unlimited то где это редактировать ?
Если что корень выгледит у меня так:
-

28 KB
Просмотры: 15
kapangaIII
-
#18
Если о unlimited то где это редактировать ?
файл hlds_run отредактируй так как написано выше
-
#19
первым делом поставить на своё место
Reunion
ReAimDetector
-
#20
первым делом поставить на своё место
Reunion
ReAimDetector
Я просто не вкурсе они что должны на 1-2 втором месте быть?