We use essential cookies for login and local storage for your preferences. For usage metrics, we use Google Analytics 4 — you can decline without losing anything in the product. Learn more

ThreadMineThreadMine
Back

Open-source tool

Analyze production thread dumps without sending internal names

tm-anon is ThreadMine's open-source local anonymizer: it masks the dump on your machine, the analysis works the same, and real names never leave it.

Analyze a dump now

Quick answer

To sanitize a thread dump before sharing it: mask it locally with tm-anon (tm-anon mask dump.txt) and upload only the result. Real package, class and thread names become deterministic pseudonyms and stay in a vault on your machine — the ThreadMine analysis fires the same detections and returns the same health score.

The problem: a dump is useful because it is indiscreet

In a lot of companies, pasting a production thread dump into a third-party analyzer is against policy — and the policy has a point. The dump carries internal package and class names (com.acme.payment.LedgerService), thread names that embed tenant ids, routes or customer identifiers, and the JVM’s full command line, flags and paths included. It is exactly the kind of data a compliance team labels “does not leave the building” — and during an incident, the people who need the analysis most are the ones who cannot send the dump.

tm-anon exists to unlock that scenario: it makes the dump boring before it leaves the machine, without breaking what an analyzer needs to do its job.

How it works

tm-anon replaces your names with deterministic pseudonyms (HMAC keyed by a local vault): com.acme.payment.LedgerService always becomes the same com.app1.Class2, in this dump and in the next ones. That determinism matters — before/after comparison and multi-dump timelines keep working, because the same class gets the same pseudonym in every dump. The reverse mapping lives in the vault, which never leaves your machine.

  1. 01

    Mask the dump locally

    tm-anon mask produces a dump.anon.txt with no internal names left; tm-anon verify checks the result — that is the compliance gate.

  2. 02

    Upload the masked file

    A normal ThreadMine upload: paste or drop the dump.anon.txt like any dump.

  3. 03

    The analysis runs the same — with a badge

    The same detections fire, and the report shows the "Anonymized" badge automatically — detection is automatic, nothing to configure.

  4. 04

    Export the report as JSON

    The JSON export carries the full diagnosis, still under pseudonyms.

  5. 05

    Back to your real names

    tm-anon unmask translates the report using the vault — on your machine, and only there.

Install

The primary artifact is a single dependency-free jar (requires Java 21+). If you don’t want a JVM on the workstation, native binaries are attached to the same release: tm-anon-windows-amd64.exe, tm-anon-linux-amd64 and tm-anon-macos-arm64.

Download

curl -LO https://github.com/maschiojv/threadmine-anonymizer/releases/latest/download/tm-anon.jar
java -jar tm-anon.jar

Usage

Four commands: init once per project, mask and verify for each dump, unmask when the report comes back.

Create the local vault (once per project)

tm-anon init

Mask the dump

tm-anon mask dump.txt

Verify — the compliance gate

tm-anon verify dump.txt dump.anon.txt

Reverse the names in the JSON export

tm-anon unmask export.json

Why you can trust it

The right question for any tool that touches sensitive data is “how do I verify?” — here, every guarantee is auditable:

Open source (MIT)

Full code on GitHub — what runs on your machine is what is in the repository.

Zero network code

The jar has no HTTP client and no java.net — and an architecture test fails the build if anyone adds one.

Public THREAT_MODEL

The threat model documents what the tool protects and the honest limits of masking.

Native binaries win/linux/mac

Built in public CI from the same code as the jar — no JVM needed to run.

GitHub Release — jar & binaries THREAT_MODEL

What the analysis preserves

Masking doesn’t degrade the analysis because ThreadMine detections are structural: a deadlock is a lock cycle, pool exhaustion is a whole pool stuck in the same state, virtual thread pinning is a frame pattern — none of it depends on your class names. What the detectors do match by name (JDK and framework frames, pool suffixes like http-nio-8080-exec-1) sits on a public allowlist and passes through verbatim. In the end-to-end parity check, 17/17 corpus dumps analyzed before and after masking produced the same result. And the report of a masked dump shows the “Anonymized” badge automatically.

Frequently asked questions

Does the masked dump lose analysis quality?

No. ThreadMine detections are structural, and everything the detectors match by name (JDK and framework frames, pool suffixes) stays verbatim via a public allowlist. In the parity check, 17 out of 17 corpus dumps produced the same result before and after masking — same problems, same health score.

What if I lose the vault?

The vault is the only map between pseudonyms and real names — and it never leaves your machine, so not even ThreadMine can reverse it for you. Without it, unmask is no longer possible; analyses you already ran remain valid, just reading pseudonyms. Treat the file like a secret and back it up as you would a private key.

Does the AI (Vein) work with an anonymized dump?

The deterministic analysis is identical with or without masking. The AI verdict, though, is generated over the masked dump, so it references the pseudonyms (com.app1.Class2 instead of your real names). To read it with the real names, export the JSON and run unmask locally — the translation happens on your machine, and only there.

Mask it, upload it, analyze it — no signup

Run tm-anon mask on your dump, paste the result into ThreadMine and get the diagnosis in seconds. Your first dump doesn’t require an account.