Skip to content
Permalink
Browse files
8243455: Many SA tests can fail due to trying to get the stack trace …
…of an active method

Reviewed-by: lmesnik, ysuenaga, sspitsyn
  • Loading branch information
plummercj committed Mar 12, 2021
1 parent e834f99 commit 43524cc41a67ef87b06df74d2d52c695c9fb8b3e
Showing 11 changed files with 78 additions and 73 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -84,7 +84,7 @@ public static void main(String[] args) throws Exception {
"Common-Cleaner",
"Signal Dispatcher",
"Method*",
"LingeredApp.main"));
"LingeredApp.steadyState"));
unExpStrMap.put("jstack -v", List.of(
"sun.jvm.hotspot.types.WrongTypeException",
"No suitable match for type of address"));
@@ -105,8 +105,8 @@ public static void main(String[] args) throws Exception {
"illegal code",
"Failure occurred at bci"));
expStrMap.put("where -a", List.of(
"Java Stack Trace for main",
"public static void main"));
"Java Stack Trace for SteadyStateThread",
"private static void steadyState"));
unExpStrMap.put("where -a", List.of(
"illegal code",
"Failure occurred at bci"));
@@ -53,8 +53,8 @@ public static void printStackTraces(String file) {
try {
System.out.println("HprofReader.getStack() output:");
String output = HprofReader.getStack(file, 0);
if (!output.contains("LingeredApp.main")) {
throw new RuntimeException("'LingeredApp.main' missing from stdout/stderr");
if (!output.contains("LingeredApp.steadyState")) {
throw new RuntimeException("'LingeredApp.steadyState' missing from stdout/stderr");
}
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
@@ -90,7 +90,7 @@ private static void testFindPC(boolean withXcomp, boolean withCore) throws Excep

test = new ClhsdbLauncher();

theApp = new LingeredAppWithTrivialMain();
theApp = new LingeredApp();
theApp.setForceCrash(withCore);
if (withXcomp) {
LingeredApp.startApp(theApp, "-Xcomp");
@@ -134,9 +134,9 @@ private static void testFindPC(boolean withXcomp, boolean withCore) throws Excep
String jStackOutput = runTest(withCore, cmds, null);

// Extract pc address from the following line:
// - LingeredAppWithTrivialMain.main(java.lang.String[]) @bci=1, line=33, pc=0x00007ff18ff519f0, ...
// - LingeredApp.steadyState(java.lang.Object) @bci=1, line=33, pc=0x00007ff18ff519f0, ...
String pcAddress = null;
String[] parts = jStackOutput.split("LingeredAppWithTrivialMain.main");
String[] parts = jStackOutput.split("LingeredApp.steadyState");
String[] tokens = parts[1].split(" ");
for (String token : tokens) {
if (token.contains("pc")) {
@@ -147,7 +147,7 @@ private static void testFindPC(boolean withXcomp, boolean withCore) throws Excep
}
}
if (pcAddress == null) {
throw new RuntimeException("Cannot find LingeredAppWithTrivialMain.main pc in output");
throw new RuntimeException("Cannot find LingeredApp.steadyState pc in output");
}

// Test the 'findpc' command passing in the pc obtained from jstack above
@@ -157,7 +157,7 @@ private static void testFindPC(boolean withXcomp, boolean withCore) throws Excep
expStrMap = new HashMap<>();
if (withXcomp) {
expStrMap.put(cmdStr, List.of(
"In code in NMethod for LingeredAppWithTrivialMain.main",
"In code in NMethod for jdk/test/lib/apps/LingeredApp.steadyState",
"content:",
"oops:",
"frame size:"));
@@ -168,17 +168,17 @@ private static void testFindPC(boolean withXcomp, boolean withCore) throws Excep
runTest(withCore, cmds, expStrMap);

// Run findpc on a Method*. We can find one in the jstack output. For example:
// - LingeredAppWithTrivialMain.main(java.lang.String[]) @bci=1, line=33, pc=..., Method*=0x0000008041000208 ...
// - LingeredApp.steadyState(java.lang.Object) @bci=1, line=33, pc=..., Method*=0x0000008041000208 ...
// This is testing the PointerFinder support for C++ MetaData types.
parts = jStackOutput.split("LingeredAppWithTrivialMain.main");
parts = jStackOutput.split("LingeredApp.steadyState");
parts = parts[1].split("Method\\*=");
parts = parts[1].split(" ");
String methodAddr = parts[0];
cmdStr = "findpc " + methodAddr;
cmds = List.of(cmdStr);
expStrMap = new HashMap<>();
expStrMap.put(cmdStr, List.of("Method ",
"LingeredAppWithTrivialMain.main",
"LingeredApp.steadyState",
methodAddr));
runTest(withCore, cmds, expStrMap);

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@ public static void main(String[] args) throws Exception {
cmds = new ArrayList<String>();

String cmdStr = null;
String[] parts = output.split("LingeredApp.main");
String[] parts = output.split("LingeredApp.steadyState");
String[] tokens = parts[1].split(" ");
for (String token : tokens) {
if (token.contains("Method")) {
@@ -72,7 +72,7 @@ public static void main(String[] args) throws Exception {

Map<String, List<String>> expStrMap = new HashMap<>();
expStrMap.put(cmdStr, List.of(
"public static void main\\(java\\.lang\\.String\\[\\]\\)",
"private static void steadyState\\(java\\.lang\\.Object\\)",
"Holder Class",
"public class jdk.test.lib.apps.LingeredApp @",
"public class jdk\\.test\\.lib\\.apps\\.LingeredApp @",
@@ -93,4 +93,3 @@ public static void main(String[] args) throws Exception {
System.out.println("Test PASSED");
}
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,7 @@ private static void testJstack(boolean withXcomp) throws Exception {
"java.lang.ref.Finalizer\\$FinalizerThread.run",
"java.lang.ref.Reference",
"Method\\*",
"LingeredApp.main"));
"LingeredApp.steadyState"));

test.run(theApp.getPid(), cmds, expStrMap, null);
} catch (SkippedException se) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,13 +49,13 @@ public static void main(String[] args) throws Exception {
System.out.println("Started LingeredApp with pid " + theApp.getPid());

// Run the 'jstack -v' command to get the address of a the Method*
// representing LingeredApp.main
// representing LingeredApp.steadyState
List<String> cmds = List.of("jstack -v");
Map<String, List<String>> expStrMap;

String jstackOutput = test.run(theApp.getPid(), cmds, null, null);

String[] snippets = jstackOutput.split("LingeredApp.main");
String[] snippets = jstackOutput.split("LingeredApp.steadyState");
String addressString = null;

String[] tokens = snippets[1].split("Method\\*=");
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,7 +63,7 @@ public static void main(String[] args) throws Exception {
"java.lang.ref.Finalizer\\$FinalizerThread.run",
"java.lang.ref.Reference",
"Method\\*",
"LingeredApp.main",
"LingeredApp.steadyState",
"Available commands:",
"attach pid \\| exec core",
"intConstant \\[ name \\[ value \\] \\]",
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,8 +59,8 @@ public static void main(String[] args) throws Exception {
"Java Stack Trace for Finalizer",
"Java Stack Trace for Signal Dispatcher",
"Java Stack Trace for Reference Handler",
"Java Stack Trace for main",
"public static void main"));
"Java Stack Trace for SteadyStateThread",
"private static void steadyState"));

test.run(theApp.getPid(), cmds, expStrMap, null);
} catch (SkippedException se) {

This file was deleted.

@@ -102,8 +102,8 @@ public static void launch(int expectedExitValue, String... toolArgs)
public static void printStackTraces(String file) throws IOException {
try {
String output = HprofReader.getStack(file, 0);
if (!output.contains("LingeredAppWithExtendedChars.main")) {
throw new RuntimeException("'LingeredAppWithExtendedChars.main' missing from stdout/stderr");
if (!output.contains("LingeredApp.steadyState")) {
throw new RuntimeException("'LingeredApp.steadyState' missing from stdout/stderr");
}
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
@@ -496,6 +496,43 @@ public static boolean isLastModifiedWorking() {
return sane;
}

/**
* Support for creating a thread whose stack trace is always readable. There are
* occassional isues trying to get the stack trace for LingeredApp.main() since
* it sometimes wakes up from sleep and may breifly have an unreadable thread
* stack trace. The code below is used to create "SteadyStateThread" whose
* stack trace is always readable.
*/

private static volatile boolean steadyStateReached = false;

private static void steadyState(Object steadyStateObj) {
steadyStateReached = true;
synchronized(steadyStateObj) {
}
}

private static void startSteadyStateThread(Object steadyStateObj) {
Thread steadyStateThread = new Thread() {
public void run() {
steadyState(steadyStateObj);
}
};
steadyStateThread.setName("SteadyStateThread");
steadyStateThread.start();

// Wait until the thread has started running.
while (!steadyStateReached) {
Thread.onSpinWait();
}

// Now wait until we get into the synchronized block.
while (steadyStateThread.getState() != Thread.State.BLOCKED) {
Thread.onSpinWait();
}
}


/**
* This part is the application itself. First arg is optional "forceCrash".
* Following arg is the lock file name.
@@ -524,14 +561,18 @@ public static void main(String args[]) {
Path path = Paths.get(theLockFileName);

try {
if (forceCrash) {
System.loadLibrary("LingeredApp"); // location of native crash() method
crash();
}
while (Files.exists(path)) {
// Touch the lock to indicate our readiness
setLastModified(theLockFileName, epoch());
Thread.sleep(spinDelay);
Object steadyStateObj = new Object();
synchronized(steadyStateObj) {
startSteadyStateThread(steadyStateObj);
if (forceCrash) {
System.loadLibrary("LingeredApp"); // location of native crash() method
crash();
}
while (Files.exists(path)) {
// Touch the lock to indicate our readiness
setLastModified(theLockFileName, epoch());
Thread.sleep(spinDelay);
}
}
} catch (IOException ex) {
// Lock deleted while we are setting last modified time.

1 comment on commit 43524cc

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 43524cc Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.