HMCL-dev/HMCL · error · IOException

Cannot attach VM

Error message

Cannot attach VM ${lvmid}

What it means

GameDumpGenerator.attachVM fails to attach to the target JVM via the attach API and, after retrying, writes 'Cannot attach VM <lvmid>' to the dump writer and throws IOException. This happens when the HotSpotVirtualMachine attach or its load/instrument command cannot complete within the retry loop. The dump file will contain the same message.

Solutions

  1. Confirm the target process is alive (jps / process list) and re-list lvmids before attaching
  2. Run the launcher and the target JVM under the same user account
  3. Remove -XX:+DisableAttachMechanism from the target JVM's options and ensure it is a HotSpot JVM with attach support
  4. Check OS permissions/security software blocking the attach mechanism, then retry

Example fix

// before
new GameDumpGenerator().vm(lvmid); // lvmid may be stale
// after
if (ProcessHandle.of(lvmid).isPresent()) {
    new GameDumpGenerator().vm(lvmid);
} else {
    LOG.warning("Process " + lvmid + " exited; skipping dump");
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (ProcessHandle.of(lvmid).isEmpty()) { skip; } // and verify same user account

Type guard

static boolean canAttach(long lvmid) {
    return ProcessHandle.of(lvmid).map(p -> p.isAlive()).orElse(false);
}

Try / catch

try { dump = generator.vm(lvmid); }
catch (IOException e) { if (e.getMessage().startsWith("Cannot attach VM")) { LOG.warning("Attach failed for " + lvmid); } else throw e; }

Prevention

When it happens

Trigger: vm() requesting a dump for a lvmid whose process has exited, is not a Java process, or whose JVM refuses attach (different user, permissions, attach disabled via -XX:+DisableAttachMechanism), or repeated attach attempts failing after the 3-second retry sleeps.

Common situations: Target game process crashed between listing and attach; attaching to a process owned by another user; JDK tools not available (no attach provider); security software blocking the attach socket; attach mechanism disabled in the target JVM.


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/f5bc33be38eb0509. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameDumpGenerator.java:161

            execute(vm, "Thread.print -l", writer);

    }

    private static VirtualMachine attachVM(String lvmid, Writer writer) throws IOException, InterruptedException {
        for (int i = 0; i < RETRY_TIME; i++) {
            try {
                return VirtualMachine.attach(lvmid);
            } catch (Throwable e) {
                LOG.warning("An exception encountered while attaching vm " + lvmid, e);
                writer.write(StringUtils.getStackTrace(e));
                writer.write('\n');
                Thread.sleep(3000);
            }
        }

        String message = "Cannot attach VM " + lvmid;
        writer.write(message);
        throw new IOException(message);
    }

    private static void execute(VirtualMachine vm, String command, Appendable target) throws IOException {
        try (Reader reader = new InputStreamReader(executeJVMCommand(vm, command), OperatingSystem.NATIVE_CHARSET)) {
            char[] data = new char[256];
            CharBuffer cb = CharBuffer.wrap(data);
            int len;
            while ((len = reader.read(data)) > 0) { // Directly read the data into a CharBuffer would cause useless array copy actions.
                target.append(cb, 0, len);
            }
        } catch (Throwable throwable) {
            LOG.warning("An exception encountered while executing jcmd " + vm.id(), throwable);
            target.append(StringUtils.getStackTrace(throwable));
            target.append('\n');
        }
    }

    private static InputStream executeJVMCommand(VirtualMachine vm, String command) throws IOException, AttachNotSupportedException {

View on GitHub (pinned to 24702dc5a0)