Range Analysis : enable range analysis for wide range 77/27277/2
authorwoojin <woojin2.jung@samsung.com>
Wed, 10 Sep 2014 03:55:50 +0000 (12:55 +0900)
committerwoojin <woojin2.jung@samsung.com>
Thu, 11 Sep 2014 08:32:23 +0000 (17:32 +0900)
1. change the way of getting data from database to avoid memory overflow
2. bug fix : not to obtain duplicate rows from database

Change-Id: I079d84cfb10edf1f4363c17889939607654ae1bf
Signed-off-by: woojin <woojin2.jung@samsung.com>
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/BaseCallstackManager.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/callstack/SWAPCallStackManager.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ProfileData.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/info/callstack/CallStackManager.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/range/RangeDataManager.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/FunctionSampleDBTable.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/summary/profiling/ProfileDataMaker.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionEntryDBTable.java
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/timeline/calltrace/FunctionExitDBTable.java

index d1d75e1..776d602 100644 (file)
@@ -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);
 
index 7792f15..a10d07c 100644 (file)
@@ -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<Long, CallStackUnit> 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<CallStackItem> 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;
 
index 9ee45b3..882e90a 100644 (file)
@@ -79,6 +79,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;
index 73406b7..a7c37d3 100644 (file)
@@ -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<Long, CallStackUnit> 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<CallStackItem> 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<Long, CallStackUnit> addrMap = getCallStackApiAddrByPidMap(inputData.getPid());
index e018a8c..5f3ffc9 100644 (file)
 
 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<ProfileData> 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<ProfileData>();
 
                // 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<ProfileData> pQueue = new PriorityQueue<ProfileData>(3,
+                                                       new Comparator<ProfileData>() {
+                                               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<List<Object>> 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<List<Object>> 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<LogData> logList = new ArrayList<LogData>();
-//                                     String query = String.format(FunctionSampleDBTable.SELECT_QUERY,
-//                                                     from, to, markerStartTime, markerEndTime);
-//                                     List<List<Object>> 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<Object> 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<List<Object>> result) {
-               int resultSize = result.size();
-               for (int j = 0; j < resultSize; j++) {
-                       List<Object> 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<ProfileData>() {
-                       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) {
index 91408fd..1737375 100644 (file)
@@ -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";
                        
        
index d87c112..a0bd724 100644 (file)
@@ -431,7 +431,136 @@ public class ProfileDataMaker {
                        }
                }
        }
+       // TODO: divide this method into sub-methods, redesign data process
+       public void makeFunctionUsageProfileDataforRange(ProfileData sampleLog) {
+               totalSampleCount++;
+               List<Long> addrs = new ArrayList<Long>();
+               long selfAddr = sampleLog.getPcAddr();
+               int pid = sampleLog.getPid();
+               int tid = sampleLog.getTid();
+               long sampleTime = sampleLog.getTime();  
+
+               Map<Long, CallStackUnit> 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<CallStackItem> 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<Long> makeCallstackHashAndList(List<String> callstackLog,
                        LogData log) {
                int pid = log.getPid();
index 03e10ef..51104b4 100644 (file)
@@ -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 {
index b8f596f..9aadaf0 100644 (file)
@@ -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";