printing stack crawls with LXR URLs.

git-svn-id: svn://10.0.0.236/trunk@50472 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
beard%netscape.com
1999-10-12 18:59:52 +00:00
parent 980b8b883b
commit fa0386eb21

View File

@@ -40,20 +40,22 @@ import java.util.*;
class Leak {
String mAddress;
Object[] mReferences;
Object[] mCrawl;
int mRefCount;
int mSize;
String mType;
Leak(String addr, String type, Object[] refs, int size) {
Leak(String addr, String type, Object[] refs, Object[] crawl, int size) {
mAddress = addr;
mReferences = refs;
mCrawl = crawl;
mRefCount = 0;
mSize = size;
mType = type;
}
public String toString() {
return (mAddress + " [" + mRefCount + "] (" + mSize + ") " + mType);
return (mAddress + " [" + mRefCount + "] " + mType + " (" + mSize + ") " + mType);
}
static class Comparator implements QuickSort.Comparator {
@@ -69,6 +71,55 @@ class Leak {
}
}
class FileTable {
static class Line {
int mOffset;
int mLength;
Line(int offset, int length) {
mOffset = offset;
mLength = length;
}
}
Line[] mLines;
FileTable(String path) throws IOException {
Vector lines = new Vector();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
int offset = 0;
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
// always add 1 for the line feed.
int length = 1 + line.length();
lines.addElement(new Line(offset, length));
offset += length;
}
reader.close();
int size = lines.size();
mLines = new Line[size];
lines.copyInto(mLines);
}
public int getLine(int offset) {
// use binary search to find the line which spans this offset.
int length = mLines.length;
int minIndex = 0, maxIndex = length - 1;
int index = maxIndex / 2;
while (minIndex < maxIndex) {
Line line = mLines[index];
if (offset < line.mOffset) {
maxIndex = (index - 1);
index = (minIndex + maxIndex) / 2;
} else {
if (offset < (line.mOffset + line.mLength))
break;
minIndex = (index + 1);
index = (minIndex + maxIndex) / 2;
}
}
return (1 + index);
}
}
public class leaksoup {
public static void main(String[] args) {
if (args.length == 0) {
@@ -95,12 +146,23 @@ public class leaksoup {
} catch (NumberFormatException nfe) {
size = 0;
}
// read in fields.
vec.setSize(0);
for (line = reader.readLine(); line != null && line.charAt(0) == '\t'; line = reader.readLine())
vec.addElement(line.substring(1, 11));
Object[] refs = new Object[vec.size()];
vec.copyInto(refs);
table.put(addr, new Leak(addr, type, refs, size));
// read in stack crawl.
vec.setSize(0);
for (line = reader.readLine(); line != null && !line.equals("Leaked composite object at:"); line = reader.readLine())
vec.addElement(line.intern());
Object[] crawl = new Object[vec.size()];
vec.copyInto(crawl);
// record the leak.
table.put(addr, new Leak(addr, type, refs, crawl, size));
if (type.equals("<void*>"))
type = "(" + size + ") <void*>";
hist.record(type);
@@ -153,6 +215,38 @@ public class leaksoup {
}
}
static final String MOZILLA_BASE = "mozilla/";
static final String LXR_BASE = "http://lxr.mozilla.org/seamonkey/source/";
static String getFileLocation(Hashtable fileTables, String line) throws IOException {
int leftBracket = line.indexOf('[');
if (leftBracket == -1)
return line;
int comma = line.indexOf(',', leftBracket + 1);
int rightBracket = line.indexOf(']', leftBracket + 1);
String macPath = line.substring(leftBracket + 1, comma);
String path = macPath.replace(':', '/');
int mozillaIndex = path.indexOf(MOZILLA_BASE);
String locationURL;
if (mozillaIndex > -1)
locationURL = LXR_BASE + path.substring(path.indexOf(MOZILLA_BASE) + MOZILLA_BASE.length());
else
locationURL = "file:///" + path;
int offset = 0;
try {
offset = Integer.parseInt(line.substring(comma + 1, rightBracket));
} catch (NumberFormatException nfe) {
return line;
}
FileTable table = (FileTable) fileTables.get(path);
if (table == null) {
table = new FileTable("/" + path);
fileTables.put(path, table);
}
int lineNumber = table.getLine(offset);
return line.substring(0, leftBracket) + "[" + locationURL + "#" + lineNumber + "]";
}
static void printLeaks(PrintStream out, Leak[] leaks, int leakCount, long totalSize) throws IOException {
// sort the leaks by reference count.
QuickSort sorter = new QuickSort(new Leak.Comparator());
@@ -163,14 +257,24 @@ public class leaksoup {
out.println("total objects leaked = " + leakCount);
out.println("total memory leaked = " + totalSize + " bytes.");
Hashtable fileTables = new Hashtable();
// now, print the report, sorted by reference count.
for (int i = 0; i < leakCount; i++) {
Leak leak = leaks[i];
out.println(leak);
// print object's fields:
Object[] refs = leak.mReferences;
int count = refs.length;
for (int j = 0; j < count; j++)
out.println("\t" + refs[j]);
// print object's stack crawl:
Object[] crawl = leak.mCrawl;
count = crawl.length;
for (int j = 0; j < count; j++) {
String location = getFileLocation(fileTables, (String) crawl[j]);
out.println(location);
}
}
}