
CME is Bad
Мод для отладки ConcurrentModificationException и IndexOutOfBoundsException в Minecraft. Помогает быстро найти виновника краша, показывая полную историю изменений коллекций.
CME is Bad - это технический мод для Майнкрафт, который решает одну из самых головоломных проблем при разработке модов и сборок: краши с ConcurrentModificationException (CME) и IndexOutOfBoundsException (IOOBE). Обычно такие ошибки показывают только стек вызовов текущего потока, и понять, какой именно мод или механика вызвала конфликт, практически невозможно. CME is Bad записывает полную историю изменений отслеживаемой коллекции (List, Set, Map) и при следующем краше выдаёт лог, где видно, какой поток и какой мод модифицировал контейнер в последнюю очередь.
Зачем это нужно
Если вы собираете модпак или пишете свой мод, рано или поздно столкнётесь с CME. Особенно часто они вылезают на Forge 1.16.5-1.20.1, когда несколько потоков одновременно пытаются изменить один и тот же список или мапу. Без этого мода приходится часами перебирать моды вручную, отключая их по одному. CME is Bad сокращает поиск до минут.
Как это работает
Мод внедряется через Java Agent и перехватывает все операции с указанным контейнером (добавление, удаление, изменение). Каждое действие записывается вместе с полным стеком вызовов. Когда происходит краш, в файле CMESuckMyDuck.log вы увидите, кто и когда трогал коллекцию.
Установка
- Скачайте мод CME is Bad и положите JAR-файл в папку
mods. - В настройках лаунчера добавьте аргумент JVM:
-javaagent:mods/CMESuckMyDuck-<version>.jar=<полное_имя_класса>;<имя_поля>;<тип>;<фаза> - Запустите игру, играйте до краша.
- Откройте
CMESuckMyDuck.log- там будет вся история.
Аргументы
<полное_имя_класса>- внутреннее имя класса (с\вместо.), напримерnet/minecraft/client/audio/SoundEngine.<имя_поля>- имя поля-контейнера. Для Forge используйте SRG-имя, для Fabric - intermediary, для NeoForge - official.<тип>-List,SetилиMap.<фаза>-staticилиnonstatic.
Примеры JVM-аргументов
Forge 1.16.5, SoundEngine (ConcurrentModificationException):
-javaagent:mods/CMESuckMyDuck-1.0.0.jar=net/minecraft/client/audio/SoundEngine;field_217942_m;Map;nonstatic
Forge 1.20.1, PotionBrewing:
-javaagent:mods/CMESuckMyDuck-1.0.0.jar=net/minecraft/world/item/alchemy/PotionBrewing;f_43494_;List;static
Zeta мод (ArrayIndexOutOfBoundsException):
-javaagent:CMESuckMyDuck-1.0.0.jar=org/violetmoon/zetaimplforge/event/ForgeZetaEventBus;convertedHandlers;Map;nonstatic
Дополнительные опции
- Уровень логирования -
-Dcme_suck_my_duck.log_level=<0|1>. По умолчанию 1 (без дебага). 0 пишет всё, включаяMap#get, что делает лог огромным. - Версия ASM - для старых версий Minecraft (1.12.2) укажите
-Dcme_suck_my_duck.asm_api_version=5. - Максимум записей в файле -
-Dcme_suck_my_duck.file_max_entries=<число>. По умолчанию 500. После v1.0.3 мод хранит только последние две страницы. - Белый список конструктора -
-Dcme_suck_my_duck.whitelist_constructor_stacktrace=<строка>. Позволяет отслеживать только те контейнеры, которые созданы в определённом контексте (например, только в конкретном классе). - Преобразование в потокобезопасный контейнер -
-Dcme_suck_my_duck.transform_to_thread_safe=true. Не рекомендуется, так как сильно замедляет игру. - Режим inject -
-Dcme_suck_my_duck.inject_method=true. Вместо поля отслеживает вызов метода. Аргумент:-javaagent:...=<класс>;<метод>. - Игнорирование потоков -
-Dcme_suck_my_duck.ignore_threads="Server thread"и т.д. - Остановка логирования при ошибке -
-Dcme_suck_my_duck.stop_logging_if_exception_created=false. - Обновление Trace ID -
-Dcme_suck_my_duck.trace_id_updater=<класс>;<метод>. - Мониторинг локальных переменных (v1.1.0+) -
-Dcme_suck_my_duck.local_var_index=<индекс>+-Dcme_suck_my_duck.match_local_index=<порядковый>.
Важно знать
- Мод работает не только с Minecraft, но и с любыми Java-проектами. Для этого нужно добавить gson и asm в classpath.
- На слабых машинах с большим количеством модов логи могут быстро разрастись. Используйте белый список конструктора или ограничьте количество записей.
- Если вы не разработчик, а просто игрок, который хочет помочь автору модпака найти баг - этот мод ваш must-have. Скачайте CME is Bad и приложите лог к баг-репорту.
Скачать мод CME is Bad для Майнкрафт можно на любой версии, поддерживающей Fabric, Forge или NeoForge. Просто положите JAR в mods и настройте JVM-аргумент.
Как поиграть с друзьями с модом CME is Bad?
Мод CME is Bad куда интереснее в компании: поднимите сервер Майнкрафт с уже установленным модом, позовите друзей и играйте по своим правилам. Хостинг Майнкрафт для мода CME is Bad будет готов за пару минут - BungeeHost сделает всё за вас.
