From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libjava/gnu/gcj/runtime/NameFinder.java | 341 ++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 libjava/gnu/gcj/runtime/NameFinder.java (limited to 'libjava/gnu/gcj/runtime/NameFinder.java') diff --git a/libjava/gnu/gcj/runtime/NameFinder.java b/libjava/gnu/gcj/runtime/NameFinder.java new file mode 100644 index 000000000..0742af193 --- /dev/null +++ b/libjava/gnu/gcj/runtime/NameFinder.java @@ -0,0 +1,341 @@ +/* NameFinder.java -- Translates addresses to StackTraceElements. + Copyright (C) 2002, 2004 Free Software Foundation, Inc. + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package gnu.gcj.runtime; + +import gnu.classpath.Configuration; +import gnu.gcj.RawData; + +import java.lang.StringBuffer; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.IOException; +import java.io.File; +import java.util.Collections; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + + +/** + * Lookup addresses (represented as longs) to find source & line number info. + * + * The following system property is available (defaults to true): + *
  • + * + * + *
  • + * + * close() should be called to get rid of all resources. + * + * This class is used from java.lang.VMThrowable. + * + * @author Mark Wielaard (mark@klomp.org) + */ +public class NameFinder +{ + /** + * The name of the binary to look up. + */ + private String binaryFile; + private String sourceFile; + private int lineNum; + private HashMap procs = new HashMap(); + /** + * Set of binary files that addr2line should not be called on. + */ + private static Set blacklist = Collections.synchronizedSet(new HashSet()); + + private static boolean use_addr2line + = Boolean.valueOf(System.getProperty + ("gnu.gcj.runtime.NameFinder.use_addr2line", "true") + ).booleanValue(); + + private static boolean show_raw + = Boolean.valueOf(System.getProperty + ("gnu.gcj.runtime.NameFinder.show_raw", "false") + ).booleanValue(); + + /** + * Return true if raw addresses should be printed in stacktraces + * when no line number information is available. + */ + static final boolean showRaw() + { + return show_raw; + } + + private static final boolean remove_unknown + = Boolean.valueOf(System.getProperty + ("gnu.gcj.runtime.NameFinder.remove_unknown", "true") + ).booleanValue(); + + /** + * Return true if non-Java frames should be removed from stack + * traces. + */ + static final boolean removeUnknown() + { + return remove_unknown; + } + + class Addr2Line + { + Process proc; + BufferedWriter out; + BufferedReader in; + + Addr2Line(String binaryFile) + { + try + { + String[] exec = new String[] {"addr2line", "-e", binaryFile}; + Runtime runtime = Runtime.getRuntime(); + proc = runtime.exec(exec); + } + catch (IOException ioe) + { + } + + if (proc != null) + { + in = new BufferedReader(new InputStreamReader(proc.getInputStream())); + out = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())); + } + } + + void close() + { + try + { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + catch (IOException x) {} + if (proc != null) + proc.destroy(); + } + } + + /** + * Create a new NameFinder to lookup names in binaryFile. Call close to get rid of any + * resources created while using the lookup methods. + */ + public NameFinder() + { + } + + /** + * Returns the source file name if lookup() was successful. If the source file could not be + * determined, the binary name will be returned instead. + */ + public String getSourceFile() + { + String file; + if (sourceFile != null) + file = sourceFile; + else + file = binaryFile; + + return file.substring(file.lastIndexOf(File.separator) + 1, file.length()); + } + + /** + * If lookup() was successful, returns the line number of addr. If the line number could not + * be determined, -1 is returned. + */ + public int getLineNum() + { + return lineNum; + } + + public void lookup (String file, long addr) + { + binaryFile = file; + sourceFile = null; + lineNum = -1; + + if (! use_addr2line || blacklist.contains(file)) + return; + Addr2Line addr2line = (Addr2Line) procs.get(file); + if (addr2line == null) + { + addr2line = new Addr2Line(file); + procs.put(file, addr2line); + } + + if (addr2line.proc == null) + { + use_addr2line = false; + return; + } + + String hexAddr = "0x" + Long.toHexString(addr); + String name; + + try + { + addr2line.out.write(hexAddr); + addr2line.out.newLine(); + addr2line.out.flush(); + String result = addr2line.in.readLine(); + + if (result.indexOf("??") == -1) + { + int split = result.lastIndexOf(':'); + sourceFile = result.substring(0, split); + String lineNumStr = result.substring(split + 1, result.length()); + lineNum = Integer.parseInt (lineNumStr); + } + else + { + /* This binary has no debug info (assuming addr was valid). + Avoid repeat addr2line invocations. */ + blacklist.add(binaryFile); + } + } + catch (IOException ioe) + { + addr2line = null; + } + catch (NumberFormatException x) + { + } + } + + /** + * Returns human readable method name and aguments given a method type + * signature as known to the interpreter and a classname. + */ + public static String demangleInterpreterMethod(String m, String cn) + { + int index = 0; + int length = m.length(); + StringBuffer sb = new StringBuffer(length); + + // Figure out the real method name + if (m.startsWith("")) + { + String className; + int i = cn.lastIndexOf('.'); + if (i < 0) + className = cn; + else + className = cn.substring(i + 1); + sb.append(className); + index += 7; + } + else + { + int i = m.indexOf('('); + if (i > 0) + { + sb.append(m.substring(0,i)); + index += i + 1; + } + } + + sb.append('('); + + // Demangle the type arguments + int arrayDepth = 0; + char c = (index < length) ? m.charAt(index) : ')'; + while (c != ')') + { + String type; + switch(c) + { + case 'B': + type = "byte"; + break; + case 'C': + type = "char"; + break; + case 'D': + type = "double"; + break; + case 'F': + type = "float"; + break; + case 'I': + type = "int"; + break; + case 'J': + type = "long"; + break; + case 'S': + type = "short"; + break; + case 'Z': + type = "boolean"; + break; + case 'L': + int i = m.indexOf(';', index); + if (i > 0) + { + type = m.substring(index+1, i); + index = i; + } + else + type = ""; + break; + case '[': + type = ""; + arrayDepth++; + break; + default: + type = "'; + } + sb.append(type); + + // Handle arrays + if (c != '[' && arrayDepth > 0) + while (arrayDepth > 0) + { + sb.append("[]"); + arrayDepth--; + } + + index++; + char nc = (index < length) ? m.charAt(index) : ')'; + if (c != '[' && nc != ')') + sb.append(", "); + c = nc; + } + + // Stop. We are not interested in the return type. + sb.append(')'); + return sb.toString(); + } + + /** + * Releases all resources used by this NameFinder. + */ + public void close() + { + Iterator itr = procs.values().iterator(); + while (itr.hasNext()) + { + Addr2Line proc = (Addr2Line) itr.next(); + proc.close(); + } + } +} -- cgit v1.2.3