AI-Assisted Debuggingon the JVM

run(application)→Unexpected behavior→Why?

What to expect

Experience & intuition

Debugging approaches

What not to expect

A model leaderboard

One universal recipe

Beyond the JVM

My path to debugging

Algorithms

Kotlin Coroutines
IDE tooling

PLDI · PPoPP

→

Concurrency
Testing

Lincheck GitHub

Concurrent JVM code

CAV · ISSTA

→

Debugging

Execution traces
Failing schedules

AI-Assisted Debugging
Debugging production

I start with println()

OrderDemo.java→PricingService.java
3PricingService pricing = new PricingService(args.length == 0);
4Order order = new Order();
5Money result = pricing.price(order);
6if (!order.currency.equals(result.currency)) {
7 throw new AssertionError("expected " + order.currency + ", got " + result.currency);
8}
Console
AssertionError: expected EUR, got USD
  at OrderDemo.main(OrderDemo.java:7)
OrderDemo.java→PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
4 if (cached != null) {
5 return useCached(cached);
6 } else {
7 return fetchPrice(order);
8 }
9}
Console
AssertionError: expected EUR, got USD

Which branch?

OrderDemo.java→PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
4 if (cached != null) {
+ println("useCached");
6 return useCached(cached);
7 } else {
+ println("fetchPrice");
9 return fetchPrice(order);
10 }
11}
Console
useCached
AssertionError: expected EUR, got USD

Which call?

OrderDemo.java→PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
+ println("sku=" + order.sku +
+ ", requested=" + order.currency +
+ ", cached=" + cached);
7 if (cached != null) {
+ println("useCached");
9 return useCached(cached);
10 } else {
+ println("fetchPrice");
12 return fetchPrice(order);
13 }
14}
Console
sku=JVM-1, requested=EUR, cached=90 USD
useCached
AssertionError: expected EUR, got USD

Which values?

Agents add logs too

CURSOR · 10 DECEMBER 2025

Introducing Debug Mode

Cursor Debug Mode article preview

ReLog

Generate diagnostic logs
Refine them after execution

Debugging framework · ASE 2026

A developer and an AI robot point at each other, each holding the same log printout
MeAI

An agent runs the same loop

PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
4 if (cached != null) {
5 return useCached(cached);
6 } else {
7 return fetchPrice(order);
8 }
9}
Console
AssertionError: expected EUR, got USD
AI ChatDemo
You · OrderDemo.java:7

Test failed: expected EUR, got USD

Locating the price calculation
✓Read PricingService.java
PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
4 if (cached != null) {
+ println("useCached " + cached);
6 return useCached(cached);
7 } else {
+ println("fetchPrice " + order);
9 return fetchPrice(order);
10 }
11}
Console
useCached 90 USD
AssertionError: expected EUR, got USD
AI ChatDemo
You · OrderDemo.java:7

Test failed: expected EUR, got USD

Checking both price sources
✓Add call + result logs
PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
4 if (cached != null) {
+ println("useCached " + cached);
6 return useCached(cached);
7 } else {
+ println("fetchPrice " + order);
9 return fetchPrice(order);
10 }
11}
Console
useCached 90 USD
AssertionError: expected EUR, got USD
AI ChatDemo
You · OrderDemo.java:7

Test failed: expected EUR, got USD

Checking which currency was requested
✓Inspect the request and cache key
PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
+ println("sku=" + order.sku +
+ ", requested=" + order.currency +
+ ", cached=" + cached);
7 if (cached != null) {
+ println("useCached " + cached);
9 return useCached(cached);
10 } else {
+ println("fetchPrice " + order);
12 return fetchPrice(order);
13 }
14}
Console
sku=JVM-1, requested=EUR, cached=90 USD
useCached 90 USD
AssertionError: expected EUR, got USD
AI ChatDemo
You · OrderDemo.java:7

Test failed: expected EUR, got USD

Comparing request and cached price
✓Log SKU, currency and cached value
PricingService.java
1class PricingService {
2Money price(Order order) {
3 Money cached = prices.get(order.sku);
4 println("sku=" + order.sku +
5 ", requested=" + order.currency +
6 ", cached=" + cached);
7 if (cached != null) {
8 println("useCached " + cached);
9 return useCached(cached);
10 } else {
11 println("fetchPrice " + order);
12 return fetchPrice(order);
13 }
14}
Console
sku=JVM-1, requested=EUR, cached=90 USD
useCached 90 USD
AssertionError: expected EUR, got USD
AI ChatDemo
You · OrderDemo.java:7

Test failed: expected EUR, got USD

Connecting the observations
✓Read request and cached currency

Currency is missing from the cache key

A EUR order gets a USD price

0:00 / 0:19

Logs need a feedback loop

ReLog · ASE 2026 · revised 26 August 2026

DeepSeek-V3 · 311 faulty Java methods · correct repairs

One round of logging

Add logs → Run → Diagnose

26.0%

Improve the observations

Add logs → Run → Read output

↳ Revise logs → Rerun → Diagnose

31.2%

println() has limits

Change a log

Recompile + rerun

Inside a dependency

No source edits

A skeleton still waiting for its laptop to finish compiling

println() has limits

Change a log

Recompile + rerun

Inside a dependency

No source edits