GatherProcessInfoTimeoutHandler.java revision 1998:922839953828
1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24package jdk.test.failurehandler.jtreg; 25 26import com.sun.javatest.regtest.OS; 27import com.sun.javatest.regtest.TimeoutHandler; 28import jdk.test.failurehandler.*; 29 30import java.io.File; 31import java.io.FileWriter; 32import java.io.IOException; 33import java.io.PrintWriter; 34import java.lang.reflect.Field; 35import java.nio.file.Path; 36 37/** 38 * A timeout handler for jtreg, which gathers information about the timed out 39 * process and its children. 40 */ 41public class GatherProcessInfoTimeoutHandler extends TimeoutHandler { 42 private static final boolean HAS_NATIVE_LIBRARY; 43 static { 44 boolean value = true; 45 try { 46 System.loadLibrary("timeoutHandler"); 47 } catch (UnsatisfiedLinkError ignore) { 48 // not all os need timeoutHandler native-library 49 value = false; 50 } 51 HAS_NATIVE_LIBRARY = value; 52 } 53 private static final String LOG_FILENAME = "processes.log"; 54 private static final String OUTPUT_FILENAME = "processes.html"; 55 56 public GatherProcessInfoTimeoutHandler(PrintWriter jtregLog, File outputDir, 57 File testJdk) { 58 super(jtregLog, outputDir, testJdk); 59 } 60 61 /** 62 * Runs various actions for jtreg timeout handler. 63 * 64 * <p>Please see method code for the actions. 65 */ 66 @Override 67 protected void runActions(Process process, long pid) 68 throws InterruptedException { 69 Path workDir = outputDir.toPath(); 70 71 String name = getClass().getName(); 72 PrintWriter actionsLog; 73 try { 74 // try to open a separate file for aciton log 75 actionsLog = new PrintWriter(new FileWriter( 76 workDir.resolve(LOG_FILENAME).toFile(), true)); 77 } catch (IOException e) { 78 // use jtreg log as a fallback 79 actionsLog = log; 80 actionsLog.printf("ERROR: %s cannot open log file %s : %s", name, 81 LOG_FILENAME, e.getMessage()); 82 } 83 try { 84 actionsLog.printf("%s ---%n", name); 85 86 File output = workDir.resolve(OUTPUT_FILENAME).toFile(); 87 try { 88 PrintWriter pw = new PrintWriter(new FileWriter(output, true)); 89 runGatherer(name, workDir, actionsLog, pw, pid); 90 } catch (IOException e) { 91 actionsLog.printf("IOException: cannot open output file[%s] : %s", 92 output, e.getMessage()); 93 e.printStackTrace(actionsLog); 94 } 95 } finally { 96 actionsLog.printf("--- %s%n", name); 97 // don't close jtreg log 98 if (actionsLog != log) { 99 actionsLog.close(); 100 } else { 101 log.flush(); 102 } 103 } 104 } 105 106 @Override 107 protected long getProcessId(Process process) { 108 long result = super.getProcessId(process); 109 if (result == 0L) { 110 /* jtreg didn't find pid, most probably we are on JDK < 9 111 there is no Process::getPid */ 112 if (HAS_NATIVE_LIBRARY && "windows".equals(OS.current().family)) { 113 try { 114 Field field = process.getClass().getDeclaredField("handle"); 115 boolean old = field.isAccessible(); 116 try { 117 field.setAccessible(true); 118 long handle = field.getLong(process); 119 result = getWin32Pid(handle); 120 } finally { 121 field.setAccessible(old); 122 } 123 } catch (ReflectiveOperationException e) { 124 e.printStackTrace(log); 125 } 126 } 127 } 128 return result; 129 } 130 131 private native long getWin32Pid(long handle); 132 133 private void runGatherer(String name, Path workDir, PrintWriter log, 134 PrintWriter out, long pid) { 135 try (HtmlPage html = new HtmlPage(out)) { 136 ProcessInfoGatherer gatherer = new GathererFactory( 137 OS.current().family, 138 workDir, log, testJdk.toPath()).getProcessInfoGatherer(); 139 try (ElapsedTimePrinter timePrinter 140 = new ElapsedTimePrinter(new Stopwatch(), name, log)) { 141 gatherer.gatherProcessInfo(html.getRootSection(), pid); 142 } 143 } catch (Throwable e) { 144 log.printf("ERROR: exception in timeout handler %s:", name); 145 e.printStackTrace(log); 146 } 147 } 148} 149