1 /* 2 * Copyright (c) 1997, 2020, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 /* 28 * The Original Code is HAT. The Initial Developer of the 29 * Original Code is Bill Foote, with contributions from others 30 * at JavaSoft/Sun. 31 */ 32 33 package jdk.test.lib.hprof.parser; 34 35 import java.io.*; 36 import jdk.test.lib.hprof.model.*; 37 38 /** 39 * Abstract base class for reading object dump files. A reader need not be 40 * thread-safe. 41 * 42 * @author Bill Foote 43 */ 44 45 46 public abstract class Reader { 47 protected PositionDataInputStream in; 48 49 protected Reader(PositionDataInputStream in) { 50 this.in = in; 51 } 52 53 /** 54 * Read a snapshot from a data input stream. It is assumed that the magic 55 * number has already been read. 56 */ 57 abstract public Snapshot read() throws IOException; 58 59 /** 60 * Read a snapshot from a file. 61 * 62 * @param heapFile The name of a file containing a heap dump 63 * @param callStack If true, read the call stack of allocaation sites 64 */ 65 public static Snapshot readFile(String heapFile, boolean callStack, 66 int debugLevel) 67 throws IOException { 68 int dumpNumber = 1; 69 int pos = heapFile.lastIndexOf('#'); 70 if (pos > -1) { 71 String num = heapFile.substring(pos+1, heapFile.length()); 72 try { 73 dumpNumber = Integer.parseInt(num, 10); 74 } catch (java.lang.NumberFormatException ex) { 75 String msg = "In file name \"" + heapFile 76 + "\", a dump number was " 77 + "expected after the :, but \"" 78 + num + "\" was found instead."; 79 System.err.println(msg); 80 throw new IOException(msg); 81 } 82 heapFile = heapFile.substring(0, pos); 83 } 84 GzipRandomAccess access = null; 85 try (PositionDataInputStream in = new PositionDataInputStream( 86 new BufferedInputStream(new FileInputStream(heapFile)))) { 87 int i = in.readInt(); 88 if (i == HprofReader.MAGIC_NUMBER) { 89 Reader r 90 = new HprofReader(heapFile, in, dumpNumber, 91 callStack, debugLevel); 92 return r.read(); 93 } else if ((access = GzipRandomAccess.getAccess(heapFile, 16)) != null) { 94 in.close(); 95 try (PositionDataInputStream in2 = new PositionDataInputStream( 96 new BufferedInputStream(access.asStream(0)))) { 97 i = in2.readInt(); 98 if (i == HprofReader.MAGIC_NUMBER) { 99 Reader r 100 = new HprofReader(access.asFileBuffer(), in2, dumpNumber, 101 callStack, debugLevel); 102 return r.read(); 103 } else { 104 throw new IOException("Unrecognized magic number in gzipped file: " + i); 105 } 106 } 107 } else { 108 throw new IOException("Unrecognized magic number: " + i); 109 } 110 } 111 } 112 113 /** 114 * Get Stack Traces from a Hprof file. 115 * 116 * @param heapFile The name of a file containing a heap dump 117 */ 118 public static String getStack(String heapFile, int debugLevel) 119 throws IOException { 120 int dumpNumber = 1; 121 int pos = heapFile.lastIndexOf('#'); 122 if (pos > -1) { 123 String num = heapFile.substring(pos+1, heapFile.length()); 124 try { 125 dumpNumber = Integer.parseInt(num, 10); 126 } catch (java.lang.NumberFormatException ex) { 127 String msg = "In file name \"" + heapFile 128 + "\", a dump number was " 129 + "expected after the :, but \"" 130 + num + "\" was found instead."; 131 System.err.println(msg); 132 throw new IOException(msg); 133 } 134 heapFile = heapFile.substring(0, pos); 135 } 136 try (PositionDataInputStream in = new PositionDataInputStream( 137 new BufferedInputStream(new FileInputStream(heapFile)))) { 138 int i = in.readInt(); 139 if (i == HprofReader.MAGIC_NUMBER) { 140 HprofReader r 141 = new HprofReader(heapFile, in, dumpNumber, 142 true, debugLevel); 143 r.read(); 144 return r.printStackTraces(); 145 } else { 146 throw new IOException("Unrecognized magic number: " + i); 147 } 148 } 149 } 150 }