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 24 package jdk.test.failurehandler.jtreg; 25 26 import com.sun.javatest.regtest.OS; 27 import com.sun.javatest.regtest.TimeoutHandler; 28 import jdk.test.failurehandler.*; 29 30 import java.io.File; 31 import java.io.FileWriter; 32 import java.io.IOException; 33 import java.io.PrintWriter; 34 import java.lang.reflect.Field; 35 import 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 */ 41 public class GatherProcessInfoTimeoutHandler extends TimeoutHandler { 42 static { 43 try { 44 System.loadLibrary("timeoutHandler"); 45 } catch (UnsatisfiedLinkError ignore) { 46 // not all os need timeoutHandler native-library 47 } 48 } 49 private static final String LOG_FILENAME = "processes.log"; 50 private static final String OUTPUT_FILENAME = "processes.html"; 51 52 public GatherProcessInfoTimeoutHandler(PrintWriter jtregLog, File outputDir, 53 File testJdk) { 54 super(jtregLog, outputDir, testJdk); 55 } 56 57 /** 58 * Runs various actions for jtreg timeout handler. 59 * 60 * <p>Please see method code for the actions. 61 */ 62 @Override 63 protected void runActions(Process process, long pid) 64 throws InterruptedException { 65 Path workDir = outputDir.toPath(); 66 67 String name = getClass().getName(); 68 PrintWriter actionsLog; 69 try { 70 // try to open a separate file for aciton log 71 actionsLog = new PrintWriter(new FileWriter( 72 workDir.resolve(LOG_FILENAME).toFile(), true)); 73 } catch (IOException e) { 74 // use jtreg log as a fallback 75 actionsLog = log; 76 actionsLog.printf("ERROR: %s cannot open log file %s : %s", name, 77 LOG_FILENAME, e.getMessage()); 78 } 79 try { 80 actionsLog.printf("%s ---%n", name); 81 82 File output = workDir.resolve(OUTPUT_FILENAME).toFile(); 83 try { 84 PrintWriter pw = new PrintWriter(new FileWriter(output, true)); 85 runGatherer(name, workDir, actionsLog, pw, pid); 86 } catch (IOException e) { 87 actionsLog.printf("IOException: cannot open output file[%s] : %s", 88 output, e.getMessage()); 89 e.printStackTrace(actionsLog); 90 } 91 } finally { 92 actionsLog.printf("--- %s%n", name); 93 // don't close jtreg log 94 if (actionsLog != log) { 95 actionsLog.close(); 96 } else { 97 log.flush(); 98 } 99 } 100 } 101 102 @Override 103 protected long getProcessId(Process process) { 104 long result = super.getProcessId(process); 105 if (result == 0L) { 106 /* jtreg didn't find pid, most probably we are on JDK < 9 107 there is no Process::getPid */ 108 if ("windows".equals(OS.current().family)) { 109 try { 110 Field field = process.getClass().getDeclaredField("handle"); 111 boolean old = field.isAccessible(); 112 try { 113 field.setAccessible(true); 114 long handle = field.getLong(process); 115 result = getWin32Pid(handle); 116 } finally { 117 field.setAccessible(old); 118 } 119 } catch (ReflectiveOperationException e) { 120 e.printStackTrace(log); 121 } 122 } 123 } 124 return result; 125 } 126 127 private native long getWin32Pid(long handle); 128 129 private void runGatherer(String name, Path workDir, PrintWriter log, 130 PrintWriter out, long pid) { 131 try (HtmlPage html = new HtmlPage(out)) { 132 ProcessInfoGatherer gatherer = new GathererFactory( 133 OS.current().family, 134 workDir, log, testJdk.toPath()).getProcessInfoGatherer(); 135 try (ElapsedTimePrinter timePrinter 136 = new ElapsedTimePrinter(new Stopwatch(), name, log)) { 137 gatherer.gatherProcessInfo(html.getRootSection(), pid); 138 } 139 } catch (Throwable e) { 140 log.printf("ERROR: exception in timeout handler %s:", name); 141 e.printStackTrace(log); 142 } 143 } 144 }