From fd7ead45b8e0e3743c457b9192a452848d70b23f Mon Sep 17 00:00:00 2001 From: woojin Date: Thu, 7 Nov 2013 15:27:36 +0900 Subject: [PATCH] [Title] callstack / function profiling bug fix [Desc.] 1. additional handling routine for virtual thunk is no longer necessary 2. CallstackTree is maintained per tid 3. add isAddrInBinaryRange function [Issue] --- .../swap/callstack/SWAPCallStackManager.java | 67 +++++++++++----------- .../ui/summary/profiling/ProfileDataMaker.java | 26 ++++++--- .../tizen/dynamicanalyzer/utils/AnalyzerUtil.java | 17 ++++++ 3 files changed, 70 insertions(+), 40 deletions(-) diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java index aa43828..1e4bbc5 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java @@ -112,7 +112,7 @@ public class SWAPCallStackManager extends BaseCallstackManager { if (size == 0) { userCallstack.add(new CallStackItem(selfCallstackUnit, time)); } else { - if (!AnalyzerManager.isInBinaryRange(callerAddr)) { + if (!AnalyzerUtil.isAddrInBinaryRange(log.getPid(), log.getTime(), callerAddr)) { CallStackUnit callbackApi = new CallStackUnit( LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, @@ -128,24 +128,24 @@ public class SWAPCallStackManager extends BaseCallstackManager { LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, defaultCallstackUnit); } - } else if (callerCallstackUnit.getFunctionName().contains( - AnalyzerConstants.VIRTUAL_THUNK)) { - CallStackUnit callbackApi = new CallStackUnit( - LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, - LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, - log); - userCallstack.add(new CallStackItem(callbackApi)); - if (addrMap - .get(LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR) == null) { - CallStackUnit defaultCallstackUnit = new CallStackUnit( - LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, - LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, - log); - addrMap.put( - LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, - defaultCallstackUnit); - } - userCallstack.add(new CallStackItem(callerCallstackUnit)); +// } else if (callerCallstackUnit.getFunctionName().contains( +// AnalyzerConstants.VIRTUAL_THUNK)) { +// CallStackUnit callbackApi = new CallStackUnit( +// LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, +// LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, +// log); +// userCallstack.add(new CallStackItem(callbackApi)); +// if (addrMap +// .get(LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR) == null) { +// CallStackUnit defaultCallstackUnit = new CallStackUnit( +// LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, +// LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, +// log); +// addrMap.put( +// LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, +// defaultCallstackUnit); +// } +// userCallstack.add(new CallStackItem(callerCallstackUnit)); } else { CallStackUnit callerCsa = addrMap.get(callerAddr); if (null == callerCsa) { @@ -176,19 +176,19 @@ public class SWAPCallStackManager extends BaseCallstackManager { if (selfCallstackUnit.getFunctionName().equals( removeCallStackUnit.getFunctionName())) { userCallstack.remove(size - 1); - if (size - 2 > 0) { - if (callerCallstackUnit.getFunctionName().contains( - AnalyzerConstants.VIRTUAL_THUNK)) { - if (callerCallstackUnit.getFunctionName().equals( - userCallstack.get(size - 2).getCallStackUnit().getFunctionName())) { - userCallstack.remove(size - 2); - } else { - System.out - .println("makeUserCallstack : [virtual thunk] EXIT caller is not the same" - + "as top of user callstack after remove EXIT self"); - } - } - } +// if (size - 2 > 0) { +// if (callerCallstackUnit.getFunctionName().contains( +// AnalyzerConstants.VIRTUAL_THUNK)) { +// if (callerCallstackUnit.getFunctionName().equals( +// userCallstack.get(size - 2).getCallStackUnit().getFunctionName())) { +// userCallstack.remove(size - 2); +// } else { +// System.out +// .println("makeUserCallstack : [virtual thunk] EXIT caller is not the same" +// + "as top of user callstack after remove EXIT self"); +// } +// } +// } size = userCallstack.size(); if (size - 1 > 0) { CallStackUnit checkCallStackUnit = userCallstack @@ -299,7 +299,8 @@ public class SWAPCallStackManager extends BaseCallstackManager { CallStackData callstackData = new CallStackData(seq); - if ((size == 0) || (!AnalyzerManager.isInBinaryRange(callerAddr))) { + if ((size == 0) || + (!AnalyzerUtil.isAddrInBinaryRange(log.getPid(), log.getTime(), callerAddr))) { CallStackUnit callbackApi = new CallStackUnit( LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR, LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, inputData); diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java index 6d537d6..ed8e91d 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java @@ -91,7 +91,7 @@ public class ProfileDataMaker { } } - private CallstackTree current = null; + private HashMap callstackTreeByTidMap = new HashMap(); private int totalSampleCount = 0; private BaseCallstackManager callstackManager = null; @@ -187,6 +187,16 @@ public class ProfileDataMaker { return symbolSeqHash; } + public CallstackTree getCurrentCallstackTree(int tid) { + CallstackTree current = callstackTreeByTidMap.get(tid); + return current; + } + + public void putCurrentCallstackTree(int tid, CallstackTree current) { + callstackTreeByTidMap.put(tid, current); + return; + } + public String getCpuRate(ProfilingData data, boolean exclusive) { int count = 0; double rate = 0.; @@ -648,6 +658,7 @@ public class ProfileDataMaker { } // calculate internal time + CallstackTree current = getCurrentCallstackTree(tid); if (type == LogCenterConstants.USER_FUNCTION_EVENT_TYPE_EXIT) { if (null == current) { // bug @@ -660,16 +671,16 @@ public class ProfileDataMaker { .getLastElapsedTime()); } child.addExclusiveElapsedTime(current.getInclusiveExeTime()); - current = current.getParent(); + putCurrentCallstackTree(tid, current.getParent()); } } else { if (null == current) { CallstackTree ct = new CallstackTree(child, null); - current = ct; + putCurrentCallstackTree(tid, ct); } else { CallstackTree ct = new CallstackTree(child, current); current.addChild(ct); - current = ct; + putCurrentCallstackTree(tid, ct); } } } @@ -731,6 +742,7 @@ public class ProfileDataMaker { } // calculate internal time + CallstackTree current = getCurrentCallstackTree(tid); if (type == MSG_FUNCTION_EXIT) { if (null == current) { // bug @@ -743,16 +755,16 @@ public class ProfileDataMaker { .getLastElapsedTime()); } child.addExclusiveElapsedTime(current.getInclusiveExeTime()); - current = current.getParent(); + putCurrentCallstackTree(tid, current.getParent()); } } else { if (null == current) { CallstackTree ct = new CallstackTree(child, null); - current = ct; + putCurrentCallstackTree(tid, ct); } else { CallstackTree ct = new CallstackTree(child, current); current.addChild(ct); - current = ct; + putCurrentCallstackTree(tid, ct); } } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/utils/AnalyzerUtil.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/utils/AnalyzerUtil.java index 04ccb51..122d147 100755 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/utils/AnalyzerUtil.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/utils/AnalyzerUtil.java @@ -1107,6 +1107,23 @@ public class AnalyzerUtil { return false; } + public static boolean isAddrInBinaryRange(int pid, long time, long addr) + { + ProcessInfoPackage processInfoPkg = AnalyzerManager + .getProject().getProcessInfo(pid); + ProcessInfo processInfo = processInfoPkg.getProcessInfo(time); + if (null == processInfo) { + return false; + } + + if (addr >= processInfo.getLowestAddress() + && addr <= processInfo.getHighestAddress()) { + return true; + } else { + return false; + } + } + public static boolean getBinaryBuildType(String localBinaryPath) { HashMap binMap = DACommunicator.getSelectedApp() .getBinaryInfoMap(); -- 2.7.4