jdb-debug — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited jdb-debug (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use this skill when the user wants to debug a Java application, investigate an exception, inspect runtime state, or understand execution flow.
jdb must be installed and on PATH (comes with the JDK)suspend=y pauses the JVM until the debugger attaches (recommended for startup debugging)suspend=n lets the JVM run immediately (for attaching to a live process)You (Claude) will typically start the JVM yourself before connecting. The JDWP agent stanza varies by launcher. Pick a free port (e.g. 5005) and use suspend=y so the JVM waits for you to attach.
javajava -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 \
-cp target/classes com.example.Mainmvn test -Dmaven.surefire.debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"Or the built-in shorthand (uses port 5005 by default):
mvn -Dmaven.surefire.debug testFor Failsafe integration tests replace surefire with failsafe.
MAVEN_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005" \
mvn exec:java -Dexec.mainClass=com.example.Main./gradlew test --debug-jvm # uses port 5005 by default, suspend=yAdd to the task or pass via env:
JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005" \
./gradlew runTycho Surefire uses the same property as Maven Surefire:
mvn verify -Dmaven.surefire.debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"Or with the tycho.testArgLine property:
mvn verify -Dtycho.testArgLine="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"Or with Gradle:
./gradlew bootRun --args='--debug' # or pass JAVA_OPTSAs a fallback, this environment variable is picked up by every JVM:
JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005" \
<any-command-that-starts-a-jvm>Use jdb_launch to start the JVM with ${JDB_PORT} substitution (allocates a random port):
jdb_launch(["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:${JDB_PORT}",
"-cp", "target/classes", "com.example.Main"])Or for Maven tests:
jdb_launch(["mvn", "test",
"-Dmaven.surefire.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:${JDB_PORT}"])Then connect with wait_timeout to wait for the JVM to start. When there is exactly one launched process, jdb_connect auto-resolves the port — no need to pass it:
jdb_connect(wait_timeout=30)If you launched multiple JVMs or are connecting to a manually started JVM, specify the port:
jdb_connect(port=5005, wait_timeout=30)Similarly, all debugging tools auto-resolve the port when only one session is active. When multiple sessions are active, pass port= to select which session to use.
Pass jdb_path if jdb is not on PATH. Pass sourcepath to enable source listing. Pass trackallthreads=True on JDK 20+ to track virtual threads.
jdb_breakpoint_set("com.example.MyClass:42") # line breakpoint
jdb_breakpoint_set("com.example.MyClass.myMethod") # method breakpoint
jdb_breakpoint_set("com.example.MyClass.myMethod(int)") # overloaded methodFor exception debugging:
jdb_catch("java.lang.NullPointerException") # break on NullPointerException
jdb_catch("*", filter_type="uncaught") # break on any uncaught exceptionFor field watchpoints:
jdb_watch("com.example.MyClass.myField") # break on field write
jdb_watch("com.example.MyClass.myField", access_type="access") # break on field readExecution commands are fire-and-forget: they return immediately once the JVM resumes. If a breakpoint or exception is hit within a few seconds, the stop event is returned directly. Otherwise, the tool returns reason="resumed" and you should use jdb_suspend() or wait for the next breakpoint to examine state.
If the JVM was started with suspend=y:
jdb_run() # start execution (returns immediately)Or if already running:
jdb_cont() # continue execution (returns immediately)If jdb_run or jdb_cont returns reason="resumed", call jdb_wait_for_event to block until the next breakpoint, exception, or program exit:
jdb_wait_for_event(timeout=120) # blocks until stop event or timeoutjdb_where() — see the call stackjdb_locals() — see all local variablesjdb_print("expression") — evaluate any Java expressionjdb_dump("objectRef") — show all fields of an objectjdb_list() — see source code at current positionjdb_threads() — list all threadsjdb_step() — step into (enter method calls)jdb_next() — step over (skip over method calls)jdb_step_up() — step out (run until current method returns)jdb_up() / jdb_down() — navigate the call stack without steppingjdb_classes() to find loaded classesjdb_methods("com.example.MyClass") to discover available methodsjdb_fields("com.example.MyClass") to discover fieldsjdb_class_info("com.example.MyClass") to see class hierarchyjdb_set("variable", "newValue") to modify state and test hypothesesFor deadlock analysis:
jdb_threads() — find stuck threadsjdb_threadlocks() — see what locks a thread holds and waits forjdb_lock("objectRef") — see who owns a lock and who's waitingjdb_thread("threadId") then jdb_where() — inspect each thread's stackjdb_session_list() — list all active debug sessions with port and JDK versionjdb_launch_list() — list all launched JVM processes with statusjdb_launch_status(port=<port>) — check if a specific launched process is still runningjdb_disconnect()
jdb_launch_stop(port=<port>)Or when debugging multiple JVMs:
jdb_disconnect(port=<port>)
jdb_launch_stop(port=<port>)${JDB_PORT} substitution, and process detachment.
jdb_connect,jdb_launch*, and jdb_session_list require an active session.
set breakpoints.
JDK 13+, virtual thread tracking requires JDK 20+.
java., javax., sun., com.sun., jdk.*.
debugging.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.