From 24adad0b497a3481ae87621695aee7d927c95eb2 Mon Sep 17 00:00:00 2001 From: woojin Date: Fri, 20 Jun 2014 20:15:34 +0900 Subject: [PATCH] Thread Analysis : thread function name and thread class name is shown in the thread details view Show thread class name for Tizen Thread. Show thread function name for other thread (e.g. pthread). Change-Id: I6a1f8312f3cda5527e4c04dfb543453753f2f0f0 Signed-off-by: woojin --- .../dynamicanalyzer/common/SymbolManager.java | 147 +++++++++++++++++++++ .../tizen/dynamicanalyzer/nl/ThreadPageLabels.java | 2 + .../dynamicanalyzer/nl/ThreadPageLabels.properties | 4 +- .../swap/logparser/SWAPLogParser.java | 135 +------------------ .../swap/model/data/ThreadData.java | 12 ++ .../ui/thread/ThreadDetailInfoView.java | 35 +++++ .../ui/thread/thread/ThreadPageThreadData.java | 18 ++- .../thread/thread/ThreadPageThreadDataManager.java | 49 +++++-- 8 files changed, 259 insertions(+), 143 deletions(-) diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/SymbolManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/SymbolManager.java index 74036b5..9d934d3 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/SymbolManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/common/SymbolManager.java @@ -30,7 +30,9 @@ import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProviderFactory; @@ -52,6 +54,14 @@ import org.eclipse.cdt.utils.elf.Elf.Symbol; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.tizen.dynamicanalyzer.nl.AnalyzerLabels; +import org.tizen.dynamicanalyzer.nl.InformationViewLabels; +import org.tizen.dynamicanalyzer.swap.channel.control.BinaryInfo; +import org.tizen.dynamicanalyzer.swap.channel.data.ApiNameManager; +import org.tizen.dynamicanalyzer.swap.channel.data.LibraryObject; +import org.tizen.dynamicanalyzer.swap.channel.data.ProcessInfo; +import org.tizen.dynamicanalyzer.swap.channel.data.ProcessInfoPackage; +import org.tizen.dynamicanalyzer.swap.model.data.ProfileData; +import org.tizen.dynamicanalyzer.swap.platform.BinarySettingManager; import org.tizen.dynamicanalyzer.util.DALogger; public class SymbolManager { @@ -316,4 +326,141 @@ public class SymbolManager { } return demangled; } + + + /** + * getFuncName : returns function name from pc address, pid, time + * and set build type and binary path for ProfileData + * @param input : can be null. If not null, set build type and binary path for ProfileData + * @param address : pc address + * @param pid : process id + * @param time : time stamp of the function call + * @return : function name + */ + // TODO: remove unnecessary code + public static String getFuncName(ProfileData input, long address, int pid, long time) { + HashMap funcNameMap = AnalyzerManager + .getFuncNameMapByPid(pid); + String functionName = funcNameMap.get(address); + if (null != functionName) { + return functionName; + } + + ProcessInfoPackage processInfoPkg = AnalyzerManager.getProject() + .getProcessInfoPackage(pid); + ProcessInfo processInfo = processInfoPkg + .getProcessInfo(time); + + /** for debug */ + BinaryInfo binInfo1 = processInfo.getTargetBinary(address); + if (binInfo1 == null) { + // System.out.println("[Get functino name bug : " + // + "Can't find binary info]"); + // System.out + // .println("msg id : " + // + AnalyzerUtil.toHexdecimal(input.getId()) + // + " pid : " + // + processInfo.getPid() + // + " low : " + // + AnalyzerUtil.toHexdecimal(processInfo + // .getLowestAddress()) + // + " input addr : " + // + AnalyzerUtil.toHexdecimal(input.getPcAddr()) + // + " high : " + // + AnalyzerUtil.toHexdecimal(processInfo + // .getHighestAddress())); + return null; + } + // String binPath1 = binInfo1.getTargetBinaryPath(); + // System.out.print("binary : " + binPath1 + " ==> "); + // AnalyzerUtil.printHexdecimal(processInfo.getLowestAddress()); + // System.out.print(" < "); + // AnalyzerUtil.printHexdecimal(pcAddr); + // System.out.print(" < "); + // AnalyzerUtil.printHexdecimal(processInfo.getHighestAddress()); + // System.out.println(); + + if (address >= processInfo.getLowestAddress() + && address <= processInfo.getHighestAddress()) { + String baseAddr = Long.toString(processInfo.getLowestAddress()); + String pcStr = Long.toString(address); + BinaryInfo binInfo = processInfo.getTargetBinary(address); + String localPath = binInfo.getTempBinaryPath(); + if (null != input) { + input.setBuildType(binInfo.getType()); + input.setBinaryPath(binInfo.getTargetBinaryPath()); + } + boolean isPieBuild = true; + if (binInfo.getType() != 1) { + isPieBuild = false; + } + functionName = addr2func(localPath, pcStr, isPieBuild, baseAddr); + } else { + HashMap binInfoMap = BinarySettingManager + .getInstance().getTargetBinInfoMap(); + List binPaths = new ArrayList(); + binPaths.addAll(binInfoMap.keySet()); + + HashMap libHash = processInfo + .getLibObjHash(); + LibraryObject libraryObject = null; + int size = binPaths.size(); + for (int i = 0; i < size; i++) { + String binPath = binPaths.get(i); + LibraryObject libObj = libHash.get(binPath); + if (null == libObj) { + continue; + } + long lowAddr = libObj.getLowestAddress(); + long highAddr = libObj.getHighestAddress(); + + /** for debug */ + // if (lowAddr > pcAddr || highAddr < pcAddr) { + // System.out.print(input.getId() + " lib : " + binPath + // + " ==> "); + // AnalyzerUtil.printHexdecimal(lowAddr); + // System.out.print(" < "); + // AnalyzerUtil.printHexdecimal(pcAddr); + // System.out.print(" < "); + // AnalyzerUtil.printHexdecimal(highAddr); + // System.out.println(); + // } + + if (address >= lowAddr && address <= highAddr) { + libraryObject = libObj; + break; + } + } + if (null != libraryObject) { + String path = libraryObject.getLibPath(); + BinaryInfo binInfo = binInfoMap.get(path); + if (null != binInfo) { + String localPath = binInfo.getTempBinaryPath(); + String baseAddr = Long.toString(libraryObject + .getLowestAddress()); + String pcStr = Long.toString(address); + if (null != input) { + input.setBinaryPath(binInfo.getTargetBinaryPath()); + } + boolean isPieBuild = true; + if (binInfo.getType() != 1) { + isPieBuild = false; + } + functionName = addr2func(localPath, pcStr, isPieBuild, baseAddr); + } + } + } + + if (null == functionName || functionName.isEmpty() + || functionName.equals("_end")) { //$NON-NLS-1$ + functionName = InformationViewLabels.CALLSTACK_TABLE_UNKNOWN_FUNCTION; + ApiNameManager.getApiId(functionName); + } else { + String prevFunctionName = functionName; + functionName = demanglingFunctionName(prevFunctionName); + ApiNameManager.getApiId(functionName); + } + funcNameMap.put(address, functionName); + return functionName; + } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.java index 0b9a376..9c7bb2e 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.java @@ -101,6 +101,8 @@ public class ThreadPageLabels extends NLS { public static String THREAD_DETAILS_TID; public static String THREAD_DETAILS_TTYPE; public static String THREAD_DETAILS_TATTRTYPE; + public static String THREAD_DETAILS_FUNCNAME; + public static String THREAD_DETAILS_CLASSNAME; public static String THREAD_DETAILS_STARTTIME; public static String THREAD_DETAILS_ENDTIME; diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.properties b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.properties index 40960ee..c72030e 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.properties +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/nl/ThreadPageLabels.properties @@ -64,9 +64,11 @@ THREAD_API_LIST_VIEW_THREAD_ID=TID THREAD_API_LIST_VIEW_RETURN=Return THREAD_API_LIST_VIEW_ERRNO=Error Code -THREAD_DETAILS_TID=Thread ID : +THREAD_DETAILS_TID=Thread ID : THREAD_DETAILS_TTYPE=Type : THREAD_DETAILS_TATTRTYPE=Attr Type : +THREAD_DETAILS_FUNCNAME=Thread Function : +THREAD_DETAILS_CLASSNAME=Thread Class : THREAD_DETAILS_STARTTIME=Start Time : THREAD_DETAILS_ENDTIME=End Time : diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/SWAPLogParser.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/SWAPLogParser.java index a5c4d93..92cdca2 100755 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/SWAPLogParser.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/SWAPLogParser.java @@ -144,7 +144,6 @@ public class SWAPLogParser implements Runnable { } LogData log = logLumb.get(i); int id = log.getId(); - int seqNum = log.getSeq(); if (log instanceof SystemData) { // System.out // .println("=========systemData is slicing===========\n"); @@ -165,9 +164,13 @@ public class SWAPLogParser implements Runnable { .getProject().getProcessInfoPackage(pData.getPid()); String apiName = pData.getApiName(); + // _end indicates end of BSS (uninitialized data) section + // function entry of _end is considered as bad data + // TODO: test and remove _end condition if (null == apiName || apiName.isEmpty() || apiName.equals("_end")) { //$NON-NLS-1$ - apiName = getFuncName(pData); + apiName = SymbolManager.getFuncName(pData, pData.getPcAddr(), + pData.getPid(), pData.getTime()); if (apiName == null || apiName.equals("")) { continue; @@ -420,132 +423,4 @@ public class SWAPLogParser implements Runnable { // + " time " + input.getTime()); // System.out.println(" ]"); // } - - // TODO: remove unnecessary code - private String getFuncName(ProfileData input) { - long pcAddr = input.getPcAddr(); - HashMap funcNameMap = AnalyzerManager - .getFuncNameMapByPid(input.getPid()); - String functionName = funcNameMap.get(pcAddr); - if (null != functionName) { - return functionName; - } - - // String functionName = null; - ProcessInfoPackage processInfoPkg = AnalyzerManager.getProject() - .getProcessInfoPackage(input.getPid()); - ProcessInfo processInfo = processInfoPkg - .getProcessInfo(input.getTime()); - - /** for debug */ - BinaryInfo binInfo1 = processInfo.getTargetBinary(input.getPcAddr()); - if (binInfo1 == null) { - // System.out.println("[Get functino name bug : " - // + "Can't find binary info]"); - // System.out - // .println("msg id : " - // + AnalyzerUtil.toHexdecimal(input.getId()) - // + " pid : " - // + processInfo.getPid() - // + " low : " - // + AnalyzerUtil.toHexdecimal(processInfo - // .getLowestAddress()) - // + " input addr : " - // + AnalyzerUtil.toHexdecimal(input.getPcAddr()) - // + " high : " - // + AnalyzerUtil.toHexdecimal(processInfo - // .getHighestAddress())); - return null; - } - // String binPath1 = binInfo1.getTargetBinaryPath(); - // System.out.print("binary : " + binPath1 + " ==> "); - // AnalyzerUtil.printHexdecimal(processInfo.getLowestAddress()); - // System.out.print(" < "); - // AnalyzerUtil.printHexdecimal(pcAddr); - // System.out.print(" < "); - // AnalyzerUtil.printHexdecimal(processInfo.getHighestAddress()); - // System.out.println(); - - if (pcAddr >= processInfo.getLowestAddress() - && pcAddr <= processInfo.getHighestAddress()) { - String baseAddr = Long.toString(processInfo.getLowestAddress()); - String pcStr = Long.toString(pcAddr); - BinaryInfo binInfo = processInfo.getTargetBinary(pcAddr); - String localPath = binInfo.getTempBinaryPath(); - input.setBuildType(binInfo.getType()); - input.setBinaryPath(binInfo.getTargetBinaryPath()); - boolean isPieBuild = true; - if (binInfo.getType() != 1) { - isPieBuild = false; - } - functionName = SymbolManager.addr2func(localPath, pcStr, - isPieBuild, baseAddr); - } else { - HashMap binInfoMap = BinarySettingManager - .getInstance().getTargetBinInfoMap(); - List binPaths = new ArrayList(); - binPaths.addAll(binInfoMap.keySet()); - - HashMap libHash = processInfo - .getLibObjHash(); - LibraryObject libraryObject = null; - int size = binPaths.size(); - for (int i = 0; i < size; i++) { - String binPath = binPaths.get(i); - LibraryObject libObj = libHash.get(binPath); - if (null == libObj) { - continue; - } - long lowAddr = libObj.getLowestAddress(); - long highAddr = libObj.getHighestAddress(); - - /** for debug */ - // if (lowAddr > pcAddr || highAddr < pcAddr) { - // System.out.print(input.getId() + " lib : " + binPath - // + " ==> "); - // AnalyzerUtil.printHexdecimal(lowAddr); - // System.out.print(" < "); - // AnalyzerUtil.printHexdecimal(pcAddr); - // System.out.print(" < "); - // AnalyzerUtil.printHexdecimal(highAddr); - // System.out.println(); - // } - - if (pcAddr >= lowAddr && pcAddr <= highAddr) { - libraryObject = libObj; - break; - } - } - if (null != libraryObject) { - String path = libraryObject.getLibPath(); - BinaryInfo binInfo = binInfoMap.get(path); - if (null != binInfo) { - String localPath = binInfo.getTempBinaryPath(); - String baseAddr = Long.toString(libraryObject - .getLowestAddress()); - String pcStr = Long.toString(pcAddr); - input.setBinaryPath(binInfo.getTargetBinaryPath()); - boolean isPieBuild = true; - if (binInfo.getType() != 1) { - isPieBuild = false; - } - functionName = SymbolManager.addr2func(localPath, pcStr, - isPieBuild, baseAddr); - } - } - } - - if (null == functionName || functionName.isEmpty() - || functionName.equals("_end")) { //$NON-NLS-1$ - functionName = InformationViewLabels.CALLSTACK_TABLE_UNKNOWN_FUNCTION; - ApiNameManager.getApiId(functionName); - } else { - String prevFunctionName = functionName; - functionName = SymbolManager - .demanglingFunctionName(prevFunctionName); - ApiNameManager.getApiId(functionName); - } - funcNameMap.put(pcAddr, functionName); - return functionName; - } } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ThreadData.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ThreadData.java index 9b4289e..51a965d 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ThreadData.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/model/data/ThreadData.java @@ -39,6 +39,7 @@ public class ThreadData extends ProbeCommonData { long ospThreadId = 0; int threadType = 0; // TODO: short int apiType = 0;// TODO: short + String className = null; public ThreadData(){} @@ -55,6 +56,9 @@ public class ThreadData extends ProbeCommonData { index += INT_SIZE; apiType = ByteUtil.toInt(data, index); + index += INT_SIZE; + + className = ByteUtil.getString(data, index); } public long getPThreadId() { @@ -89,6 +93,14 @@ public class ThreadData extends ProbeCommonData { this.apiType = apiType; } + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + @Override public void makePreparedStatement(PreparedStatement prep) throws SQLException { diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/ThreadDetailInfoView.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/ThreadDetailInfoView.java index e6b2dda..26d3e0c 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/ThreadDetailInfoView.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/ThreadDetailInfoView.java @@ -55,6 +55,8 @@ public class ThreadDetailInfoView extends DAViewComposite { private Canvas canvas = null; private String tid = AnalyzerLabels.EMPTY_STRING; private String type = AnalyzerLabels.EMPTY_STRING; + private String funcName = AnalyzerLabels.EMPTY_STRING; + private String className = AnalyzerLabels.EMPTY_STRING; private String startTime = AnalyzerLabels.EMPTY_STRING; private String endTime = AnalyzerLabels.EMPTY_STRING; private String attrType = AnalyzerLabels.EMPTY_STRING; @@ -64,6 +66,8 @@ public class ThreadDetailInfoView extends DAViewComposite { private void init() { tid = AnalyzerLabels.EMPTY_STRING; type = AnalyzerLabels.EMPTY_STRING; + funcName = AnalyzerLabels.EMPTY_STRING; + className = AnalyzerLabels.EMPTY_STRING; startTime = AnalyzerLabels.EMPTY_STRING; endTime = AnalyzerLabels.EMPTY_STRING; attrType = AnalyzerLabels.EMPTY_STRING; @@ -106,6 +110,23 @@ public class ThreadDetailInfoView extends DAViewComposite { p = e.gc.textExtent(tid, SWT.DRAW_MNEMONIC); y += (p.y + HEIGHT_MARGIN); } + // tizen thread : show thread class name + // other thread (e.g. pthread) : show thread function name + if (type.equals(ThreadPageLabels.THREAD_ITEM_TYPE_TIZEN)) { + if (null != className && !(className.equals(CommonConstants.EMPTY))) { + e.gc.drawText(ThreadPageLabels.THREAD_DETAILS_CLASSNAME + className, + LEFT_MARGIN, y); + p = e.gc.textExtent(tid, SWT.DRAW_MNEMONIC); + y += (p.y + HEIGHT_MARGIN); + } + } else { + if (null != funcName && !(funcName.equals(CommonConstants.EMPTY))) { + e.gc.drawText(ThreadPageLabels.THREAD_DETAILS_FUNCNAME + funcName, + LEFT_MARGIN, y); + p = e.gc.textExtent(tid, SWT.DRAW_MNEMONIC); + y += (p.y + HEIGHT_MARGIN); + } + } if (null != startTime && !(startTime.equals(CommonConstants.EMPTY))) { @@ -139,6 +160,14 @@ public class ThreadDetailInfoView extends DAViewComposite { if (item instanceof ThreadPageThreadData) { tid = item.getTid(); type = item.getType(); + str = ((ThreadPageThreadData) item).getThreadFuncName(); + if (null != str && !(str.equals(CommonConstants.EMPTY))) { + funcName = str; + } + str = ((ThreadPageThreadData) item).getThreadClassName(); + if (null != str && !(str.equals(CommonConstants.EMPTY))) { + className = str; + } str = ((ThreadPageThreadData) item).getStartTime(); if (null != str && !(str.equals(CommonConstants.EMPTY))) { startTime = str; @@ -176,6 +205,12 @@ public class ThreadDetailInfoView extends DAViewComposite { if (!type.equals(item.getType())) { return true; } + if (!funcName.equals(((ThreadPageThreadData) item).getThreadFuncName())) { + return true; + } + if (!className.equals(((ThreadPageThreadData) item).getThreadClassName())) { + return true; + } if (!startTime.equals(((ThreadPageThreadData) item).getStartTime())) { return true; } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadData.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadData.java index 1ad826e..7df646e 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadData.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadData.java @@ -45,17 +45,33 @@ public class ThreadPageThreadData extends ThreadPageData { private List syncs = new ArrayList(); private String StartTime; private String EndTime; + private String threadFuncName; + private String threadClassName; private DAChartSeries loadSeries; private DAChartSeries eventSeries; private DAChartSeries apiSeries; - public ThreadPageThreadData(String type, String pid, String tid, String attrType) { + public ThreadPageThreadData(String type, String pid, String tid, String attrType, + String funcName) { super(type, String.valueOf(tid), pid, tid, attrType); + this.threadFuncName = funcName; } public void addDataEvent(ThreadPageThreadDataEvent dataEvent) { contentsQueue.add(dataEvent); } + + public String getThreadFuncName() { + return threadFuncName; + } + + public String getThreadClassName() { + return threadClassName; + } + + public void setThreadClassName(String className) { + threadClassName = className; + } public void setItem(DAChartBoardItem item) { this.item = item; diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadDataManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadDataManager.java index 6180957..08ba159 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadDataManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/thread/thread/ThreadPageThreadDataManager.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Comparator; import org.tizen.dynamicanalyzer.common.AnalyzerManager; +import org.tizen.dynamicanalyzer.common.SymbolManager; import org.tizen.dynamicanalyzer.constant.CommonConstants; import org.tizen.dynamicanalyzer.logparser.LogCenterConstants; import org.tizen.dynamicanalyzer.nl.ThreadPageLabels; @@ -87,6 +88,8 @@ public class ThreadPageThreadDataManager { private List callEventQueue = new ArrayList(); private HashMap threadAttrMap = new HashMap(); private HashMap syncAttrMap = new HashMap(); + // threadFuncMap : (pthreadId, function address) + private HashMap threadFuncMap = new HashMap(); private int preSelectionPid = -1; public static final int PTHREAD_CREATE_JOINABLE = 0; @@ -339,7 +342,7 @@ public class ThreadPageThreadDataManager { public void createMainThreadItem(int tid) { ThreadPageThreadData mainData = new ThreadPageThreadData( ThreadPageLabels.THREAD_ITEM_TYPE_MAIN, String.valueOf(tid), - String.valueOf(tid), CommonConstants.EMPTY); + String.valueOf(tid), CommonConstants.EMPTY, "main"); pushRow(mainData); } @@ -482,6 +485,7 @@ public class ThreadPageThreadDataManager { case LogCenterConstants.THREAD_API_TYPE_START: if (apiName.equals(ThreadPageLabels.THREAD_API_PTHREAD_CREATE)) { checkThreadType(input.getArgs(), pthreadId); + checkThreadFunc(input.getArgs(), pthreadId); } event = new ThreadPageThreadDataEvent( ThreadPageThreadDataEvent.TYPE_API, @@ -530,16 +534,20 @@ public class ThreadPageThreadDataManager { case LogCenterConstants.THREAD_API_TYPE_INTERNAL_START: Integer threadAttrTypeInt = threadAttrMap.get(pthreadId); String threadAttrType; + String funcName; if (null != threadAttrTypeInt) { threadAttrType = getAttrTypeByTypeInt(threadAttrTypeInt); } else { threadAttrType = ThreadPageLabels.THREAD_ATTR_TYPE_JOINABLE; } + // get thread function name for this pthread + funcName = SymbolManager.getFuncName(null, threadFuncMap.get(pthreadId), + input.getPid(), input.getTime()); ThreadPageThreadData data = new ThreadPageThreadData( ThreadPageLabels.THREAD_ITEM_TYPE_PTHREAD, pid, tid, - threadAttrType); + threadAttrType, funcName); pushRow(data); event = new ThreadPageThreadDataEvent( ThreadPageThreadDataEvent.TYPE_EVENT, @@ -560,6 +568,7 @@ public class ThreadPageThreadDataManager { int apiType = input.getApiType(); String apiName = input.getApiName(); String callID = Long.toString(input.getOspThreadId()); + String className = null; ThreadPageThreadData data; ThreadPageThreadDataEvent event; long errorNum = input.getErrno(); @@ -584,6 +593,7 @@ public class ThreadPageThreadDataManager { event.setCallID(callID); data = findCallQueue(callID); if (null != data) { + data.setThreadClassName(input.getClassName()); pushRow(data); } pushEvent(event); @@ -629,10 +639,11 @@ public class ThreadPageThreadDataManager { case LogCenterConstants.THREAD_API_TYPE_INTERNAL_START: data = new ThreadPageThreadData( ThreadPageLabels.THREAD_ITEM_TYPE_TIZEN, pid, tid, - ThreadPageLabels.THREAD_ATTR_TYPE_JOINABLE); + ThreadPageLabels.THREAD_ATTR_TYPE_JOINABLE, CommonConstants.EMPTY); // TIZEN thread includes the internal thread - if (true == checkCalledThread(callID)) { - pushRow(data); + if ((className = checkCalledThread(callID)) != null) { + data.setThreadClassName(className); + pushRow(data); } else { pushCallRow(data); } @@ -648,7 +659,6 @@ public class ThreadPageThreadDataManager { } public void parseAPI(LogData input) { - if (null == input) { return; } @@ -830,10 +840,12 @@ public class ThreadPageThreadDataManager { parseSync(logPack); hasUpdate = true; } - - private boolean checkCalledThread(String callId) { + // when INTERNAL_START log comes after START log, + // this method finds matching START log (for TIZEN thread only) + // return class name from the START log + private String checkCalledThread(String callId) { if (null == callId) { - return false; + return null; } int callEventQueueSize = callEventQueue.size(); ThreadPageThreadDataEvent callEvent; @@ -843,10 +855,11 @@ public class ThreadPageThreadDataManager { continue; } if (callId.equals(callEvent.getCallID())) { - return true; + ThreadData threadData = (ThreadData) callEvent.getContents(); + return threadData.getClassName(); } } - return false; + return null; } private String getCallEventID(String callID) { @@ -934,6 +947,20 @@ public class ThreadPageThreadDataManager { threadAttrMap.put(pthreadId, attrType); } } + // extract function address from arguments of thread create function, + // (e.g. int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); ) + // put (pthreadId, function address) in the map + private void checkThreadFunc(String args, String pthreadId) { + String[] temp = args.split(","); + if (temp.length != 4) { + return; + } + // 3rd argument is function address + String strFuncAddr = temp[2].trim(); + Long funcAddr = Long.decode(strFuncAddr); + + threadFuncMap.put(pthreadId, funcAddr); + } private void checkMutexAttrType(String input) { String[] temp = input.split(","); -- 2.7.4