From 853d5b375568441ee82918b257c6497b6143943d Mon Sep 17 00:00:00 2001 From: heeyoung Date: Fri, 12 Sep 2014 18:20:42 +0900 Subject: [PATCH] Merge remote-tracking branch 'origin/tizen' into da-setting Change-Id: I3f394164016ddc6acbc86959ced86dc6206b8123 Signed-off-by: heeyoung --- .../swap/callstack/BaseCallstackManager.java | 1 + .../swap/callstack/SWAPCallStackManager.java | 88 +++++ .../swap/model/data/ProfileData.java | 1 + .../ui/info/callstack/CallStackManager.java | 164 ++++++++ .../ui/network/NetworkDetailView.java | 14 +- .../dynamicanalyzer/ui/range/RangeDataManager.java | 434 +++++++++++---------- .../summary/profiling/FunctionSampleDBTable.java | 3 +- .../ui/summary/profiling/ProfileDataMaker.java | 129 ++++++ .../timeline/calltrace/FunctionEntryDBTable.java | 2 +- .../ui/timeline/calltrace/FunctionExitDBTable.java | 2 +- 10 files changed, 618 insertions(+), 220 deletions(-) diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java index d1d75e1..776d602 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java @@ -93,6 +93,7 @@ public abstract class BaseCallstackManager { protected CallStackInserter callstackInserter = null; abstract public void makeUserCallstack(LogData log, ProfileDataMaker profiler); + abstract public void makeUserCallstackforRange(LogData log, ProfileDataMaker profiler); abstract public void makeCallstackWithoutBacktrace(LogData inputData); 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 7792f15..a10d07c 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 @@ -200,6 +200,94 @@ public class SWAPCallStackManager extends BaseCallstackManager { } } + public void makeUserCallstackforRange(LogData input, ProfileDataMaker profiler) { + ProfileData pData = (ProfileData) input; + int pid = pData.getPid(); + long time = pData.getTime(); + + Map addrMap = getCallStackApiAddrByPidMap(pid); + + int tid = pData.getTid(); + long selfAddr = pData.getPcAddr(); + long callerAddr = pData.getCallerPcAddr(); + + CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); + // TODO: use callstackunit made during trace time + if (null == selfCallstackUnit) { + String strSelfFuncName = FunctionNameManager.getFunctionName(pData.getApiId()); + BinaryInfo binInfo = AnalyzerManager.getProject().getDeviceStatusInfo() + .getBinaryInfo(pData.getBinaryId()); + String strSelfSymbol = binInfo.getTargetBinaryPath() + + AnalyzerConstants.CALLSTACK_API_TOKEN_STRING + strSelfFuncName; + selfCallstackUnit = new CallStackUnit(selfAddr, strSelfSymbol, pData.getApiId(), pData); + addrMap.put(selfAddr, selfCallstackUnit); + } + + // make ProfilingData + profiler.makeFupDataForCallTrace(selfCallstackUnit, pData); + + List userCallstack = getUserCallstack(tid); + int size = userCallstack.size(); + + CallStackUnit callerCallstackUnit = addrMap.get(callerAddr); + if (null == callerCallstackUnit) { + String strCallerSymbol = getCallStackSymbol(callerAddr, pid, time); + callerCallstackUnit = new CallStackUnit(callerAddr, strCallerSymbol, pData); + addrMap.put(callerAddr, callerCallstackUnit); + } + + int eventType = pData.getId(); + if (eventType == MSG_FUNCTION_ENTRY) { + if (size == 0) { + userCallstack.add(new CallStackItem(selfCallstackUnit, time)); + } else { + if (isAddrInBinaryRange(pid, time, callerAddr)) { + // change previous top callstackunit's address to caller address of this callstackunit + CallStackUnit callerCsa = addrMap.get(callerAddr); + if (null == callerCsa) { + callerCsa = userCallstack.get(size - 1).getCallStackUnit(); + callerCsa.setFunctionStartAddr(callerCsa.getAddr()); + callerCsa.setAddr(callerAddr); + } else { + CallStackItem topCallstackItem = userCallstack.get(size - 1); + callerCsa.setFunctionStartAddr(topCallstackItem + .getCallStackUnit().getAddr()); + userCallstack.set(size - 1, new CallStackItem(callerCsa, + topCallstackItem.getStartTime())); + } + } // do nothing when call is from library + // in range analysis, user callstack is only used to make callstack of sample + // and callstack of sample does not include "~~ internal library~~" + userCallstack.add(new CallStackItem(selfCallstackUnit, time)); + } + } else if (eventType == MSG_FUNCTION_EXIT) { + if (size == 0) { + return; + } + CallStackUnit removeCallStackUnit = userCallstack.get(size - 1) + .getCallStackUnit(); + if (selfCallstackUnit.getFunctionId() == removeCallStackUnit.getFunctionId()) { + userCallstack.remove(size - 1); + size = userCallstack.size(); + if (size > 0) { + // restore start address of previous top callstackunit + CallStackItem prevCallstackItem = userCallstack.get(size - 1); + long prevSelfAddr = prevCallstackItem.getCallStackUnit() + .getFunctionStartAddr(); + CallStackUnit callerCsa = addrMap.get(prevSelfAddr); + if (null == callerCsa) { + prevCallstackItem.getCallStackUnit().setAddr(prevSelfAddr); + } else { + userCallstack.set(size - 1, new CallStackItem(callerCsa, + prevCallstackItem.getStartTime())); + } + } + } else { + Logger.error("makeUserCallstack : EXIT self is not the same as top of user callstack"); + } + } + } + public void makeCallstackWithoutBacktrace(LogData inputData) { ProbeCommonData log = (ProbeCommonData) inputData; diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ProfileData.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ProfileData.java index dd1ccb7..e664f04 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ProfileData.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ProfileData.java @@ -80,6 +80,7 @@ public class ProfileData extends LogData { /** make function sample from Database **/ public ProfileData(long time, int pid, int tid, long pcAddr) { + this.id = MSG_DATA_SAMPLE; this.time = time; this.pid = pid; this.tid = tid; diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackManager.java index 73406b7..a7c37d3 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackManager.java @@ -210,6 +210,170 @@ public class CallStackManager extends BaseCallstackManager { } } } + // TODO: will be removed with other 2.2 only code + public void makeUserCallstackforRange(LogData input, ProfileDataMaker profiler) { + UserFunctionData log = (UserFunctionData) input; + Map addrMap = getCallStackApiAddrByPidMap(log.getPid()); + boolean isPieBuild = AnalyzerUtil.isPieBuild(log.getPid(), log.getTime()); + ProcessMemoryMap pmap = AnalyzerManager.getProject() + .getProcessInformation(log.getPid()).getProcessMemoryMap(log.getTime()); + if (pmap == null) { + return; + } + + String binPath = AnalyzerUtil.getProcessLocalBinaryPath(log.getPid(), + log.getTime()); + if (null == binPath || binPath.isEmpty()) { + return; + } + + String baseAddr = Long.toString(pmap.getMainbinary().getLowestAddress()); + String strSelfAddr = Long.toString(log.getPcAddr()); + String strCallerAddr = Long.toString(log.getCallerPcAddr()); + + int seq = log.getSeq(); + int tid = log.getTid(); + + long selfAddr = log.getPcAddr(); + long callerAddr = log.getCallerPcAddr(); + + CallStackData callstackData = new CallStackData(seq); + CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); + + if (null == selfCallstackUnit) { + String strSelfFuncName = SymbolManager.addr2func(binPath, strSelfAddr, + isPieBuild, baseAddr); + String strSelfSymbol = getUserFunctionPosition() + + AnalyzerConstants.CALLSTACK_API_TOKEN_STRING + strSelfFuncName; + selfCallstackUnit = new CallStackUnit(selfAddr, strSelfSymbol, log); + addrMap.put(selfAddr, selfCallstackUnit); + } + + // insert call count + profiler.makeFupDataForCallTrace(selfCallstackUnit, log); + + List userCallstack = getUserCallstack(tid); + int size = userCallstack.size(); + + CallStackUnit callerCallstackUnit = addrMap.get(callerAddr); + if (null == callerCallstackUnit) { + String strCallerFuncName = SymbolManager.addr2func(binPath, strCallerAddr, + isPieBuild, baseAddr); + String strCallerSymbol = getUserFunctionPosition(log.getPid(), log.getTime()) + + AnalyzerConstants.CALLSTACK_API_TOKEN_STRING + strCallerFuncName; + callerCallstackUnit = new CallStackUnit(callerAddr, strCallerSymbol, log); + addrMap.put(callerAddr, callerCallstackUnit); + } + + int eventType = log.getType(); + if (eventType == LogCenterConstants.USER_FUNCTION_EVENT_TYPE_ENTER) { + if (size == 0) { + userCallstack.add(new CallStackItem(selfCallstackUnit)); + } else { + if (!AnalyzerManager.isInBinaryRange(callerAddr)) { + 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); + } + } 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) { + callerCsa = userCallstack.get(size - 1).getCallStackUnit(); + callerCsa.setFunctionStartAddr(callerCsa.getAddr()); + callerCsa.setAddr(callerAddr); + } else { + callerCsa.setFunctionStartAddr(userCallstack.get(size - 1) + .getCallStackUnit().getAddr()); + userCallstack.set(size - 1, new CallStackItem(callerCsa)); + } + } + userCallstack.add(new CallStackItem(selfCallstackUnit)); + } + size = userCallstack.size(); + for (int i = size - 1; i >= 0; i--) { + callstackData.getAddrs().add( + userCallstack.get(i).getCallStackUnit().getAddr()); + } + getCallStackDataBySeqMap().put(seq, callstackData); + } else if (eventType == LogCenterConstants.USER_FUNCTION_EVENT_TYPE_EXIT) { + if (size == 0) { + // this case only range profiling, other time is bug + return; + } + CallStackUnit removeCallStackUnit = userCallstack.get(size - 1) + .getCallStackUnit(); + 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 { + Logger.debug("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.get(size - 1) + .getCallStackUnit(); + if (checkCallStackUnit.getFunctionName().equals( + LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC)) { + userCallstack.remove(size - 1); + } + } + size = userCallstack.size(); + if (size > 0) { + CallStackUnit prevCallstackUnit = userCallstack.get(size - 1) + .getCallStackUnit(); + long prevSelfAddr = prevCallstackUnit.getFunctionStartAddr(); + CallStackUnit callerCsa = addrMap.get(prevSelfAddr); + if (null == callerCsa) { + prevCallstackUnit.setAddr(prevSelfAddr); + } else { + userCallstack.set(size - 1, new CallStackItem(callerCsa)); + } + } + } else { + Logger.debug("makeUserCallstack : EXIT self is not the same as top of user callstack"); + } + if (AnalyzerManager.isOsp()) { + // String apiName = input[LogCenterConstants.APINAME_INDEX]; + String apiName = log.getApiName(); + if (apiName.equals("OspMain")) { //$NON-NLS-1$ + LogParser.setDropCallTraceLog(true); + } + } + } + } public void makeCallstackWithoutBacktrace(LogData inputData) { Map addrMap = getCallStackApiAddrByPidMap(inputData.getPid()); diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/network/NetworkDetailView.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/network/NetworkDetailView.java index 1204869..6419556 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/network/NetworkDetailView.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/network/NetworkDetailView.java @@ -118,13 +118,15 @@ public class NetworkDetailView extends DAViewComposite { return; } DASelectionData seldata = (DASelectionData) data; - if (seldata.getData() instanceof GridItem[] == false) { - return; + if (seldata.getData() instanceof GridItem[]) { + GridItem[] tableData = (GridItem[]) data.getData(); + DATableDataFormat tableFormat = (DATableDataFormat) tableData[0].getData(); + NetworkAPIType apiType = (NetworkAPIType) tableFormat.getLogData(); + updateData(apiType.getSeq()); + }else{ + updateData(0); } - GridItem[] tableData = (GridItem[]) data.getData(); - DATableDataFormat tableFormat = (DATableDataFormat) tableData[0].getData(); - NetworkAPIType apiType = (NetworkAPIType) tableFormat.getLogData(); - updateData(apiType.getSeq()); + } @Override diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java index e018a8c..5f3ffc9 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java @@ -28,11 +28,13 @@ package org.tizen.dynamicanalyzer.ui.range; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.PriorityQueue; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; @@ -63,6 +65,7 @@ import org.tizen.dynamicanalyzer.widgets.da.view.DABaseComposite; import org.tizen.dynamicanalyzer.widgets.da.view.DAPageComposite; import org.tizen.dynamicanalyzer.widgets.da.view.DATabButton; import org.tizen.dynamicanalyzer.widgets.da.view.DATabComposite; +import org.tizen.dynamicanalyzer.util.Logger; public class RangeDataManager implements Runnable { private static RangeDataManager instance = null; @@ -73,9 +76,6 @@ public class RangeDataManager implements Runnable { private BaseCallstackManager callstackManager = null; private BaseCallstackManager swapCallstackManager = null; - // function entry/exit queue - private List profileDataList = null; - private long markerStartTime = 0; private long markerEndTime = 0; private long analysisStartTime = 0; @@ -84,14 +84,14 @@ public class RangeDataManager implements Runnable { private boolean isBeingAnalyzed = false; private enum Function { - SEQ(0), - PID(1), - TID(2), - FUNCTIONID(3), - BINARYID(4), - TIME(5), - CALLERPCADDR(6), - PCADDR(7); + SEQ(1), // ResultSet column index starts from 1 + PID(2), + TID(3), + FUNCTIONID(4), + BINARYID(5), + TIME(6), + CALLERPCADDR(7), + PCADDR(8); public final int index; @@ -101,10 +101,10 @@ public class RangeDataManager implements Runnable { } private enum Sample { - TIME(0), - PID(1), - TID(2), - PCADDR(3); + TIME(1), + PID(2), + TID(3), + PCADDR(4); public final int index; @@ -116,7 +116,6 @@ public class RangeDataManager implements Runnable { private RangeDataManager() { callstackManager = new CallStackManager(); swapCallstackManager = new SWAPCallStackManager(true); - profileDataList = new ArrayList(); // fileDataMaker = new FileDataMaker(failedChecker, leakDetector, // warningChecker); @@ -129,7 +128,6 @@ public class RangeDataManager implements Runnable { profileDataMakerMap.clear(); if (swapProfileDataMakerMap != null) swapProfileDataMakerMap.clear(); - profileDataList.clear(); SummaryDataManager.getInstance().getLeakDataMaker().clearLeakDataForRange(); } @@ -296,160 +294,185 @@ public class RangeDataManager implements Runnable { int from = 0; boolean profileSkip = false; boolean contextSkip = false; + //TODO: divide this method into sub-methods + for (int i = 0; i < size; i++) { + // case 1 : profile data + // log id = profiling data + + int logId = logIds.get(i); + if (!profileSkip) { + if (logId == DataChannelConstants.MSG_FUNCTION_EXIT) { + ResultSet rsEntry = null; + ResultSet rsExit = null; + ResultSet rsSample = null; + PriorityQueue pQueue = new PriorityQueue(3, + new Comparator() { + public int compare(ProfileData pData1, ProfileData pData2) { + long time1 = pData1.getTime(); + long time2 = pData2.getTime(); + if (time1 < time2) { + return -1; + } else if (time1 > time2) { + return 1; + } else { + return 0; + } + } + }); + + try { + String query = String.format(FunctionEntryDBTable.SELECT_QUERY, + markerStartTime, markerEndTime); + rsEntry = SqlConnectionManager.executeQueryRS(query); + + query = String.format(FunctionExitDBTable.SELECT_QUERY, + markerStartTime, markerEndTime); + rsExit = SqlConnectionManager.executeQueryRS(query); + + query = String.format(FunctionSampleDBTable.SELECT_QUERY, + markerStartTime, markerEndTime); + rsSample = SqlConnectionManager.executeQueryRS(query); + + if (rsEntry == null || rsExit == null || rsSample == null) { + Logger.error("failed to query function profiling data in range"); + continue; + } + + if (rsEntry.next()) { + ProfileData pEntry = + makeFunctionProfileData(DataChannelConstants.MSG_FUNCTION_ENTRY, rsEntry); + pQueue.offer(pEntry); + } + if (rsExit.next()) { + ProfileData pExit = + makeFunctionProfileData(DataChannelConstants.MSG_FUNCTION_EXIT, rsExit); + pQueue.offer(pExit); + } + if (rsSample.next()) { + ProfileData pSample = makeSampleProfileData(rsSample); + pQueue.offer(pSample); + } + // handle entry/exit/sample data one by one in chronological order + while (true) { + ProfileData top = pQueue.poll(); + if (top == null) { + break; + } + ProfileDataMaker profileDataMaker = getProfileDataMakerByPid(top.getPid()); + + switch(top.getId()) { + case DataChannelConstants.MSG_FUNCTION_ENTRY: + if (rsEntry.next()) { + ProfileData pEntry = + makeFunctionProfileData(DataChannelConstants.MSG_FUNCTION_ENTRY, rsEntry); + pQueue.offer(pEntry); + } + swapCallstackManager.makeUserCallstackforRange(top, profileDataMaker); + break; + case DataChannelConstants.MSG_FUNCTION_EXIT: + if (rsExit.next()) { + ProfileData pExit = + makeFunctionProfileData(DataChannelConstants.MSG_FUNCTION_EXIT, rsExit); + pQueue.offer(pExit); + } + swapCallstackManager.makeUserCallstackforRange(top, profileDataMaker); + break; + case DataChannelConstants.MSG_DATA_SAMPLE: + if (rsSample.next()) { + ProfileData pSample = makeSampleProfileData(rsSample); + pQueue.offer(pSample); + } + profileDataMaker.makeFunctionUsageProfileDataforRange(top); + break; + default: // never goes here + Logger.error("Wrong data from selecting function profiling data inside range"); + break; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rsEntry != null) { + SqlConnectionManager.releaseResultSet(rsEntry); + } + if (rsExit != null) { + SqlConnectionManager.releaseResultSet(rsExit); + } + if (rsSample != null) { + SqlConnectionManager.releaseResultSet(rsSample); + } + } + profileSkip = true; + continue; + } + } + // case 2 : context data + if (!contextSkip) { + if (logId == DataChannelConstants.MSG_CONTEXT_SWITCH_ENTRY) { + from = 0; + while (true) { + LogPackage logPackage = new LogPackage(); + Logs logs = new Logs( + DataChannelConstants.LOG_CONTEXT_SWITCH); + input = SqlManager.getInstance().selectArea2(logId, + markerStartTime, markerEndTime, from, AnalyzerConstants.DATABASE_READ_SIZE); + if (input == null || input.isEmpty()) { + break; + } + logs.setLogs(input); + logPackage.setLogs( + DataChannelConstants.LOG_CONTEXT_SWITCH, logs); + makeRangeData(logPackage); + from += AnalyzerConstants.DATABASE_READ_SIZE; + } + contextSkip = true; + continue; + } + } + // case 3 : system data + + if (logId == DataChannelConstants.MSG_DATA_SYSTEM) { + from = 0; + while (true) { + LogPackage logPackage = new LogPackage(); + Logs logs = new Logs(logId); + input = SqlManager.getInstance().selectArea2(logId, + markerStartTime, markerEndTime, from, AnalyzerConstants.DATABASE_READ_SIZE); + if (input == null || input.isEmpty()) { + break; + } + logs.setLogs(input); + logPackage.setLogs(logId, logs); + makeRangeData(logPackage); + from += AnalyzerConstants.DATABASE_READ_SIZE; + } + continue; + } + // case 4 : probe data + if (logId != DataChannelConstants.MSG_DATA_SYSTEM + && logId != DataChannelConstants.MSG_FUNCTION_ENTRY + && logId != DataChannelConstants.MSG_FUNCTION_EXIT + && logId != DataChannelConstants.MSG_CONTEXT_SWITCH_ENTRY + && logId != DataChannelConstants.MSG_CONTEXT_SWITCH_EXIT + && logId != DataChannelConstants.MSG_DATA_SAMPLE) { -// for (int i = 0; i < size; i++) { -// // case 1 : profile data -// // log id = profiling data -// -// int logId = logIds.get(i); -// if (!profileSkip) { -// if (logId == DataChannelConstants.MSG_FUNCTION_EXIT) { -// from = 0; -// int to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// while (true) { // load function entry data -// String query = String.format(FunctionEntryDBTable.SELECT_QUERY, -// from, to, markerStartTime, markerEndTime); -// -// List> result = SqlConnectionManager.executeQuery(query); -// if (null == result || result.size() == 0 || result.get(0).size() == 0) { -// break; -// } -// makeProfileData(DataChannelConstants.MSG_FUNCTION_ENTRY, result); -// from += AnalyzerConstants.DATABASE_READ_SIZE; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// } -// -// from = 0; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// while (true) { // load function exit data -// String query = String.format(FunctionExitDBTable.SELECT_QUERY, -// from, to, markerStartTime, markerEndTime); -// -// List> result = SqlConnectionManager.executeQuery(query); -// if (null == result || result.size() == 0 || result.get(0).size() == 0) { -// break; -// } -// makeProfileData(DataChannelConstants.MSG_FUNCTION_EXIT, result); -// from += AnalyzerConstants.DATABASE_READ_SIZE; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// } -// -// makeRangeProfileData(); -// profileSkip = true; -// continue; -// } -// } -// -// // case 2 : function sample data -// if (logId == DataChannelConstants.MSG_DATA_SAMPLE) { -// from = 0; -// int to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// while (true) { -// LogPackage logPackage = new LogPackage(); -// Logs logs = new Logs( -// DataChannelConstants.LOG_USER_FUNCTION); -// List logList = new ArrayList(); -// String query = String.format(FunctionSampleDBTable.SELECT_QUERY, -// from, to, markerStartTime, markerEndTime); -// List> result = SqlConnectionManager.executeQuery(query); -// if (null == result || result.size() == 0 || result.get(0).size() == 0) { -// break; -// } -// -// int resultSize = result.size(); -// for (int j = 0; j < resultSize; j++) { -// List resultData = result.get(j); -// long time = (Long) resultData.get(Sample.TIME.index); -// int pid = (Integer) resultData.get(Sample.PID.index); -// int tid = (Integer) resultData.get(Sample.TID.index); -// long pcAddr = (Long) resultData.get(Sample.PCADDR.index); -// -// ProfileData profileData = new ProfileData(time, pid, tid, pcAddr); -// logList.add(profileData); -// } -// logs.setLogs(logList); -// logPackage.setLogs( -// DataChannelConstants.LOG_USER_FUNCTION, logs); -// makeRangeData(logPackage); -// from += AnalyzerConstants.DATABASE_READ_SIZE; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// } -// continue; -// } -// -// // case 3 : context data -// if (!contextSkip) { -// if (logId == DataChannelConstants.MSG_CONTEXT_SWITCH_ENTRY) { -// from = 0; -// int to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// while (true) { -// LogPackage logPackage = new LogPackage(); -// Logs logs = new Logs( -// DataChannelConstants.LOG_CONTEXT_SWITCH); -// input = SqlManager.getInstance().selectArea2(logId, -// markerStartTime, markerEndTime, from, to); -// if (input == null || input.isEmpty()) { -// break; -// } -// logs.setLogs(input); -// logPackage.setLogs( -// DataChannelConstants.LOG_CONTEXT_SWITCH, logs); -// makeRangeData(logPackage); -// from += AnalyzerConstants.DATABASE_READ_SIZE; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// } -// contextSkip = true; -// continue; -// } -// } -// // case 4 : system data -// -// if (logId == DataChannelConstants.MSG_DATA_SYSTEM) { -// from = 0; -// int to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// while (true) { -// LogPackage logPackage = new LogPackage(); -// Logs logs = new Logs(logId); -// input = SqlManager.getInstance().selectArea2(logId, -// markerStartTime, markerEndTime, from, to); -// if (input == null || input.isEmpty()) { -// break; -// } -// logs.setLogs(input); -// logPackage.setLogs(logId, logs); -// makeRangeData(logPackage); -// from += AnalyzerConstants.DATABASE_READ_SIZE; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// } -// continue; -// } -// // case 5 : probe data -// if (logId != DataChannelConstants.MSG_DATA_SYSTEM -// && logId != DataChannelConstants.MSG_FUNCTION_ENTRY -// && logId != DataChannelConstants.MSG_FUNCTION_EXIT -// && logId != DataChannelConstants.MSG_CONTEXT_SWITCH_ENTRY -// && logId != DataChannelConstants.MSG_CONTEXT_SWITCH_EXIT -// && logId != DataChannelConstants.MSG_DATA_SAMPLE) { -// -// from = 0; -// int to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// while (true) { -// LogPackage logPackage = new LogPackage(); -// Logs logs = new Logs(logId); -// input = SqlManager.getInstance().selectArea2(logId, -// markerStartTime, markerEndTime, from, to); -// if (input == null || input.isEmpty()) { -// break; -// } -// logs.setLogs(input); -// logPackage.setLogs(logId, logs); -// makeRangeData(logPackage); -// from += AnalyzerConstants.DATABASE_READ_SIZE; -// to = from + AnalyzerConstants.DATABASE_READ_SIZE; -// } -// continue; -// } -// } + from = 0; + while (true) { + LogPackage logPackage = new LogPackage(); + Logs logs = new Logs(logId); + input = SqlManager.getInstance().selectArea2(logId, + markerStartTime, markerEndTime, from, AnalyzerConstants.DATABASE_READ_SIZE); + if (input == null || input.isEmpty()) { + break; + } + logs.setLogs(input); + logPackage.setLogs(logId, logs); + makeRangeData(logPackage); + from += AnalyzerConstants.DATABASE_READ_SIZE; + } + continue; + } + } // make leak data SummaryDataManager.getInstance().getLeakDataMaker() @@ -464,49 +487,40 @@ public class RangeDataManager implements Runnable { } }); } - // make ProfileData from database result set and push it to function entry/exit queue - private void makeProfileData(int id, List> result) { - int resultSize = result.size(); - for (int j = 0; j < resultSize; j++) { - List resultData = result.get(j); - int seq = ((Long) resultData.get(Function.SEQ.index)).intValue(); - int pid = (Integer) resultData.get(Function.PID.index); - int tid = (Integer) resultData.get(Function.TID.index); - int functionId = (Integer) resultData.get(Function.FUNCTIONID.index); - int binaryId = (Integer) resultData.get(Function.BINARYID.index); - long time = (Long) resultData.get(Function.TIME.index); - long callerPcAddr = (Long) resultData.get(Function.CALLERPCADDR.index); - long pcAddr = (Long) resultData.get(Function.PCADDR.index); + + private ProfileData makeFunctionProfileData(int id, ResultSet rs) { + ProfileData profileData = null; + try { + int seq = rs.getInt(Function.SEQ.index); + int pid = rs.getInt(Function.PID.index); + int tid = rs.getInt(Function.TID.index); + int functionId = rs.getInt(Function.FUNCTIONID.index); + int binaryId = rs.getInt(Function.BINARYID.index); + long time = rs.getLong(Function.TIME.index); + long callerPcAddr = rs.getLong(Function.CALLERPCADDR.index); + long pcAddr = rs.getLong(Function.PCADDR.index); - ProfileData profileData = new ProfileData(id, seq, pid, tid, functionId, - binaryId, time, callerPcAddr, pcAddr); - profileDataList.add(profileData); - } + profileData = new ProfileData(id, seq, pid, tid, functionId, + binaryId, time, callerPcAddr, pcAddr); + } catch (SQLException e) { + e.printStackTrace(); + } + return profileData; } - private void makeRangeProfileData() { - if (profileDataList.isEmpty()) { - return; + private ProfileData makeSampleProfileData(ResultSet rs) { + ProfileData profileData = null; + try { + long time = rs.getLong(Sample.TIME.index); + int pid = rs.getInt(Sample.PID.index); + int tid = rs.getInt(Sample.TID.index); + long pcAddr = rs.getLong(Sample.PCADDR.index); + + profileData = new ProfileData(time, pid, tid, pcAddr); + } catch (SQLException e) { + e.printStackTrace(); } - // sort by sequence number - // function entry/exit log must be handled by exact order - Collections.sort(profileDataList, new Comparator() { - public int compare(ProfileData pData1, ProfileData pData2) { - return pData1.getSeq() - pData2.getSeq(); - } - }); - - int size = profileDataList.size(); - for (int i = 0; i < size; i++) { - ProfileData input = profileDataList.get(i); - ProfileDataMaker profileDataMaker = getProfileDataMakerByPid(input - .getPid()); - // function_exit log doesn't have probe type yet -// if (input.getProbeType() -// == AnalyzerConstants.FUNCTION_TYPE_APPINST) { - swapCallstackManager.makeUserCallstack(input, profileDataMaker); -// } - } + return profileData; } private void makeRangeData(LogPackage logPack) { diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionSampleDBTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionSampleDBTable.java index 91408fd..1737375 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionSampleDBTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionSampleDBTable.java @@ -43,9 +43,8 @@ public class FunctionSampleDBTable extends DBTable { COLUMN.PID.name + CommonConstants.COMMA + COLUMN.TID.name + CommonConstants.COMMA + COLUMN.PCADDR.name; - public static final String SELECT_QUERY = - "select limit %s %s " + SELECT_COLUMN + " from " + TABLENAME + + "select " + SELECT_COLUMN + " from " + TABLENAME + " where " + COLUMN.SAMPLETIME.name + " >= %s and " + COLUMN.SAMPLETIME.name + " <= %s"; 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 d87c112..a0bd724 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 @@ -431,7 +431,136 @@ public class ProfileDataMaker { } } } + // TODO: divide this method into sub-methods, redesign data process + public void makeFunctionUsageProfileDataforRange(ProfileData sampleLog) { + totalSampleCount++; + List addrs = new ArrayList(); + long selfAddr = sampleLog.getPcAddr(); + int pid = sampleLog.getPid(); + int tid = sampleLog.getTid(); + long sampleTime = sampleLog.getTime(); + + Map addrMap = callstackManager + .getCallStackApiAddrByPidMap(pid); + + CallStackUnit selfCallstackUnit = addrMap.get(selfAddr); + if (null == selfCallstackUnit) { + selfCallstackUnit = new CallStackUnit(selfAddr, + callstackManager.getCallStackSymbol(selfAddr, pid, sampleTime), sampleLog); + addrMap.put(selfAddr, selfCallstackUnit); + } + + List userCallstack = callstackManager.getUserCallstack(tid); + int callstackSize = userCallstack.size(); + + for (int i = 0; i < callstackSize; i++) { + long addr = userCallstack.get(i).getCallStackUnit().getAddr(); + addrs.add(addr); + } + addrs.add(selfAddr); + + // drop samples of probe library + if (selfCallstackUnit.getPath().startsWith(PathConstants.DA_REMOTE_PROBE_PATH)) { + return; + } + + String inputPath = selfCallstackUnit.getPath(); + String inputFuncName = selfCallstackUnit.getFunctionName(); + + ProfilingData parent = getProfilingDataByKey(inputPath); + // exclusive cpu time + if (null == parent) { + parent = makeNewProfilingData(selfCallstackUnit, true); + checkUserCall(selfCallstackUnit, parent, null, sampleLog); + if (inputFuncName.equals(FunctionUsageProfiler.UNKNOWN)) { + parent.addExCount(); + } else { + ProfilingData child = makeNewProfilingData(selfCallstackUnit, false); + parent.addChild(child); + child.addExCount(); + child.setParent(parent.getName()); + } + } else { + if (inputFuncName.isEmpty()) { + parent.addExCount(); + } else { + ProfilingData child = getProfilingDataByKey(selfCallstackUnit + .getSymbol()); + if (null == child) { + child = makeNewProfilingData(selfCallstackUnit, false); + parent.addChild(child); + child.setParent(parent.getName()); + } + child.addExCount(); + } + } + + // inclusive cpu time + int size = 0; + if (null != addrs) { + size = addrs.size(); + } + for (int i = 0; i < size; i++) { + CallStackUnit callstackCsa = addrMap.get(addrs.get(i)); + + if (callstackCsa.getFunctionName().equals( + FunctionUsageProfiler.UNKNOWN)) { + ProfilingData inParent = getProfilingDataByKey(callstackCsa + .getPath()); + ProfilingData pp = null; + if (null == inParent) { + inParent = makeNewProfilingData(callstackCsa, true); + checkUserCall(callstackCsa, inParent, pp, sampleLog); + } + inParent.addInCount(totalSampleCount); + + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + pp = getProfilingDataByKey(pInParentName); + if (null != pp) { + pp.addInCount(totalSampleCount); + } + } + } else { + ProfilingData fupData = getProfilingDataByKey(callstackCsa + .getSymbol()); + if (null == fupData) { + ProfilingData inParent = getProfilingDataByKey(callstackCsa + .getPath()); + if (null == inParent) { + inParent = makeNewProfilingData(callstackCsa, true); + checkUserCall(callstackCsa, inParent, null, sampleLog); + } + fupData = makeNewProfilingData(callstackCsa, false); + fupData.setParent(inParent.getName()); + inParent.addChild(fupData); + inParent.addInCount(totalSampleCount); + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + ProfilingData pp = getProfilingDataByKey(pInParentName); + if (null != pp) { + pp.addInCount(totalSampleCount); + } + } + } else { + String pName = fupData.getParent(); + ProfilingData inParent = getProfilingDataByKey(pName); + inParent.addInCount(totalSampleCount); + + if (null != inParent.getParent()) { + String pInParentName = inParent.getParent(); + ProfilingData ppData = getProfilingDataByKey(pInParentName); + if (null != ppData) { + ppData.addInCount(totalSampleCount); + } + } + } + fupData.addInCount(totalSampleCount); + } + } + } + private List makeCallstackHashAndList(List callstackLog, LogData log) { int pid = log.getPid(); diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionEntryDBTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionEntryDBTable.java index 03e10ef..51104b4 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionEntryDBTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionEntryDBTable.java @@ -49,7 +49,7 @@ public class FunctionEntryDBTable extends DBTable { COLUMN.CALLERPCADDR.name + CommonConstants.COMMA + COLUMN.PCADDR.name; public static final String SELECT_QUERY = - "select limit %s %s " + SELECT_COLUMN + " from " + TABLENAME + + "select " + SELECT_COLUMN + " from " + TABLENAME + " where " + COLUMN.STARTTIME.name + " >= %s and " + COLUMN.STARTTIME.name + " <= %s"; public enum COLUMN { diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionExitDBTable.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionExitDBTable.java index b8f596f..9aadaf0 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionExitDBTable.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionExitDBTable.java @@ -50,7 +50,7 @@ public class FunctionExitDBTable extends DBTable { FunctionEntryDBTable.COLUMN.PCADDR.name; public static final String SELECT_QUERY = - "select limit %s %s " + SELECT_COLUMN + " from " + TABLENAME + + "select " + SELECT_COLUMN + " from " + TABLENAME + CommonConstants.COMMA + FunctionEntryDBTable.TABLENAME + " where " + COLUMN.ENTRYSEQ.name + CommonConstants.EQUAL + FunctionEntryDBTable.COLUMN.SEQ.name + " and " + COLUMN.ENDTIME.name + " >= %s and " + COLUMN.ENDTIME.name + " <= %s"; -- 2.7.4