From 82a26a929d98f8edeee09e0c95c7704ab0955a88 Mon Sep 17 00:00:00 2001 From: Boblet Date: Fri, 19 Aug 2022 15:21:58 +0200 Subject: [PATCH] a command for diagnostic and suicide --- src/main/java/com/hbm/main/MainRegistry.java | 3 + .../java/com/hbm/util/SuicideThreadDump.java | 85 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/main/java/com/hbm/util/SuicideThreadDump.java diff --git a/src/main/java/com/hbm/main/MainRegistry.java b/src/main/java/com/hbm/main/MainRegistry.java index 0ca3b45af..e715ee150 100644 --- a/src/main/java/com/hbm/main/MainRegistry.java +++ b/src/main/java/com/hbm/main/MainRegistry.java @@ -69,6 +69,7 @@ import com.hbm.tileentity.bomb.TileEntityNukeCustom; import com.hbm.tileentity.machine.*; import com.hbm.tileentity.machine.rbmk.RBMKDials; import com.hbm.util.ArmorUtil; +import com.hbm.util.SuicideThreadDump; import com.hbm.world.feature.*; import com.hbm.world.generator.CellularDungeonFactory; @@ -809,6 +810,8 @@ public class MainRegistry { new OreCave(ModBlocks.stone_resource, 0).setThreshold(1.5D).setRangeMult(20).setYLevel(30).setMaxRange(20).withFluid(ModBlocks.sulfuric_acid_block); //sulfur new OreCave(ModBlocks.stone_resource, 1).setThreshold(1.75D).setRangeMult(20).setYLevel(25).setMaxRange(20); //asbestos //new OreLayer(Blocks.coal_ore, 0.2F).setThreshold(4).setRangeMult(3).setYLevel(70); + + SuicideThreadDump.register(); } @EventHandler diff --git a/src/main/java/com/hbm/util/SuicideThreadDump.java b/src/main/java/com/hbm/util/SuicideThreadDump.java new file mode 100644 index 000000000..39ad116a2 --- /dev/null +++ b/src/main/java/com/hbm/util/SuicideThreadDump.java @@ -0,0 +1,85 @@ +package com.hbm.util; + +import java.lang.management.ManagementFactory; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; + +import org.apache.logging.log4j.Level; + +import com.hbm.main.MainRegistry; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.FMLLaunchHandler; +import cpw.mods.fml.relauncher.Side; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.client.ClientCommandHandler; + +public class SuicideThreadDump extends CommandBase { + + public static void register() { + if(FMLLaunchHandler.side() != Side.CLIENT) return; + ClientCommandHandler handler = ClientCommandHandler.instance; + handler.registerCommand(new SuicideThreadDump()); + } + + @Override + public String getCommandName() { + return "dumpthreadsandcrashgame"; + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return "/dumpthreadsandcrashgame [dump/crash]"; + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender sender) { + return sender instanceof EntityPlayer; + } + + @Override + public void processCommand(ICommandSender sender, String[] args) { + + if(args.length != 1 || !(args[0].equals("dump") || args[0].equals("crash"))) { + throw new CommandException("Requires argument \"dump\" or \"crash\"!"); + } + + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + + for(ThreadInfo thread : threads) { + dumpThread(thread); + } + + if(args[0].equals("crash")) { + FMLCommonHandler.instance().exitJava(0, true); + } + } + + private static void dumpThread(ThreadInfo info) { + + MainRegistry.logger.log(Level.FATAL, "==========================================="); + MainRegistry.logger.log(Level.FATAL, "Thread: " + info.getThreadName() + " PID: " + info.getThreadId()); + MainRegistry.logger.log(Level.FATAL, "Suspended: " + info.isSuspended()); + MainRegistry.logger.log(Level.FATAL, "Blocked: " + info.getBlockedTime() + "ms, " + info.getBlockedCount() + "x"); + MainRegistry.logger.log(Level.FATAL, "Runs Native: " + info.isInNative()); + MainRegistry.logger.log(Level.FATAL, "State: " + info.getThreadState().name()); + MainRegistry.logger.log(Level.FATAL, "-------------------------------------------"); + + if(info.getLockedMonitors().length != 0) { + MainRegistry.logger.log(Level.FATAL, "Following locks found:"); + for(MonitorInfo monitor : info.getLockedMonitors()) { + MainRegistry.logger.log(Level.FATAL, "- " + monitor.getLockedStackFrame()); + } + MainRegistry.logger.log(Level.FATAL, "-------------------------------------------"); + } + + MainRegistry.logger.log(Level.FATAL, "Stacktrace:"); + for(StackTraceElement line : info.getStackTrace()) { + MainRegistry.logger.log(Level.FATAL, "- " + line); + } + MainRegistry.logger.log(Level.FATAL, "==========================================="); + } +}