Garry's Mod: аддон вызывает краш сервера
Сервер неделю стоял ровно, ты подключил новую партию аддонов под вайп — и через пару часов игры процесс просто исчезает из списка процессов, без единого внятного слова в консоли. Игроки уже пишут в дискорд «опять упал», а ты смотришь на коллекцию из полусотни аддонов и не понимаешь, с какого конца искать виновника. Знакомая ситуация — сам не раз перебирал Workshop-коллекции ночью перед открытием сервера. Разберём рабочую методику: как отличить настоящий краш процесса от безобидной Lua-ошибки, что искать в логе и как вычислить виновника среди десятков аддонов бинарным поиском, а не методом «отключил всё и молюсь».
Содержание
- Сначала пойми: это Lua-ошибка или настоящий краш процесса
- Включаем логирование до того, как сервер упадёт снова
- Читаем стектрейс: на что смотреть в первую очередь
- Бинарный поиск виновника: отключаем аддоны по одному или пополам
- Частые виновники после апдейта GMod
- Проверяем совместимость через Steam Workshop перед следующим вайпом
Сначала пойми: это Lua-ошибка или настоящий краш процесса
Это два разных явления, и путать их — главная причина потерянного времени при диагностике.
Lua-ошибка — это когда аддон написан криво, но сервер выживает. GMod гоняет Lua-код в песочнице поверх движка: если скрипт обращается к nil-значению или вызывает несуществующий метод, в консоль сыплется красный текст с [ERROR] и стектрейсом, аддон (или часть его функциональности) просто перестаёт работать, а srcds продолжает крутиться дальше. Игроки могут даже не заметить — разве что сломанная фича конкретного аддона.
Настоящий краш — это когда процесс сервера целиком умирает. Все игроки отваливаются разом с ошибкой соединения, в списке процессов srcds_linux/srcds.exe больше нет, а в консоли часто вообще нет финальной ошибки — просто обрыв. Причины у этого другие: падение бинарного модуля (.dll/.so), сегфолт движка, переполнение памяти физическим движком или системный OOM-killer, о котором подробно разобрано в статье про чтение логов и краш-репортов.
Практический вывод: если в консоли перед падением есть читаемый Lua-стектрейс — тебе повезло, ищи виновника по нему (раздел ниже). Если консоль просто обрывается без единой ошибки — придётся идти через логи хоста и бинарный поиск.
Включаем логирование до того, как сервер упадёт снова
Проблема с диагностикой краша задним числом в том, что стандартный игровой лог (sv_logfile 1, файлы logs/L<дата>.log) пишет в основном игровые события — коннекты, чат, урон — а не консольный вывод целиком, и буферизуется не построчно. Если процесс падает резко, последние строки консоли легко потерять.
Добавь в параметры запуска флаги, которые дублируют весь консольный вывод в отдельный файл построчно:
./srcds_run -game garrysmod -console -port 27015 \
+gamemode sandbox +map gm_construct +maxplayers 16 \
-condebug +con_logfile console.log \
+exec server.cfg
-condebug включает запись консоли в файл, +con_logfile console.log задаёт имя (файл появится в garrysmod/console.log, дописывается при каждом старте). После следующего краша сразу смотри в конец этого файла:
tail -n 100 garrysmod/console.log
Если сервер запущен через systemd (см. инструкцию по автозапуску), дополнительно проверь код завершения процесса:
journalctl -u gmod --since "2 hours ago"
Строка вида Main process exited, code=killed, status=11/SEGV — это сегфолт, почти всегда вина бинарного модуля или самого движка, а не чистого Lua-кода (Lua-ошибки процесс не убивают). status=9/KILL без предшествующей активности сервиса — подозревай OOM-killer, сверься с dmesg | grep -i oom.
Поднять сервер Garry's Mod за пару минут
Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.
Создать серверЧитаем стектрейс: на что смотреть в первую очередь
Типичная Lua-ошибка в консоли GMod выглядит так:
[ERROR] addons/awesome-swep-pack/lua/weapons/weapon_example/init.lua:87: attempt to call method 'GetOwner' (a nil value)
1. unknown - addons/awesome-swep-pack/lua/weapons/weapon_example/init.lua:87
2. include - [C]:-1
3. unknown - lua/autorun/server/sv_loader.lua:14
Первая строка после addons/ — это папка аддона, и именно она называет виновника. Загвоздка в том, что для аддонов, смонтированных через Workshop-коллекцию (см. подключение коллекции), вместо человеческого имени в пути стоит числовой Workshop ID: addons/3123456789/lua/.... Чтобы понять, что это за аддон, просто открой https://steamcommunity.com/sharedfiles/filedetails/?id=3123456789 в браузере — страница покажет название и автора.
Два правила при чтении стектрейса:
- Смотри самую первую ошибку в цепочке, а не последнюю. Одна первопричина (например, сломанный базовый аддон оружия) часто порождает десяток вторичных ошибок у всех аддонов, которые от него зависят — чинить нужно источник, а не симптомы.
- Если ошибок несколько и они относятся к разным на первый взгляд аддонам — проверь, не зависят ли они от одной общей библиотеки (например, оба используют один и тот же устаревший admin-фреймворк).
Если краш настоящий (процесс умер, а не просто ошибка) — стектрейса может не быть вообще, движок падает молча. В этом случае единственный путь — бисекция ниже.
Бинарный поиск виновника: отключаем аддоны по одному или пополам
Метод исключения — самый надёжный способ, когда стектрейс неоднозначный или его нет вовсе. Сценарий зависит от того, как у тебя установлены аддоны.
Если аддоны лежат вручную в garrysmod/addons/ (папками, не через Workshop) — отключить легко: GMod сканирует всё, что лежит в addons/, поэтому просто вынеси подозреваемых за пределы папки:
mkdir -p /home/gmod/gmodserver/garrysmod/addons_disabled
mv /home/gmod/gmodserver/garrysmod/addons/suspicious-pack \
/home/gmod/gmodserver/garrysmod/addons_disabled/
Перезапускаешь, воспроизводишь условия краша, смотришь результат. Если проблема не повторилась — виновник среди отключённой половины, дели её пополам дальше; если повторилась — проблема в оставшихся, отключай уже их.
Если аддоны идут через host_workshop_collection — физически отключить один предмет из коллекции нельзя, контент монтируется целиком по ID. Практичный вариант — сделай на сайте Steam копию коллекции, убери из неё половину предметов, пропиши новый ID коллекции во временном запуске (можно на том же сервере, но с флагом -port 27016, чтобы не мешать боевому инстансу) и гоняй тест там. Да, это дольше — каждая смена коллекции означает повторную сверку контрольных сумм при старте, для полусотни аддонов это минуты, не секунды. Ускорить поиск помогает не чистая бисекция по алфавиту, а деление по категориям: сначала выключи разом все SWEP/оружейные аддоны, потом все карты/пропы, потом все гейммод-плагины — так быстрее локализовать область поиска, прежде чем делить пополам внутри неё.
Отдельно ускоряет дело фиксация условий: краш случается при заходе на карту, при спавне конкретного предмета, через фиксированное время после старта, только при N+ игроках? Это резко сужает круг подозреваемых ещё до отключения аддонов.
Частые виновники после апдейта GMod
Несколько типовых причин, на которые стоит посмотреть в первую очередь:
- Бинарные модули не под ту ветку. GMod с 2020 года по умолчанию работает на x86-64 ветке движка (Chromium). Старые скомпилированные модули (
.dll/.soизgarrysmod/lua/bin/) — например, устаревшие сборки MySQLOO, голосовых или античит-модулей — либо не грузятся вовсе, либо роняют сервер почти сразу после старта. Если краш происходит буквально в первые секунды после запуска — подозревай именно это в первую очередь. Проверка: посмотри дату последнего обновления модуля на GitHub/Workshop и упоминание x86-64 в описании. - SWEP/SENT, написанные под старый API. После обновлений движка часть хуков и функций помечается устаревшей или меняет поведение — аддон, который давно не трогали, начинает падать на загрузке или при первом использовании оружия/энтити.
- Устаревшие гейммод-базы. Особенно актуально для форков DarkRP — если база гейммода и аддоны-плагины к ней обновляются разными темпами, конфликт хуков на инвентарь или экономику может уронить сервер при определённом действии игрока. Подробнее о выборе и настройке базы — в статье про популярные гейммоды DarkRP, TTT, Sandbox.
- Утечка в Think/Tick-хуке. Не мгновенный краш, а постепенный рост потребления памяти или CPU до тех пор, пока сервер не убьёт OOM-killer или он не зависнет по watchdog хостинга. Отличается от резкого краша плавным ростом потребления в мониторинге панели хостинга перед падением.
- Спам пропов и constraint'ов. Кривая система спавна (например, в билд-режимах DarkRP или sandbox-плагинах для дюпов) переполняет физический движок под нагрузкой — краш происходит не сразу при старте, а именно когда на карте скапливается много игроков и объектов.
Проверяем совместимость через Steam Workshop перед следующим вайпом
Прежде чем добавлять новый аддон в боевую коллекцию, стоит потратить пять минут на проверку прямо на странице Workshop:
- Смотри дату последнего обновления. Аддон, не тронутый автором с 2019–2020 годов (до перехода GMod на x86-64 ветку), — кандидат номер один на несовместимость.
- Читай комментарии за последние месяцы, а не только рейтинг звёзд — фразы вроде «не работает после апдейта» или «крашит сервер» от других админов обычно всплывают там раньше, чем ты столкнёшься с проблемой сам.
- Проверь список «Required items» на странице аддона — некоторые пакеты (особенно базы оружия и гейммод-фреймворки) требуют отдельно подключённый базовый аддон. Если его нет в твоей коллекции, зависимый аддон будет падать с ошибками при загрузке.
- Не смешивай в одной коллекции два полноценных «базовых» фреймворка одного назначения (например, два разных weapon base или два разных admin-мода вроде ULX и SAM одновременно) — они часто переопределяют одни и те же хуки без вызова оригинала, и результат непредсказуем.
- Заведи отдельную тестовую коллекцию — дубликат боевой плюс новый аддон — и прогоняй новинки на staging-инстансе (тот же VPS, другой порт, или отдельный дешёвый тестовый сервер) минимум полчаса-час с парой игроков или ботов, прежде чем вливать изменения в продакшен-коллекцию.
Поднять сервер Garry's Mod за пару минут
Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.
Создать серверЧастые вопросы
Сервер падает не сразу, а через несколько часов игры — с чего начать поиск?
Это больше похоже на утечку в Think/Tick-хуке или постепенное накопление объектов (пропы, constraint'ы), чем на разовую ошибку загрузки. Смотри график потребления RAM/CPU в панели хостинга за период до краша — если рост плавный, а не скачкообразный, ищи виновника среди аддонов с активными таймерами и хуками на каждый тик.
У меня в singleplayer/на листен-сервере аддон работает нормально, а на дедике падает — почему?
Выделенный сервер (dedicated) работает без клиентского рендеринга и части модулей, которые есть у листен-сервера с открытым клиентом. Бинарные модули часто собираются отдельно под Linux-дедик и под Windows-клиент — несовместимая сборка на дедике либо не подгрузится, либо уронит процесс. Также аддон может по ошибке дёргать клиентские глобальные переменные на сервере, где их просто нет.
Можно ли быстро откатиться, если краши начались после апдейта коллекции?
Да, если заранее фиксировать ID предыдущих версий коллекции или держать бэкап garrysmod/addons/ перед крупными изменениями — тогда откат сводится к смене ID в строке запуска и рестарту. Restart=on-failure в systemd спасает от даунтайма при единичных падениях, но не лечит первопричину — сервер будет падать по кругу, пока не найдёшь и не уберёшь виновника.
Стоит ли сразу писать автору аддона в комментариях Workshop?
Можно, приложив точный текст ошибки и путь из стектрейса — это помогает, если аддон ещё поддерживается. Но для давно заброшенных аддонов быстрее поискать форк с исправлениями через поиск по Workshop (часто у популярных сломанных аддонов есть неофициально обновлённая версия от другого автора) или просто заменить его на действующую альтернативу.