diff options
author | Siva Velusamy <vsiva@google.com> | 2011-09-20 15:28:10 -0700 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2011-09-20 16:57:24 -0700 |
commit | 9ab5464b15ce50ec1fdd09c1d688afd1a5b25138 (patch) | |
tree | a2be7057741d1dee3094067feac32c6723fc7cfd /ddms | |
parent | 88ee5dd5573f9700f6d5983af524b8eaf82665be (diff) | |
download | sdk-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')
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 { * <sourcefile>:<linenumber> */ 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; + } +} |