aboutsummaryrefslogtreecommitdiffstats
path: root/ddms
diff options
context:
space:
mode:
authorSiva Velusamy <vsiva@google.com>2011-09-20 15:28:10 -0700
committerSiva Velusamy <vsiva@google.com>2011-09-20 16:57:24 -0700
commit9ab5464b15ce50ec1fdd09c1d688afd1a5b25138 (patch)
treea2be7057741d1dee3094067feac32c6723fc7cfd /ddms
parent88ee5dd5573f9700f6d5983af524b8eaf82665be (diff)
downloadsdk-9ab5464b15ce50ec1fdd09c1d688afd1a5b25138.zip
sdk-9ab5464b15ce50ec1fdd09c1d688afd1a5b25138.tar.gz
sdk-9ab5464b15ce50ec1fdd09c1d688afd1a5b25138.tar.bz2
Display stack trace for selected Heap Allocation.
Minor changes in a few other places to return List's instead of arrays. Change-Id: I25ddc25ebc1c91677d16e9d77dc0f8a51022bc1b
Diffstat (limited to 'ddms')
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java5
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java8
-rw-r--r--ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java28
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java2
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java25
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java46
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java5
-rw-r--r--ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackLabelProvider.java69
8 files changed, 152 insertions, 36 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
index 6cc93c9..5c176cf 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
@@ -173,6 +173,11 @@ final class HandleNativeHeap extends ChunkHandler {
for (int j = 0 ; j < backtraceSize ; j++) {
long addr = (buffer.getInt()) & 0x00000000ffffffffL;
+ if (addr == 0x0) {
+ // skip past null addresses
+ continue;
+ }
+
info.addStackCallAddress(addr);;
}
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java b/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
index 4c9e798..0aab76c 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
@@ -120,8 +120,8 @@ public final class NativeAllocationInfo {
* Returns the stack call of this allocation as raw addresses.
* @return the list of addresses where the allocation happened.
*/
- public Long[] getStackCallAddresses() {
- return mStackCallAddresses.toArray(new Long[mStackCallAddresses.size()]);
+ public List<Long> getStackCallAddresses() {
+ return mStackCallAddresses;
}
/**
@@ -148,9 +148,9 @@ public final class NativeAllocationInfo {
* @see #setResolvedStackCall(ArrayList)
* @see #isStackCallResolved()
*/
- public synchronized NativeStackCallInfo[] getResolvedStackCall() {
+ public synchronized List<NativeStackCallInfo> getResolvedStackCall() {
if (mIsStackCallResolved) {
- return mResolvedStackCall.toArray(new NativeStackCallInfo[mResolvedStackCall.size()]);
+ return mResolvedStackCall;
}
return null;
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java b/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
index e54818d..450eb6a 100644
--- a/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
+++ b/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
@@ -25,7 +25,10 @@ import java.util.regex.Pattern;
*/
public final class NativeStackCallInfo {
private final static Pattern SOURCE_NAME_PATTERN = Pattern.compile("^(.+):(\\d+)$");
-
+
+ /** address of this stack frame */
+ private long mAddress;
+
/** name of the library */
private String mLibrary;
@@ -37,21 +40,23 @@ public final class NativeStackCallInfo {
* &lt;sourcefile&gt;:&lt;linenumber&gt;
*/
private String mSourceFile;
-
- private int mLineNumber = -1;
+
+ private int mLineNumber = -1;
/**
* Basic constructor with library, method, and sourcefile information
*
+ * @param address address of this stack frame
* @param lib The name of the library
* @param method the name of the method
* @param sourceFile the name of the source file and the line number
* as "[sourcefile]:[fileNumber]"
*/
- public NativeStackCallInfo(String lib, String method, String sourceFile) {
+ public NativeStackCallInfo(long address, String lib, String method, String sourceFile) {
+ mAddress = address;
mLibrary = lib;
mMethod = method;
-
+
Matcher m = SOURCE_NAME_PATTERN.matcher(sourceFile);
if (m.matches()) {
mSourceFile = m.group(1);
@@ -64,7 +69,14 @@ public final class NativeStackCallInfo {
mSourceFile = sourceFile;
}
}
-
+
+ /**
+ * Returns the address of this stack frame.
+ */
+ public long getAddress() {
+ return mAddress;
+ }
+
/**
* Returns the name of the library name.
*/
@@ -72,13 +84,13 @@ public final class NativeStackCallInfo {
return mLibrary;
}
- /**
+ /**
* Returns the name of the method.
*/
public String getMethodName() {
return mMethod;
}
-
+
/**
* Returns the name of the source file.
*/
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
index c921ac2..1180a96 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
@@ -271,7 +271,7 @@ public class Addr2Line {
// make the backtrace object and return it
if (method != null && source != null) {
- return new NativeStackCallInfo(mLibrary, method, source);
+ return new NativeStackCallInfo(addr, mLibrary, method, source);
}
} catch (IOException e) {
// log the error
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
index a1ded0d..a37a865 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
@@ -66,6 +66,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
/**
* Panel with native heap information.
@@ -270,14 +271,14 @@ public final class NativeHeapPanel extends BaseHeapPanel {
NativeAllocationInfo info = iter.next();
if (info.isStackCallResolved() == false) {
- final Long[] list = info.getStackCallAddresses();
- final int size = list.length;
+ final List<Long> list = info.getStackCallAddresses();
+ final int size = list.size();
ArrayList<NativeStackCallInfo> resolvedStackCall =
new ArrayList<NativeStackCallInfo>();
for (int i = 0; i < size; i++) {
- long addr = list[i];
+ long addr = list.get(i);
// first check if the addr has already been converted.
NativeStackCallInfo source = mSourceCache.get(addr);
@@ -325,8 +326,10 @@ public final class NativeHeapPanel extends BaseHeapPanel {
}
}
- return new NativeStackCallInfo(library != null ? library.getLibraryName() : null,
- Long.toHexString(addr), "");
+ return new NativeStackCallInfo(addr,
+ library != null ? library.getLibraryName() : null,
+ Long.toHexString(addr),
+ "");
}
private NativeLibraryMapInfo getLibraryFor(long addr) {
@@ -1120,20 +1123,20 @@ public final class NativeHeapPanel extends BaseHeapPanel {
try {
// populate the detail Table with the back trace
- Long[] addresses = mi.getStackCallAddresses();
- NativeStackCallInfo[] resolvedStackCall = mi.getResolvedStackCall();
+ List<Long> addresses = mi.getStackCallAddresses();
+ List<NativeStackCallInfo> resolvedStackCall = mi.getResolvedStackCall();
if (resolvedStackCall == null) {
return;
}
- for (int i = 0 ; i < resolvedStackCall.length ; i++) {
- if (addresses[i] == null || addresses[i].longValue() == 0) {
+ for (int i = 0 ; i < resolvedStackCall.size(); i++) {
+ if (addresses.get(i) == null || addresses.get(i).longValue() == 0) {
continue;
}
- long addr = addresses[i].longValue();
- NativeStackCallInfo source = resolvedStackCall[i];
+ long addr = addresses.get(i).longValue();
+ NativeStackCallInfo source = resolvedStackCall.get(i);
TableItem item = new TableItem(mDetailTable, SWT.NONE);
item.setText(0, String.format("%08x", addr)); //$NON-NLS-1$
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java
index 1b25c96..bc545c7 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java
@@ -46,6 +46,7 @@ import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
import java.text.NumberFormat;
import java.util.ArrayList;
@@ -84,10 +85,7 @@ public class NativeHeapPanel extends BaseHeapPanel {
private Combo mSnapshotIndexCombo;
private Label mMemoryAllocatedText;
- private Tree mDetailsTree;
private TreeViewer mDetailsTreeViewer;
-
- private Tree mStackTraceTree;
private TreeViewer mStackTraceTreeViewer;
private ToolBar mDetailsToolBar;
@@ -171,6 +169,7 @@ public class NativeHeapPanel extends BaseHeapPanel {
}
displaySnapshot(lastHeapSnapshot);
+ displayStackTraceForSelection();
}
});
}
@@ -344,16 +343,16 @@ public class NativeHeapPanel extends BaseHeapPanel {
mDetailsToolBar = new ToolBar(c, SWT.FLAT | SWT.BORDER);
initializeDetailsToolBar(mDetailsToolBar);
- mDetailsTree = new Tree(c, SWT.VIRTUAL | SWT.BORDER);
- initializeDetailsTree(mDetailsTree);
+ Tree detailsTree = new Tree(c, SWT.VIRTUAL | SWT.BORDER);
+ initializeDetailsTree(detailsTree);
final Sash sash = new Sash(c, SWT.HORIZONTAL | SWT.BORDER);
Label stackTraceLabel = new Label(c, SWT.NONE);
stackTraceLabel.setText("Stack Trace:");
- mStackTraceTree = new Tree(c, SWT.BORDER);
- initializeStackTraceTree(mStackTraceTree);
+ Tree stackTraceTree = new Tree(c, SWT.BORDER);
+ initializeStackTraceTree(stackTraceTree);
// layout the widgets created above
FormData data = new FormData();
@@ -367,7 +366,7 @@ public class NativeHeapPanel extends BaseHeapPanel {
data.bottom = new FormAttachment(sash, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
- mDetailsTree.setLayoutData(data);
+ detailsTree.setLayoutData(data);
final FormData sashData = new FormData();
sashData.top = new FormAttachment(mPrefStore.getInt(PREFS_SASH_HEIGHT_PERCENT), 0);
@@ -386,7 +385,7 @@ public class NativeHeapPanel extends BaseHeapPanel {
data.left = new FormAttachment(0, 0);
data.bottom = new FormAttachment(100, 0);
data.right = new FormAttachment(100, 0);
- mStackTraceTree.setLayoutData(data);
+ stackTraceTree.setLayoutData(data);
sash.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
@@ -463,6 +462,13 @@ public class NativeHeapPanel extends BaseHeapPanel {
mDetailsTreeViewer.setLabelProvider(new NativeHeapLabelProvider());
mDetailsTreeViewer.setInput(null);
+
+ tree.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ displayStackTraceForSelection();
+ }
+ });
}
private void initializeStackTraceTree(Tree tree) {
@@ -494,10 +500,32 @@ public class NativeHeapPanel extends BaseHeapPanel {
mStackTraceTreeViewer = new TreeViewer(tree);
mStackTraceTreeViewer.setContentProvider(new NativeStackContentProvider());
+ mStackTraceTreeViewer.setLabelProvider(new NativeStackLabelProvider());
mStackTraceTreeViewer.setInput(null);
}
+ private void displayStackTraceForSelection() {
+ TreeItem []items = mDetailsTreeViewer.getTree().getSelection();
+ if (items.length == 0) {
+ mStackTraceTreeViewer.setInput(null);
+ return;
+ }
+
+ Object data = items[0].getData();
+ if (!(data instanceof NativeAllocationInfo)) {
+ mStackTraceTreeViewer.setInput(null);
+ return;
+ }
+
+ NativeAllocationInfo info = (NativeAllocationInfo) data;
+ if (info.isStackCallResolved()) {
+ mStackTraceTreeViewer.setInput(info.getResolvedStackCall());
+ } else {
+ mStackTraceTreeViewer.setInput(info.getStackCallAddresses());
+ }
+ }
+
private String getPref(String prefix, String s) {
return "nativeheap.tree." + prefix + "." + s;
}
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java
index a83164b..54001d2 100644
--- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java
@@ -23,7 +23,7 @@ import java.util.List;
public class NativeStackContentProvider implements ITreeContentProvider {
public Object[] getElements(Object arg0) {
- return null;
+ return getChildren(arg0);
}
public void dispose() {
@@ -34,8 +34,7 @@ public class NativeStackContentProvider implements ITreeContentProvider {
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof List<?>) {
- List<?> stack = (List<?>) parentElement;
- return stack.toArray();
+ return ((List<?>) parentElement).toArray();
}
return null;
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackLabelProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackLabelProvider.java
new file mode 100644
index 0000000..e59e787
--- /dev/null
+++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackLabelProvider.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.heap;
+
+import com.android.ddmlib.NativeStackCallInfo;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+public class NativeStackLabelProvider extends LabelProvider implements ITableLabelProvider {
+ public Image getColumnImage(Object arg0, int arg1) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int index) {
+ if (element instanceof NativeStackCallInfo) {
+ return getResolvedStackTraceColumnText((NativeStackCallInfo) element, index);
+ }
+
+ if (element instanceof Long) {
+ // if the addresses have not been resolved, then just display the
+ // addresses alone
+ return getStackAddressColumnText((Long) element, index);
+ }
+
+ return null;
+ }
+
+ public String getResolvedStackTraceColumnText(NativeStackCallInfo info, int index) {
+ switch (index) {
+ case 0:
+ return String.format("0x%08x", info.getAddress());
+ case 1:
+ return info.getLibraryName();
+ case 2:
+ return info.getMethodName();
+ case 3:
+ return info.getSourceFile();
+ case 4:
+ int l = info.getLineNumber();
+ return l == -1 ? "" : Integer.toString(l);
+ }
+
+ return null;
+ }
+
+ private String getStackAddressColumnText(Long address, int index) {
+ if (index == 0) {
+ return String.format("0x%08x", address);
+ }
+
+ return null;
+ }
+}