Skip to content

Commit f5dd242

Browse files
jbachorikclaude
andcommitted
fix(agent,client,tests): probe listing after disconnect and test isolation
- Add disconnecting flag to RemoteClient for immediate probe visibility - Skip loadAgent when agent already running (check btrace.port) - Add try-finally cleanup in tests to prevent port conflicts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6fa8cf5 commit f5dd242

5 files changed

Lines changed: 49 additions & 14 deletions

File tree

btrace-agent/src/main/java/org/openjdk/btrace/agent/RemoteClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public Boolean apply(Command value) {
7676
private volatile Socket sock;
7777
private volatile ObjectInputStream ois;
7878
private volatile ObjectOutputStream oos;
79+
private volatile boolean disconnecting;
7980

8081
private final AtomicReferenceFieldUpdater<RemoteClient, Socket> sockUpdater =
8182
AtomicReferenceFieldUpdater.newUpdater(RemoteClient.class, Socket.class, "sock");
@@ -325,6 +326,8 @@ private boolean dispatchCommand(Command cmd, boolean isConnected) {
325326
}
326327
case Command.DISCONNECT:
327328
{
329+
// Mark as disconnecting so listProbes() can find this probe
330+
disconnecting = true;
328331
((DisconnectCommand) cmd).setProbeId(id.toString());
329332
synchronized (output) {
330333
WireIO.write(output, cmd);
@@ -361,7 +364,7 @@ private boolean dispatchCommand(Command cmd, boolean isConnected) {
361364
}
362365

363366
public boolean isDisconnected() {
364-
return sock == null;
367+
return disconnecting || sock == null;
365368
}
366369

367370
@Override
@@ -388,6 +391,7 @@ protected void closeAll() throws IOException {
388391
}
389392

390393
void reconnect(ObjectInputStream ois, ObjectOutputStream oos, Socket socket) throws IOException {
394+
this.disconnecting = false;
391395
this.sock = socket;
392396
this.ois = ois;
393397
this.oos = oos;

btrace-client/src/main/java/org/openjdk/btrace/client/Client.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ public void attach(String pid, String agentPath, String sysCp, String bootCp) th
472472
}
473473
Properties serverVmProps = vm.getSystemProperties();
474474
int serverPort = Integer.parseInt(serverVmProps.getProperty("btrace.port", "-1"));
475+
boolean agentAlreadyRunning = false;
475476
if (serverPort != -1) {
476477
if (serverPort != port) {
477478
throw new IOException(
@@ -483,12 +484,23 @@ public void attach(String pid, String agentPath, String sysCp, String bootCp) th
483484
+ serverPort
484485
+ "!");
485486
}
487+
agentAlreadyRunning = true;
488+
if (log.isDebugEnabled()) {
489+
log.debug("agent already running on port {}", port);
490+
}
486491
} else {
487492
if (!isPortAvailable(port)) {
488493
throw new IOException("Port " + port + " unavailable.");
489494
}
490495
}
491496

497+
if (agentAlreadyRunning) {
498+
if (log.isDebugEnabled()) {
499+
log.debug("skipping loadAgent, agent already active");
500+
}
501+
return;
502+
}
503+
492504
if (log.isDebugEnabled()) {
493505
log.debug("attached to {}", pid);
494506
log.debug("loading {}", agentPath);

btrace-client/src/main/java/org/openjdk/btrace/client/Main.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,12 @@ public static void main(String[] args) throws Exception {
314314
createCommandListener(client),
315315
new String[] {probeCommand, probeCommandArg});
316316
} else if (listProbes) {
317-
registerExitHook(client);
317+
// Don't register exit hook for list-only operations - they shouldn't remove probes
318318
client.attach(pid.toString(), null, classPath);
319319
client.connectAndListProbes(host, createCommandListener(client));
320320
System.exit(0);
321321
} else if (listFailedExtensions) {
322-
registerExitHook(client);
322+
// Don't register exit hook for list-only operations - they shouldn't remove probes
323323
client.attach(pid.toString(), null, classPath);
324324
client.connectAndListFailedExtensions(host, createCommandListener(client));
325325
System.exit(0);

integration-tests/src/test/java/tests/BTraceFunctionalTests.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -424,29 +424,41 @@ public void testOnMethodUnattended() throws Exception {
424424
"Skipping unattended test in CI: run locally for correctness");
425425

426426
TestApp testApp = launchTestApp("resources.Main");
427-
File traceFile = locateTrace("btrace/OnMethodTest.java");
427+
try {
428+
File traceFile = locateTrace("btrace/OnMethodTest.java");
428429

429-
String pid = String.valueOf(testApp.getPid());
430-
AtomicBoolean hasError = new AtomicBoolean(false);
431-
System.out.println("===> btrace -x (unattended)");
430+
String pid = String.valueOf(testApp.getPid());
431+
// Allow time for the worker thread to start after "ready:" is printed
432+
try {
433+
Thread.sleep(500L);
434+
} catch (InterruptedException ie) {
435+
Thread.currentThread().interrupt();
436+
}
437+
AtomicBoolean hasError = new AtomicBoolean(false);
438+
AtomicBoolean probeStarted = new AtomicBoolean(false);
439+
System.out.println("===> btrace -x (unattended)");
432440
runBTrace(
433441
new String[] {"-x", pid, traceFile.toString()},
434442
new ProcessOutputProcessor() {
435443
@Override
436444
public boolean onStdout(int lineno, String line) {
437445
System.out.println("[btrace #" + lineno + "] " + line);
446+
if (line.contains("BTrace Probe:") || line.contains("Successfully started")) {
447+
probeStarted.set(true);
448+
}
438449
return lineno < 500;
439450
}
440451

441452
@Override
442453
public boolean onStderr(int lineno, String line) {
443-
System.err.println("[btrace #" + lineno + "] " + line);
454+
System.err.println("[btrace err] " + line);
444455
hasError.set(true);
445456
return lineno < 10;
446457
}
447458
});
448459

449460
assertFalse(hasError.get(), "btrace -x reported errors");
461+
System.out.println("===> probe started: " + probeStarted.get());
450462

451463
// Poll list of probes to discover the probe id reliably
452464
System.out.println("===> polling btrace -lp for probe id");
@@ -512,10 +524,13 @@ public boolean onStderr(int lineno, String line) {
512524
}
513525
}
514526

515-
// Assert exactly one matching probe is present
516-
org.junit.jupiter.api.Assertions.assertEquals(1, matchCount[0],
517-
"expected exactly one OnMethodTest probe listed by -lp");
518-
assertNotNull(probeId[0], "probe id not found in -lp within timeout");
527+
// Assert exactly one matching probe is present
528+
org.junit.jupiter.api.Assertions.assertEquals(1, matchCount[0],
529+
"expected exactly one OnMethodTest probe listed by -lp");
530+
assertNotNull(probeId[0], "probe id not found in -lp within timeout");
531+
} finally {
532+
testApp.stop();
533+
}
519534
}
520535

521536
@ParameterizedTest(name = "testThreadStart: dynamic={0}")

integration-tests/src/test/java/tests/RuntimeTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,11 +730,13 @@ public void runBTrace(String[] args, ProcessOutputProcessor outputProcessor) thr
730730
"-cp",
731731
cp,
732732
"org.openjdk.btrace.client.Main",
733-
debugBTrace ? "-v" : "",
734733
"-cp",
735734
eventsClassPath,
736735
"-d",
737736
Paths.get(System.getProperty("java.io.tmpdir"), "btrace-test").toString()));
737+
if (debugBTrace) {
738+
argVals.add(4, "-v"); // insert after Main class name
739+
}
738740
argVals.addAll(Arrays.asList(args));
739741
if (Files.exists(Paths.get(javaHome, "jmods"))) {
740742
argVals.addAll(
@@ -857,11 +859,13 @@ public Process runBTrace(
857859
"-cp",
858860
cp,
859861
"org.openjdk.btrace.client.Main",
860-
debugBTrace ? "-v" : "",
861862
"-cp",
862863
eventsClassPath,
863864
"-d",
864865
Paths.get(System.getProperty("java.io.tmpdir"), "btrace-test").toString()));
866+
if (debugBTrace) {
867+
argVals.add(4, "-v"); // insert after Main class name
868+
}
865869
argVals.addAll(Arrays.asList(args));
866870
if (Files.exists(Paths.get(javaHome, "jmods"))) {
867871
argVals.addAll(

0 commit comments

Comments
 (0)