From eb01395a76f25d1245bfc02f8e2a8b303c1e35a2 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Tue, 27 Jan 2004 02:36:54 +0000 Subject: [PATCH] Debuging helping tools. --- .../cdt/utils/debug/tools/DebugAddr2line.java | 129 ++++++++ .../cdt/utils/debug/tools/DebugDump.java | 312 ++++++++++++++++++ .../cdt/utils/debug/tools/DebugSym.java | 53 +++ .../utils/debug/tools/DebugSymsRequestor.java | 222 +++++++++++++ 4 files changed, 716 insertions(+) create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSym.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java new file mode 100644 index 00000000000..3d77995029a --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugAddr2line.java @@ -0,0 +1,129 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.utils.debug.tools; + +import java.io.IOException; + +import org.eclipse.cdt.utils.debug.dwarf.Dwarf; +import org.eclipse.cdt.utils.debug.stabs.Stabs; +import org.eclipse.cdt.utils.elf.Elf; + +/** + * StabsAddr2ine + * + * @author alain + */ +public class DebugAddr2line { + + DebugSymsRequestor symreq; + + public DebugAddr2line(String file) throws IOException { + Elf elf = new Elf(file); + init(elf); + elf.dispose(); + } + + public DebugAddr2line(Elf elf) throws IOException { + init(elf); + } + + void init(Elf elf) throws IOException { + symreq = new DebugSymsRequestor(); + Elf.Attribute attribute = elf.getAttributes(); + int type = attribute.getDebugType(); + if (type == Elf.Attribute.DEBUG_TYPE_STABS) { + Stabs stabs = new Stabs(elf); + stabs.parse(symreq); + } else if (type == Elf.Attribute.DEBUG_TYPE_DWARF) { + Dwarf dwarf = new Dwarf(elf); + dwarf.parse(symreq); + } else { + throw new IOException("Unknown debug format"); + } + } + + /* + * (non-Javadoc) + * + * @see IAddr2line#dispose() + */ + public void dispose() { + } + + /* + * (non-Javadoc) + * + * @see IAddr2line#getStartLine(long) + */ + public int getStartLine(long address) throws IOException { + DebugSym entry = symreq.getEntry(address); + if (entry != null) { + return entry.startLine; + } + return 0; + } + + /* + * (non-Javadoc) + * + * @see IAddr2line#getEndLine(long) + */ + public int getEndLine(long address) throws IOException { + DebugSym entry = symreq.getEntry(address); + if (entry != null) { + return entry.endLine; + } + return 0; + } + + /* + * (non-Javadoc) + * + * @see IAddr2line#getFunction(long) + */ + public String getFunction(long address) throws IOException { + DebugSym entry = symreq.getEntry(address); + if (entry != null) { + return entry.name; + } + return null; + } + + /* + * (non-Javadoc) + * + * @see IAddr2line#getFileName(long) + */ + public String getFileName(long address) throws IOException { + DebugSym entry = symreq.getEntry(address); + if (entry != null) { + return entry.filename; + } + return null; + } + + public static void main(String[] args) { + try { + DebugAddr2line addr2line = new DebugAddr2line(args[0]); + long address = Integer.decode(args[1]).longValue(); + int startLine = addr2line.getStartLine(address); + int endLine = addr2line.getEndLine(address); + String function = addr2line.getFunction(address); + String filename = addr2line.getFileName(address); + System.out.println(Long.toHexString(address)); + System.out.println(filename + ":" + function + ":" + startLine + ":" + endLine); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java new file mode 100644 index 00000000000..dfb63c3d301 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugDump.java @@ -0,0 +1,312 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.utils.debug.tools; + +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.utils.debug.DebugBaseType; +import org.eclipse.cdt.utils.debug.DebugParameterKind; +import org.eclipse.cdt.utils.debug.DebugType; +import org.eclipse.cdt.utils.debug.DebugVariableKind; +import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; +import org.eclipse.cdt.utils.debug.dwarf.Dwarf; +import org.eclipse.cdt.utils.debug.stabs.Stabs; +import org.eclipse.cdt.utils.elf.Elf; + +/** + * DebugDump + * + */ +public class DebugDump implements IDebugEntryRequestor { + + List list = new ArrayList(); + BufferedWriter bwriter; + int bracket; + int paramCount = -1; + + String currentCU; + + public DebugDump(OutputStream stream){ + bwriter = new BufferedWriter(new OutputStreamWriter(stream)); + } + + void parse(String file) throws IOException { + Elf elf = new Elf(file); + parse(elf); + elf.dispose(); + } + + void parse(Elf elf) throws IOException { + Elf.Attribute attribute = elf.getAttributes(); + int type = attribute.getDebugType(); + if (type == Elf.Attribute.DEBUG_TYPE_STABS) { + Stabs stabs = new Stabs(elf); + stabs.parse(this); + } else if (type == Elf.Attribute.DEBUG_TYPE_DWARF) { + Dwarf dwarf = new Dwarf(elf); + dwarf.parse(this); + } else { + throw new IOException("Unknown debug format"); + } + bwriter.flush(); + } + + void write(String s) { + try { + bwriter.write(s, 0, s.length()); + } catch (IOException e) { + // ignore. + } + } + + void newLine() { + try { + bwriter.newLine(); + } catch (IOException e) { + // ignore + } + } + + String printTabs() { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < bracket; i++) { + sb.append('\t'); + } + return sb.toString(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCompilationUnit(java.lang.String, long) + */ + public void enterCompilationUnit(String name, long address) { + write("/* Enter Compilation Unit " + name + " address " + Long.toHexString(address) + " */"); + newLine(); + currentCU = name; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCompilationUnit(long) + */ + public void exitCompilationUnit(long address) { + write("/* Exit Compilation Unit "); + if (currentCU != null) { + write(currentCU + " address " + Long.toHexString(address)); + } + write(" */"); + newLine();newLine(); + currentCU = null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterInclude(java.lang.String) + */ + public void enterInclude(String name) { + write("#include \"" + name + "\" "); + write("/* Enter Include */"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitInclude() + */ + public void exitInclude() { + //write("/* Exit Include */"); + //newLine();newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterFunction(java.lang.String, int, boolean, long) + */ + public void enterFunction(String name, DebugType type, boolean isGlobal, long address) { + write("/* Func:" + name + " address " + Long.toHexString(address) + " */"); + newLine(); + if (!isGlobal) { + write("static "); + } + write(type.toString() + " " + name + "("); + paramCount = 0; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitFunction(long) + */ + public void exitFunction(long address) { + if (paramCount > -1) { + paramCount = -1; + write(")"); + newLine(); + write("{"); + newLine(); + bracket++; + } + for (; bracket > 0; bracket--) { + write("}"); + } + write(" /* Exit Func address " + Long.toHexString(address) + " */"); + newLine();newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCodeBlock(long) + */ + public void enterCodeBlock(long offset) { + if (paramCount > -1) { + paramCount = -1; + write(")"); + newLine(); + } + write(printTabs() + "{ " + "/* " + offset + " */"); + newLine(); + bracket++; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCodeBlock(long) + */ + public void exitCodeBlock(long offset) { + bracket--; + write(printTabs() + "} " + "/* " + offset + " */"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptStatement(int, long) + */ + public void acceptStatement(int line, long address) { + if (paramCount > -1) { + write(")"); + newLine(); + write("{"); + newLine(); + bracket++; + paramCount = -1; + } + write(printTabs() + "/* line " + line + " address " + address + " */"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptIntegerConst(java.lang.String, long) + */ + public void acceptIntegerConst(String name, int value) { + write("const int " + name + " = " + value + ";"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptFloatConst(java.lang.String, double) + */ + public void acceptFloatConst(String name, double value) { + write("const float " + name + " = " + value + ";"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeConst(java.lang.String, + * org.eclipse.cdt.utils.debug.DebugType, int) + */ + public void acceptTypeConst(String name, DebugType type, int value) { + write("const " + type.toString() + " " + name + " = " + value + ";"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptParameter(java.lang.String, int, int, long) + */ + public void acceptParameter(String name, DebugType type, DebugParameterKind kind, long offset) { + if (paramCount > 0) { + write(", "); + } + paramCount++; + write(type.toString() + " " + name + "/* " + offset + " */"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptVariable(java.lang.String, int, int, long) + */ + public void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address) { + write(printTabs() + type.toString() + " " + name + ";" + "/* " + Long.toHexString(address) + " */"); + newLine(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptCaughtException(java.lang.String, + * org.eclipse.cdt.utils.debug.DebugType, long) + */ + public void acceptCaughtException(String name, DebugType type, long address) { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeDef(java.lang.String, org.eclipse.cdt.utils.debug.DebugType) + */ + public void acceptTypeDef(String name, DebugType type) { + if (!name.equals(type.toString())) { + write("typedef " + type.toString() + " " + name + ";"); + newLine(); + } else if (type instanceof DebugBaseType){ + DebugBaseType baseType =(DebugBaseType)type; + write("/* " + name + ": " + baseType.sizeof() + " bytes */"); + newLine(); + } else { + //int x = 9; + } + } + + public static void main(String[] args) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + DebugDump dump = new DebugDump(System.out); + dump.parse(args[0]); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSym.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSym.java new file mode 100644 index 00000000000..310f7848cf0 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSym.java @@ -0,0 +1,53 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.utils.debug.tools; + + +public class DebugSym implements Comparable { + + public long addr; + public long size; + public int startLine; + public int endLine; + public String name; + public String type; + public String filename; + + public DebugSym() { + } + + public int compareTo(Object obj) { + long thisVal = 0; + long anotherVal = 0; + if (obj instanceof DebugSym) { + DebugSym entry = (DebugSym) obj; + thisVal = this.addr; + anotherVal = entry.addr; + } else if (obj instanceof Long) { + Long val = (Long) obj; + anotherVal = val.longValue(); + thisVal = (long) this.addr; + } + return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append("Type:").append(type).append("\n"); + buf.append("Name: ").append(name).append("\n"); + buf.append("\taddress:").append("0x").append(Long.toHexString(addr)).append("\n"); + buf.append("\tstartLine:").append(startLine).append("\n"); + buf.append("\tendLine:").append(endLine).append("\n"); + buf.append("\tSize:").append(size).append("\n"); + return buf.toString(); + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java new file mode 100644 index 00000000000..3e96f067b94 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/tools/DebugSymsRequestor.java @@ -0,0 +1,222 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.utils.debug.tools; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.utils.debug.DebugParameterKind; +import org.eclipse.cdt.utils.debug.DebugType; +import org.eclipse.cdt.utils.debug.DebugVariableKind; +import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; + + +/** + * DebugSymsRequestor + * + */ +public class DebugSymsRequestor implements IDebugEntryRequestor { + + DebugSym currentCU; + DebugSym currentFunction; + + List list = new ArrayList(); + + /** + * + */ + public DebugSymsRequestor() { + super(); + } + + public DebugSym[] getSortedEntries() { + DebugSym[] syms = getEntries(); + Arrays.sort(syms); + return syms; + } + + public DebugSym[] getEntries() { + DebugSym[] syms = new DebugSym[list.size()]; + list.toArray(syms); + return syms; + } + + public DebugSym getEntry(long addr) { + DebugSym[] entries = getSortedEntries(); + int insertion = Arrays.binarySearch(entries, new Long(addr)); + if (insertion >= 0) { + return entries[insertion]; + } + if (insertion == -1) { + return null; + } + insertion = -insertion - 1; + DebugSym entry = entries[insertion - 1]; + if (addr < (entry.addr + entry.size)) { + return entries[insertion - 1]; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCompilationUnit(java.lang.String, long) + */ + public void enterCompilationUnit(String name, long address) { + DebugSym sym = new DebugSym(); + sym.name = name; + sym.addr = address; + sym.type = "CU"; + sym.filename = name; + currentCU = sym; + list.add(sym); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCompilationUnit(long) + */ + public void exitCompilationUnit(long address) { + if (currentCU != null) { + currentCU.size = address; + } + currentCU = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterInclude(java.lang.String) + */ + public void enterInclude(String name) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitInclude() + */ + public void exitInclude() { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterFunction(java.lang.String, int, boolean, long) + */ + public void enterFunction(String name, DebugType type, boolean isGlobal, long address) { + DebugSym sym = new DebugSym(); + sym.name = name; + sym.addr = address; + sym.type = "Func"; + if (currentCU != null) { + sym.filename = currentCU.filename; + } + currentFunction = sym; + list.add(sym); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitFunction(long) + */ + public void exitFunction(long address) { + if (currentFunction != null) { + currentFunction.size = address; + } + currentFunction = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#enterCodeBlock(long) + */ + public void enterCodeBlock(long offset) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#exitCodeBlock(long) + */ + public void exitCodeBlock(long offset) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptStatement(int, long) + */ + public void acceptStatement(int line, long address) { + DebugSym sym = new DebugSym(); + sym.name = ""; + sym.addr = address; + sym.startLine = line; + sym.type = "SLINE"; + if (currentFunction != null) { + if (currentFunction.startLine == 0) { + currentFunction.startLine = line; + } + currentFunction.endLine = line; + } + if (currentCU != null) { + sym.filename = currentCU.filename; + } + list.add(sym); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptIntegerConst(java.lang.String, long) + */ + public void acceptIntegerConst(String name, int value) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptFloatConst(java.lang.String, double) + */ + public void acceptFloatConst(String name, double value) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeConst(java.lang.String, org.eclipse.cdt.utils.debug.DebugType, int) + */ + public void acceptTypeConst(String name, DebugType type, int value) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptParameter(java.lang.String, int, int, long) + */ + public void acceptParameter(String name, DebugType type, DebugParameterKind kind, long offset) { + DebugSym sym = new DebugSym(); + sym.name = name; + sym.addr = offset; + sym.type = "PARAM"; + if (currentCU != null) { + sym.filename = currentCU.filename; + } + list.add(sym); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptVariable(java.lang.String, int, int, long) + */ + public void acceptVariable(String name, DebugType type, DebugVariableKind kind, long address) { + DebugSym sym = new DebugSym(); + sym.name = name; + sym.addr = address; + sym.type = "VAR"; + if (currentCU != null) { + sym.filename = currentCU.filename; + } + list.add(sym); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptCaughtException(java.lang.String, org.eclipse.cdt.utils.debug.DebugType, long) + */ + public void acceptCaughtException(String name, DebugType type, long address) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.debug.IDebugEntryRequestor#acceptTypeDef(java.lang.String, org.eclipse.cdt.utils.debug.DebugType) + */ + public void acceptTypeDef(String name, DebugType type) { + } + +}