this.enabled = enabled;
}
+ /**
+ * Search for line in source code, where specified with {@code item}
+ * instruction <b>was called</b>. This method explores {@code item.getData()}, so if
+ * no data was defined it will return {@link SourceLine} with specified
+ * error.
+ *
+ * @param item grid item with defined data
+ * @return {@link SourceLine} object encapsulates info about source line, or
+ * description of appeared error. {@code null} returned if {@code item
+ * == null}.
+ */
public SourceLine getCallerSourceLine(GridItem item) {
if (item == null) {
return null;
pid = (Integer) item.getData(AnalyzerConstants.CALLSTACK_KEY_PID);
time = (Long) item.getData(AnalyzerConstants.CALLSTACK_KEY_TIME);
break;
+ case AnalyzerConstants.TYPE_TABLE_MEM_CALLSTACK:
+ addr = (Long) item
+ .getData(AnalyzerConstants.MEM_CALLSTACK_KEY_CALLER_ADDRESS);
+ pid = (Integer) item.getData(AnalyzerConstants.CALLSTACK_KEY_PID);
+ time = (Long) item.getData(AnalyzerConstants.CALLSTACK_KEY_TIME);
+ break;
// TODO: change number to define
case AnalyzerConstants.TYPE_TABLE_FAILED:
List<Object> failedData = tableData.getData();
return getSourceLine(addr, pid, time);
}
+ /**
+ * Search for line in source code, where specified with {@code item}
+ * instruction <b>is defined</b>. This method explores {@code item.getData()}, so if
+ * no data defined it will return {@link SourceLine} with specified error.
+ *
+ * @param item grid item with defined data
+ * @return {@link SourceLine} object encapsulates info about source line, or
+ * description of appeared error. {@code null} returned if {@code item ==
+ * null}.
+ */
public SourceLine getDefinitionSourceLine(GridItem item) {
if (item == null) {
return null;
pid = (Integer) calltraceData.get(FunctionEntryDBTable.COLUMN.PID.index);
time = (Long) calltraceData.get(FunctionEntryDBTable.COLUMN.START_TIME.index);
break;
+ case AnalyzerConstants.TYPE_TABLE_MEM_CALLSTACK:
+ addr = (Long) item
+ .getData(AnalyzerConstants.MEM_CALLSTACK_KEY_FUNCTION_START_ADDRESS);
+ pid = (Integer) item.getData(AnalyzerConstants.CALLSTACK_KEY_PID);
+ time = (Long) item.getData(AnalyzerConstants.CALLSTACK_KEY_TIME);
+ break;
default:
/*
* Do Nothing.
}
}
+ /**
+ * Extract library name from {@code item}'s data.
+ *
+ * @param item grid item that encapsulates data
+ * @return {@link String} representation of library path
+ */
private String getLibPath(GridItem item) {
DATableDataFormat tableData = (DATableDataFormat) item.getData();
String libName = null;
BinaryInfo binInfo = Global.getProject().getDeviceStatusInfo().getBinaryInfo(binaryId);
libName = binInfo.getTargetBinaryPath();
break;
+ case AnalyzerConstants.TYPE_TABLE_MEM_CALLSTACK:
+ libName = (String) item.getData(AnalyzerConstants.CALLSTACK_KEY_LIBNAME);
+ break;
default: // normal
ProbeCommonData wData = (ProbeCommonData) tableData.getLogData();
libName = wData.getLibName();
Map<Long, CallStackUnit> addrMap = getCallStackApiAddrByPidMap(pid);
- long 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) {
// insert call count
profiler.makeFupDataForCallTrace(selfCallstackUnit, log);
- List<CallStackItem> userCallstack = getUserCallstack(tid);
- int size = userCallstack.size();
- NavigableMap<Long, Long> seqByTimeMap = getSeqTimeByTidMap(tid, true);
+
CallStackUnit callerCallstackUnit = addrMap.get(callerAddr);
if (null == callerCallstackUnit) {
int eventType = log.getMsgID();
if (eventType == ProtocolConstants.MSG_FUNCTION_ENTRY) {
- if (size == 0) {
- userCallstack.add(new CallStackItem(selfCallstackUnit, time));
+ proceedEntry(log, selfCallstackUnit, addrMap);
+ } else if (eventType == ProtocolConstants.MSG_FUNCTION_EXIT) {
+ proceedExit(log, selfCallstackUnit, addrMap);
+
+ }
+ }
+
+ /**
+ * Method calculates new callstack value on function entry.
+ *
+ * @param log data that includes information about current state of
+ * execution
+ * @param selfCallstackUnit description of function execution enter to
+ * @param addrMap map with functions assigned to caller addresses
+ */
+ private void proceedEntry(ProfileData log, CallStackUnit selfCallstackUnit,
+ Map<Long, CallStackUnit> addrMap) {
+ int pid = log.getPid();
+ int tid = log.getTid();
+
+ long time = log.getTime();
+ long callerAddr = log.getCallerPcAddr();
+ long seq = log.getSeq();
+
+ List<CallStackItem> userCallstack = getUserCallstack(tid);
+ int size = userCallstack.size();
+ CallStackData callstackData = new CallStackData(seq);
+
+ NavigableMap<Long, Long> seqByTimeMap = getSeqTimeByTidMap(tid, true);
+ if (size == 0) {
+ userCallstack.add(new CallStackItem(selfCallstackUnit, time));
+ } else {
+ if (!isAddrInBinaryRange(pid, time, callerAddr)) {
+ CallStackUnit callbackApi = addrMap
+ .get(LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR);
+ if (null == callbackApi) {
+ callbackApi = new CallStackUnit(
+ LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR,
+ LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL,
+ log);
+ addrMap.put(
+ LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR,
+ callbackApi);
+ }
+ userCallstack.add(new CallStackItem(callbackApi));
} else {
- if (!isAddrInBinaryRange(pid, time, callerAddr)) {
- CallStackUnit callbackApi = addrMap
- .get(LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR);
- if (null == callbackApi) {
- callbackApi = new CallStackUnit(
- LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR,
- LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_SYMBOL, log);
- addrMap.put(LogCenterConstants.USER_FUNCTION_CALLBACK_FUNC_ADDR,
- callbackApi);
- }
- userCallstack.add(new CallStackItem(callbackApi));
+ CallStackUnit callerCsa = addrMap.get(callerAddr);
+ if (null == callerCsa) {
+ callerCsa = userCallstack.get(size - 1).getCallStackUnit();
+ callerCsa.setFunctionStartAddr(callerCsa.getAddr());
+ callerCsa.setAddr(callerAddr);
} else {
- 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()));
- }
+ CallStackItem topCallstackItem = userCallstack
+ .get(size - 1);
+ callerCsa.setFunctionStartAddr(topCallstackItem
+ .getCallStackUnit().getAddr());
+ userCallstack.set(size - 1, new CallStackItem(callerCsa,
+ topCallstackItem.getStartTime()));
}
- userCallstack.add(new CallStackItem(selfCallstackUnit, time));
}
+ userCallstack.add(new CallStackItem(selfCallstackUnit, time));
+ }
+ size = userCallstack.size();
+ for (int i = size - 1; i >= 0; i--) {
+ callstackData.addAddr(userCallstack.get(i).getCallStackUnit()
+ .getAddr());
+ }
+ offerCallStackData(callstackData);
+ getCallStackDataBySeqMap().put(seq, callstackData);
+ seqByTimeMap.put(time, seq);
+ }
+
+ /**
+ * Method calculates new callstack value on function exit.
+ *
+ * @param log data that includes information about current state of
+ * execution
+ * @param selfCallstackUnit description of function execution exit from
+ * @param addrMap map with functions assigned to caller addresses
+ */
+ private void proceedExit(ProfileData log, CallStackUnit selfCallstackUnit,
+ Map<Long, CallStackUnit> addrMap) {
+ int tid = log.getTid();
+ long time = log.getTime();
+ long seq = log.getSeq();
+ List<CallStackItem> userCallstack = getUserCallstack(tid);
+ int size = userCallstack.size();
+ CallStackData callstackData = new CallStackData(seq);
+
+ NavigableMap<Long, Long> seqByTimeMap = getSeqTimeByTidMap(tid, true);
+ if (size == 0) {
+ // if not in range profiling, this should not be reached
+ return;
+ }
+ CallStackUnit removeCallStackUnit = userCallstack.get(size - 1)
+ .getCallStackUnit();
+ if (selfCallstackUnit.getFunctionId() == removeCallStackUnit
+ .getFunctionId()) {
+ userCallstack.remove(size - 1);
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) {
+ 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()));
+ }
+ }
for (int i = size - 1; i >= 0; i--) {
callstackData.addAddr(userCallstack.get(i).getCallStackUnit()
.getAddr());
offerCallStackData(callstackData);
getCallStackDataBySeqMap().put(seq, callstackData);
seqByTimeMap.put(time, seq);
- } else if (eventType == ProtocolConstants.MSG_FUNCTION_EXIT) {
- if (size == 0) {
- // if not in range profiling, this should not be reached
- return;
- }
- CallStackUnit removeCallStackUnit = userCallstack.get(size - 1).getCallStackUnit();
- if (selfCallstackUnit.getFunctionId() == removeCallStackUnit.getFunctionId()) {
- userCallstack.remove(size - 1);
- 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) {
- 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()));
- }
- }
- for (int i = size - 1; i >= 0; i--) {
- callstackData.addAddr(userCallstack.get(i)
- .getCallStackUnit().getAddr());
- }
- offerCallStackData(callstackData);
- getCallStackDataBySeqMap().put(seq, callstackData);
- seqByTimeMap.put(time, seq);
- } else {
- Logger.debug("makeUserCallstack : EXIT self is not the same as top of user callstack");
- }
+ } else {
+ Logger.debug("makeUserCallstack : EXIT self is not the same as top of user callstack");
+ }
- String apiName = Global.getFunctionName(log.getApiId());
- if (apiName.equals("main")) { //$NON-NLS-1$
- ProcessInformation process = Global.getProject()
- .getProcessInformation(log.getPid());
- process.setDropLog(true);
- }
+ String apiName = Global.getFunctionName(log.getApiId());
+ if (apiName.equals("main")) { //$NON-NLS-1$
+ ProcessInformation process = Global.getProject()
+ .getProcessInformation(log.getPid());
+ process.setDropLog(true);
}
}
+ /**
+ * Method to update callstack for current state of execution, if it is not
+ * function entry or exit.
+ *
+ * @param inputData data that includes information about current state of
+ * execution
+ */
public void makeCallstackWithoutBacktrace(LogData inputData) {
if (!(inputData instanceof ProbeCommonData)) {
Logger.warning("failed to make callstack : log is not probe log");
String strCallerSymbol = getCallStackSymbol(callerAddr, pid, time);
if(strCallerSymbol != null) {
callerCallstackUnit = new CallStackUnit(callerAddr, strCallerSymbol, inputData);
+
+ CallStackUnit topUserCallstack = addrMap.get(addrs.get(0));
+ if (callerCallstackUnit.getFunctionId() == topUserCallstack.getFunctionId())
+ callerCallstackUnit.setFunctionStartAddr(topUserCallstack.getFunctionStartAddr());
+
addrMap.put(callerAddr, callerCallstackUnit);
}
}
super(parent, style);
}
+ /**
+ * Public constructor.
+ *
+ * @param parent parent composite
+ * @param compStyle SWT composite style
+ * @param tableStyle SWT table style
+ */
public MemoryCallStackTable(Composite parent, int compStyle, int tableStyle) {
super(parent, compStyle, tableStyle);
}
});
+ // Add standard right mouse button listener
+ setContextMenu(AnalyzerConstants.CONTEXT_TABLE_SOURCE);
applyFilterImage();
}
+ /**
+ * Update table data according to selected item.
+ *
+ * @param selData selected data item
+ */
public void updateCallstackTable(DASelectionData selData) {
long t = System.nanoTime(); // TODO: this instruction required to
// analyze performance and must be removed.
callstackTableData.setObject(allocCallerAddr);
GridItem gridItem = new GridItem(table, SWT.NONE);
gridItem.setData(callstackTableData);
- gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_ADDR, allocCallerAddr);
+ gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_ADDR, 0L);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_PID, pid);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_TIME, time);
- gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_LIBNAME, allocPath);
+ gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_LIBNAME, "");
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_CALLER_ADDRESS,
+ allocCallerAddr);
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_FUNCTION_START_ADDRESS,
+ 0L);
gridItem.setText(0, allocName);
gridItem.setText(1, UNKNOWN);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_PID, pid);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_TIME, time);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_LIBNAME, allocPath);
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_CALLER_ADDRESS, 0L);
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_FUNCTION_START_ADDRESS,
+ 0L);
gridItem.setText(0, UNKNOWN);
String addrInput = (allocCallerAddr == 0)
if (i==0){
if(allocPath.equals(Global.getLibraryName(api.getBinaryID()))){
gridItem.setText(0, api.getFunctionName());
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_CALLER_ADDRESS,
+ addrs.get(1));
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_FUNCTION_START_ADDRESS,
+ api.getFunctionStartAddr());
continue;
}else{
- address = 0;
+ if (addrs.size() > 1)
+ address = 0L;
}
}
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_PID, pid);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_TIME, time);
gridItem.setData(AnalyzerConstants.CALLSTACK_KEY_LIBNAME, path);
+ if (i + 1 < addrs.size())
+ gridItem.setData(AnalyzerConstants.MEM_CALLSTACK_KEY_CALLER_ADDRESS, addrs.get(i+1));
+ else
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_CALLER_ADDRESS,
+ 0L);
+ gridItem.setData(
+ AnalyzerConstants.MEM_CALLSTACK_KEY_FUNCTION_START_ADDRESS,
+ api.getFunctionStartAddr());
addrInput = (address == 0) ? UNKNOWN : hexAddr; //$NON-NLS-1$
gridItem.setText(1, addrInput.toLowerCase());