GatherProcessInfoTimeoutHandler.java revision 1870:4aa2e64eff30
1191783Srmacklem/* 2191783Srmacklem * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3191783Srmacklem * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4191783Srmacklem * 5191783Srmacklem * This code is free software; you can redistribute it and/or modify it 6191783Srmacklem * under the terms of the GNU General Public License version 2 only, as 7191783Srmacklem * published by the Free Software Foundation. 8191783Srmacklem * 9191783Srmacklem * This code is distributed in the hope that it will be useful, but WITHOUT 10191783Srmacklem * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11191783Srmacklem * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12191783Srmacklem * version 2 for more details (a copy is included in the LICENSE file that 13191783Srmacklem * accompanied this code). 14191783Srmacklem * 15191783Srmacklem * You should have received a copy of the GNU General Public License version 16191783Srmacklem * 2 along with this work; if not, write to the Free Software Foundation, 17191783Srmacklem * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18191783Srmacklem * 19191783Srmacklem * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20191783Srmacklem * or visit www.oracle.com if you need additional information or have any 21191783Srmacklem * questions. 22191783Srmacklem */ 23191783Srmacklem 24191783Srmacklempackage jdk.test.failurehandler.jtreg; 25191783Srmacklem 26191783Srmacklemimport com.sun.javatest.regtest.OS; 27191783Srmacklemimport com.sun.javatest.regtest.TimeoutHandler; 28191783Srmacklemimport jdk.test.failurehandler.*; 29191783Srmacklem 30191783Srmacklemimport java.io.File; 31191783Srmacklemimport java.io.FileWriter; 32191783Srmacklemimport java.io.IOException; 33191783Srmacklemimport java.io.PrintWriter; 34191783Srmacklemimport java.lang.reflect.Field; 35191783Srmacklemimport java.nio.file.Path; 36191783Srmacklem 37191783Srmacklem/** 38191783Srmacklem * A timeout handler for jtreg, which gathers information about the timed out 39191783Srmacklem * process and its children. 40191783Srmacklem */ 41191783Srmacklempublic class GatherProcessInfoTimeoutHandler extends TimeoutHandler { 42191783Srmacklem static { 43191783Srmacklem try { 44191783Srmacklem System.loadLibrary("timeoutHandler"); 45191783Srmacklem } catch (UnsatisfiedLinkError ignore) { 46191783Srmacklem // not all os need timeoutHandler native-library 47191783Srmacklem } 48191783Srmacklem } 49191783Srmacklem private static final String LOG_FILENAME = "processes.log"; 50191783Srmacklem private static final String OUTPUT_FILENAME = "processes.html"; 51191783Srmacklem 52191783Srmacklem public GatherProcessInfoTimeoutHandler(PrintWriter jtregLog, File outputDir, 53191783Srmacklem File testJdk) { 54191783Srmacklem super(jtregLog, outputDir, testJdk); 55191783Srmacklem } 56191783Srmacklem 57191783Srmacklem /** 58191783Srmacklem * Runs various actions for jtreg timeout handler. 59191783Srmacklem * 60220683Srmacklem * <p>Please see method code for the actions. 61191783Srmacklem */ 62191783Srmacklem @Override 63191783Srmacklem protected void runActions(Process process, long pid) 64191783Srmacklem throws InterruptedException { 65191783Srmacklem Path workDir = outputDir.toPath(); 66191783Srmacklem 67191783Srmacklem String name = getClass().getName(); 68191783Srmacklem PrintWriter actionsLog; 69191783Srmacklem try { 70191783Srmacklem // try to open a separate file for aciton log 71223280Srmacklem actionsLog = new PrintWriter(new FileWriter( 72191783Srmacklem workDir.resolve(LOG_FILENAME).toFile(), true)); 73191783Srmacklem } catch (IOException e) { 74191783Srmacklem // use jtreg log as a fallback 75191783Srmacklem actionsLog = log; 76191783Srmacklem actionsLog.printf("ERROR: %s cannot open log file %s : %s", name, 77191783Srmacklem LOG_FILENAME, e.getMessage()); 78191783Srmacklem } 79191783Srmacklem try { 80191783Srmacklem actionsLog.printf("%s ---%n", name); 81191783Srmacklem 82220683Srmacklem File output = workDir.resolve(OUTPUT_FILENAME).toFile(); 83220683Srmacklem try { 84191783Srmacklem PrintWriter pw = new PrintWriter(new FileWriter(output, true)); 85191783Srmacklem runGatherer(name, workDir, actionsLog, pw, pid); 86306609Srmacklem } catch (IOException e) { 87191783Srmacklem actionsLog.printf("IOException: cannot open output file[%s] : %s", 88220683Srmacklem output, e.getMessage()); 89220683Srmacklem e.printStackTrace(actionsLog); 90191783Srmacklem } 91191783Srmacklem } finally { 92191783Srmacklem actionsLog.printf("--- %s%n", name); 93198291Sjh // don't close jtreg log 94198291Sjh if (actionsLog != log) { 95198291Sjh actionsLog.close(); 96198291Sjh } else { 97191783Srmacklem log.flush(); 98191783Srmacklem } 99191783Srmacklem } 100191783Srmacklem } 101191783Srmacklem 102191783Srmacklem @Override 103191783Srmacklem protected long getProcessId(Process process) { 104191783Srmacklem long result = super.getProcessId(process); 105191783Srmacklem if (result == 0L) { 106203119Srmacklem /* jtreg didn't find pid, most probably we are on JDK < 9 107191783Srmacklem there is no Process::getPid */ 108191783Srmacklem if ("windows".equals(OS.current().family)) { 109191783Srmacklem try { 110191783Srmacklem Field field = process.getClass().getDeclaredField("handle"); 111191783Srmacklem boolean old = field.isAccessible(); 112191783Srmacklem try { 113191783Srmacklem field.setAccessible(true); 114198291Sjh long handle = field.getLong(process); 115198291Sjh result = getWin32Pid(handle); 116198291Sjh } finally { 117191783Srmacklem field.setAccessible(old); 118191783Srmacklem } 119191783Srmacklem } catch (ReflectiveOperationException e) { 120191783Srmacklem e.printStackTrace(log); 121191783Srmacklem } 122191783Srmacklem } 123191783Srmacklem } 124191783Srmacklem return result; 125191783Srmacklem } 126191783Srmacklem 127191783Srmacklem private native long getWin32Pid(long handle); 128191783Srmacklem 129191783Srmacklem private void runGatherer(String name, Path workDir, PrintWriter log, 130191783Srmacklem PrintWriter out, long pid) { 131191783Srmacklem try (HtmlPage html = new HtmlPage(out)) { 132191783Srmacklem ProcessInfoGatherer gatherer = new GathererFactory( 133191783Srmacklem OS.current().family, 134191783Srmacklem workDir, log, testJdk.toPath()).getProcessInfoGatherer(); 135191783Srmacklem try (ElapsedTimePrinter timePrinter 136191783Srmacklem = new ElapsedTimePrinter(new Stopwatch(), name, log)) { 137191783Srmacklem gatherer.gatherProcessInfo(html.getRootSection(), pid); 138323142Skib } 139323142Skib } catch (Throwable e) { 140191783Srmacklem log.printf("ERROR: exception in timeout handler %s:", name); 141323142Skib e.printStackTrace(log); 142323142Skib } 143196332Srmacklem } 144323142Skib} 145323142Skib