Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 136422 Details for
Bug 194081
after re-attach, no more data is collected for methods already entered
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Patch - 4521 - Update Shadow stack solution to solve reattach and attach problem with CGProf
update_4_5_2_1_shadow_stack_tracker_patch.txt (text/plain), 34.87 KB, created by
Chengrui Deng
on 2009-05-20 00:47:21 EDT
(
hide
)
Description:
Patch - 4521 - Update Shadow stack solution to solve reattach and attach problem with CGProf
Filename:
MIME Type:
Creator:
Chengrui Deng
Created:
2009-05-20 00:47:21 EDT
Size:
34.87 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.tptp.platform.jvmti.runtime >Index: src-native/src/BaseProf/ProfEnv.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/BaseProf/ProfEnv.cpp,v >retrieving revision 1.31 >diff -u -r1.31 ProfEnv.cpp >--- src-native/src/BaseProf/ProfEnv.cpp 8 Dec 2008 13:37:37 -0000 1.31 >+++ src-native/src/BaseProf/ProfEnv.cpp 20 May 2009 04:42:50 -0000 >@@ -11,6 +11,9 @@ > * > * $Id: ProfEnv.cpp,v 1.31 2008/12/08 13:37:37 jkubasta Exp $ > ************************************************************************/ >+#ifndef LIN >+#pragma warning(disable:4786) // Add for bug 194081 to disable VC compiler warning when use STL >+#endif > > #include "ProfEnv.h" > #include "log.h" >@@ -19,6 +22,7 @@ > using namespace Martini::MPI; > using namespace Martini::OSA; > using namespace Martini::JPIAgent; >+using namespace std; // Add for bug 194081 > > CProfEnv::CProfEnv(){ > m_pClassSData = 0; >@@ -61,6 +65,10 @@ > m_pAggStorage->Destroy(); > m_pSSMethodLeaveData_LockObject->Destroy(); > lockGetThreadInfoObject->Destroy(); >+ >+ // Add for bug 194081 >+ m_pShadowStackTracker = NULL; >+ // Add for bug 194081 > } > > void >@@ -101,6 +109,14 @@ > delete m_pMethodSData; > } > m_pMethodSDataLockObject->Leave(); >+ >+ // Add for bug 194081 >+ if (m_pShadowStackTracker) >+ { >+ delete m_pShadowStackTracker; >+ m_pShadowStackTracker = NULL; >+ } >+ // Add for bug 194081 > } > > /* >@@ -124,6 +140,16 @@ > } > libraryLoader->Destroy(); > (*ecpEnv)(profName, &ec_env); >+ >+ // Add for bug 194081 >+ m_pShadowStackTracker = new CCGShadowStackTracker(*this); >+ if ( (NULL == m_pShadowStackTracker) || >+ !(m_pShadowStackTracker->ValidateCGShadowStackTracker()) ) >+ { >+ return MRTE_ERROR_FAIL; >+ } >+ // Add for bug 194081 >+ > return MRTE_RESULT_OSA_PLACE_HOLDER; > } > >@@ -209,6 +235,18 @@ > return ret; > } > >+// Add for bug 194081 >+void >+CProfEnv::DeleteMethodsData() >+{ >+ if (m_pMethodSData) >+ { >+ delete m_pMethodSData; >+ m_pMethodSData = NULL; >+ } >+} >+// Add for bug 194081 >+ > void > CProfEnv::AddNewMethodData(SMethodInfo* pSMethodInfo, TId methodId, bool isPrinted) > { >@@ -366,9 +404,61 @@ > lockObjectCheckObject->Leave(); > } > >+// Add for bug 194081. Filter additional data referring to CanInstrumentClass >+bool CProfEnv::IsExcludedClass(const char* szClassName) >+{ >+ static char* ExcludedClassPatterns[] = >+ { >+ "org.eclipse.tptp.martini.", >+ "com.ibm.crypto", >+ "sun.reflect.Generated", >+ "jrockit.", >+ "com.Intel.VTune.VTuneAPI", >+ "org.eclipse.hyades.collection.profiler", >+ "java.lang.", >+ "java.security.", >+ "java.awt.", >+ "java.io.", >+ "javax.swing." >+ "com.ibm.jvm.", >+ "com.ibm.misc.", >+ "com.ibm.oti.", >+ "sun.nio.", >+ "CGLIB$$" >+ }; >+ >+ // Check if the class appear in the excluded class patterns list >+ unsigned int patternArraySize = >+ sizeof(ExcludedClassPatterns)/sizeof(*ExcludedClassPatterns); >+ >+ for (unsigned int i = 0; i < patternArraySize; ++i) >+ { >+ char *szExcludedPattern = ExcludedClassPatterns[i]; >+ if (strstr(szClassName, szExcludedPattern) != NULL) >+ { >+ return true; >+ } >+ } >+ >+ return false; >+} >+// Add for bug 194081. Filter additional data referring to CanInstrumentClass > > void > CProfEnv::CheckMethodId(TId methodId) { >+ // Add for bug 194081 to filter additional data after reattach >+ SMethodInfo methodClassInfo = {0}; >+ TResult iRes = m_pMpiApi->GetMethodInfo(m_clientId, >+ methodId, DR_CLASS_NAME, &methodClassInfo); >+ LOG_ASSERT(iRes == MRTE_RESULT_OK); >+ LOG_ASSERT((methodClassInfo.validData & DR_CLASS_NAME) != 0); >+ >+ if (IsExcludedClass(methodClassInfo.szClassName)) >+ { >+ return; >+ } >+ // Add for bug 194081 to filter additional data after reattach >+ > bool isPrint = false; > > m_pMethodSDataLockObject->Enter(); >@@ -381,7 +471,7 @@ > methodInfo->managedToSrcLineMap.uiSize = 1; > methodInfo->managedToSrcLineMap.entries = (SLineNumberTableEntry*)malloc(sizeof(SLineNumberTableEntry) * 1); > >- TResult iRes = m_pMpiApi->GetMethodInfo(m_clientId, methodId, >+ iRes = m_pMpiApi->GetMethodInfo(m_clientId, methodId, > DR_JAVA_NATIVE_METHOD_NAME | DR_JAVA_NATIVE_METHOD_SIGNATURE | DR_METHOD_NAME | DR_METHOD_SIGNATURE | > DR_JAVA_NATIVE_CLASS_NAME | DR_CLASS_NAME | DR_METHOD_LINE_NUMBERS | DR_CLASS_ID | DR_MANAGED_TO_SRC_LINE_MAP, methodInfo); > if (iRes == MRTE_ERROR_BUFFER_TOO_SHORT) { >@@ -541,6 +631,7 @@ > int size = 0; > int maxDepth = ec_env->getMaxStackDepth(); > TResult retVal; >+ > do { > if(maxDepth >= 0){ > size = maxDepth; >@@ -574,9 +665,21 @@ > for (unsigned int i = 0; i < stackTrace->uiSize; i++) { > stackTrace->pStackEntries[i].methodId = threadInfo.vmOffsetStack.pStackEntries[i].methodId; > SMethodInfo* methodInfo = GetMethodData(stackTrace->pStackEntries[i].methodId); >- stackTrace->pStackEntries[i].methodName = (char*)malloc(strlen(methodInfo->szMethodName) + strlen(methodInfo->szMethodSig) + strlen(methodInfo->szClassName) + 3); >- sprintf(stackTrace->pStackEntries[i].methodName, "%s.%s %s", methodInfo->szClassName, methodInfo->szMethodName, methodInfo->szMethodSig); >- stackTrace->pStackEntries[i].lineNumber = GetLineNumber(threadInfo.vmOffsetStack.pStackEntries[i].location, &(methodInfo->managedToSrcLineMap)); >+ if (NULL != methodInfo) >+ { >+ stackTrace->pStackEntries[i].methodName = >+ (char*)malloc(strlen(methodInfo->szMethodName) + >+ strlen(methodInfo->szMethodSig) + >+ strlen(methodInfo->szClassName) + 3); >+ >+ sprintf(stackTrace->pStackEntries[i].methodName, "%s.%s %s", >+ methodInfo->szClassName, methodInfo->szMethodName, methodInfo->szMethodSig); >+ >+ stackTrace->pStackEntries[i].lineNumber = >+ GetLineNumber(threadInfo.vmOffsetStack.pStackEntries[i].location, >+ &(methodInfo->managedToSrcLineMap)); >+ } >+ > } > free(threadInfo.vmOffsetStack.pStackEntries); > } >@@ -598,13 +701,19 @@ > void > CProfEnv::FreeStackTrace(SStackTrace_* stackTrace) > { >- if (stackTrace->pStackEntries == 0) { >+ if (NULL == stackTrace || stackTrace->pStackEntries == NULL) { > return; > } > for (unsigned int i = 0; i < stackTrace->uiSize; i++) { >- free(stackTrace->pStackEntries[i].methodName); >+ if (NULL != stackTrace->pStackEntries[i].methodName) >+ { >+ free(stackTrace->pStackEntries[i].methodName); >+ stackTrace->pStackEntries[i].methodName = NULL; >+ } > } > free(stackTrace->pStackEntries); >+ stackTrace->pStackEntries = NULL; >+ stackTrace->uiSize = 0; > } > > //================================================================================== >@@ -791,3 +900,462 @@ > return MRTE_RESULT_OK; > } > >+//================================================================== >+// Add for bug 194081 >+CCGShadowStackTracker::CCGShadowStackTracker(CProfEnv& profEnv) >+ : m_refProfEnv(profEnv) >+{ >+ m_lockVMStackDataMap = CreateThreadSync(); >+} >+ >+CCGShadowStackTracker::~CCGShadowStackTracker() >+{ >+ if (m_lockVMStackDataMap) >+ { >+ m_lockVMStackDataMap->Destroy(); >+ } >+} >+ >+bool CCGShadowStackTracker::isNeedTrack() >+{ >+ return ( >+ ((m_refProfEnv.ec_env)->isCGExecDetails()) && >+ !((m_refProfEnv.ec_env)->isStandAlone()) >+ ); >+} >+ >+bool CCGShadowStackTracker::ValidateCGShadowStackTracker() >+{ >+ if (!isNeedTrack()) >+ { >+ return true; >+ } >+ >+ // You can add additional validate condition in this function >+ return (NULL != m_lockVMStackDataMap); >+} >+ >+void CCGShadowStackTracker::TrackVMShutdown() >+{ >+ if (!(m_refProfEnv.IsSupportedEG(EG_CALL_GRAPH))) >+ {// For profilers' common events, just handle for call graph >+ return; >+ } >+ >+ if (!isNeedTrack()) >+ { >+ return; >+ } >+ >+ ReportLeftStackTrackDataMethodsLeave(); >+} >+ >+TResult CCGShadowStackTracker::InitNewThreadInfoArray( >+ SThreadInfoArray& threadInfoArray, >+ int MAX_THREADS, int MAX_FRAMES) >+{ >+ DestroyThreadInfoArray(threadInfoArray); >+ >+ threadInfoArray.pEntries = >+ (SThreadInfoArrayEntry*)malloc(sizeof(SThreadInfoArrayEntry) * MAX_THREADS); >+ if (NULL == threadInfoArray.pEntries) >+ { >+ return MRTE_ERROR_OUT_OF_MEMORY; >+ } >+ >+ threadInfoArray.uiSize = MAX_THREADS; >+ memset(threadInfoArray.pEntries, 0, sizeof(SThreadInfoArrayEntry) * MAX_THREADS); >+ >+ unsigned int i = 0; >+ for (i = 0; i < MAX_THREADS; i++) >+ { >+ threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.uiSize = MAX_FRAMES; >+ threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries = new SStackEntry[MAX_FRAMES]; >+ >+ if (NULL == threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries) >+ { >+ DestroyThreadInfoArray(threadInfoArray); >+ return MRTE_ERROR_OUT_OF_MEMORY; >+ } >+ >+ memset(threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries, 0, >+ sizeof(SStackEntry) * MAX_FRAMES); >+ } >+ >+ return MRTE_RESULT_OK; >+} >+ >+void CCGShadowStackTracker::DestroyThreadInfoArray( >+ SThreadInfoArray& threadInfoArray) >+{ >+ if (NULL != threadInfoArray.pEntries) >+ { >+ for (unsigned int i = 0; i < threadInfoArray.uiSize; i++) >+ { >+ if (NULL != threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries) >+ { >+ delete [](threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries); >+ } >+ } >+ >+ free(threadInfoArray.pEntries); >+ } >+ >+ threadInfoArray.uiSize = 0; >+ threadInfoArray.uiActualSize = 0; >+} >+ >+TResult CCGShadowStackTracker::GetInitialShadowStackTraces( >+ SThreadInfoArray& threadInfoArray) >+{ >+ // Suspend all VM threads and Get all threads stack traces >+ TResult res = (m_refProfEnv.m_pMpiApi)->SuspendVM(); >+ if (MRTE_FAILED(res)) >+ { >+ LOG_ERROR("Can not suspend VM when try to get shadow stack sanpshot") >+ return res; >+ } >+ >+ // TODO: This fixed thread num and frame num is a limit, referring to original AttachEvent.cpp >+ int MAX_THREADS = 100; >+ int MAX_FRAMES = 100; >+ >+ res = InitNewThreadInfoArray(threadInfoArray, MAX_THREADS, MAX_FRAMES); >+ if (MRTE_FAILED(res)) >+ { >+ (m_refProfEnv.m_pMpiApi)->ResumeVM(); >+ return res; >+ } >+ >+ res = (m_refProfEnv.m_pMpiApi)->GetAllThreadsInfo(m_refProfEnv.m_clientId, MAX_FRAMES, >+ DR_VM_RELATIVE_STACK_TRACE, &threadInfoArray); >+ if (MRTE_FAILED(res)) >+ { >+ (m_refProfEnv.m_pMpiApi)->ResumeVM(); >+ DestroyThreadInfoArray(threadInfoArray); >+ } >+ >+ return res; >+} >+ >+void CCGShadowStackTracker::ReportThreadsStart(SThreadInfoArray& threadInfoArray) >+{ >+ for (unsigned int threadIdx = 0; threadIdx < threadInfoArray.uiActualSize; threadIdx++) >+ { >+ SThreadInfoArrayEntry* pThread = &(threadInfoArray.pEntries[threadIdx]); >+ >+ // Clear outdated data >+ m_refProfEnv.m_Tickets.ReleaseTicket(pThread->threadId); >+ m_refProfEnv.m_Tickets.DeleteThread(pThread->threadId); >+ >+ // Add new data info >+ m_refProfEnv.m_Tickets.AddNewThread(pThread->threadId); >+ >+ m_refProfEnv.GetThreadInfo(m_refProfEnv.m_clientId, pThread->threadId, >+ DR_THREAD_INFO | DR_THREAD_ELAPSED_TIME | DR_THREAD_CPU_TIME, &(pThread->threadInfo)); >+ >+ if (m_refProfEnv.m_profilerIsActive) >+ { >+ (m_refProfEnv.ec_env)->PrintThreadStartElement(pThread->threadId, 0, >+ &(pThread->threadInfo)); >+ } >+ else >+ { >+ m_refProfEnv.StoreThreadEvent(pThread->threadId, THREAD_START_EVENT, >+ &(pThread->threadInfo), 0); >+ } >+ } >+} >+ >+void CCGShadowStackTracker::ReportMethodEnter(TId threadId, SThreadInfo* pThreadInfo, TId methodId) >+{ >+ // Get classId according to methodId >+ SMethodInfo methodInfo = {0}; >+ TResult iRes = (m_refProfEnv.m_pMpiApi)->GetMethodInfo(m_refProfEnv.m_clientId, >+ methodId, DR_CLASS_ID | DR_CLASS_NAME, &methodInfo); >+ LOG_ASSERT(iRes == MRTE_RESULT_OK); >+ LOG_ASSERT((methodInfo.validData & DR_CLASS_ID) != 0); >+ LOG_ASSERT((methodInfo.validData & DR_CLASS_NAME) != 0); >+ >+ if (m_refProfEnv.IsExcludedClass(methodInfo.szClassName)) >+ { >+ return; >+ } >+ >+ // Just for Exec Details >+ m_refProfEnv.CheckMethodId(methodId); >+ >+ if (m_refProfEnv.m_profilerIsActive) >+ {// Profiler is in run mode >+ unsigned long ticket = m_refProfEnv.m_Tickets.GetNewTicket(threadId, >+ pThreadInfo->uiCpuNanos, true); >+ unsigned long stackDepth = m_refProfEnv.m_Tickets.GetStackDepth(threadId); >+ (m_refProfEnv.ec_env)->PrintMethodEntryElement(threadId, methodId, >+ methodInfo.classId, ticket, stackDepth); >+ } >+ else >+ {// Profiler is in pause mode >+ m_refProfEnv.m_Tickets.AddMethodEnterData(threadId, methodId, >+ methodInfo.classId, pThreadInfo->uiCpuNanos); >+ } >+} >+ >+void CCGShadowStackTracker::ReportMethodsEnter(SThreadInfoArray& threadInfoArray) >+{ >+ for (unsigned int threadIdx = 0; threadIdx < threadInfoArray.uiActualSize; threadIdx++) >+ { >+ TId threadId = threadInfoArray.pEntries[threadIdx].threadId; >+ SThreadInfo* pThreadInfo = &(threadInfoArray.pEntries[threadIdx].threadInfo); >+ >+ for (int stackTraceIdx = (pThreadInfo->vmOffsetStack).uiActualSize - 1; stackTraceIdx >= 0 ; >+ stackTraceIdx--) >+ { >+ // Get methodId from stack trace info >+ SStackEntry* pStackEntry = &(pThreadInfo->vmOffsetStack.pStackEntries[stackTraceIdx]); >+ >+ ReportMethodEnter(threadId, pThreadInfo, pStackEntry->methodId); >+ } >+ } >+} >+ >+void CCGShadowStackTracker::SaveAllShadowStacksMethods(SThreadInfoArray& threadInfoArray) >+{ >+ for (unsigned int threadIdx = 0; threadIdx < threadInfoArray.uiActualSize; threadIdx++) >+ { >+ SThreadInfoArrayEntry* pThread = &(threadInfoArray.pEntries[threadIdx]); >+ CVMStackTrackData vmStacks; >+ vmStacks.threadId = pThread->threadId; >+ unsigned int stackTraceSize = >+ (pThread->threadInfo).vmOffsetStack.uiActualSize; >+ >+ for (int stackTraceIdx = stackTraceSize - 1; stackTraceIdx >= 0; stackTraceIdx--) >+ { >+ vmStacks.shadowStack.push( >+ (pThread->threadInfo).vmOffsetStack.pStackEntries[stackTraceIdx].methodId); >+ } >+ >+ m_VMStacktraceDataMap.insert( >+ std::pair<MPI::TId, CVMStackTrackData>(vmStacks.threadId, vmStacks)); >+ } >+} >+ >+void CCGShadowStackTracker::TrackECAttach() >+{ >+ if (!(m_refProfEnv.IsSupportedEG(EG_CALL_GRAPH))) >+ {// For profilers' common events, just handle for call graph >+ return; >+ } >+ >+ if (!isNeedTrack()) >+ { >+ return; >+ } >+ >+ SThreadInfoArray threadInfoArray = {0}; >+ TResult res = GetInitialShadowStackTraces(threadInfoArray); >+ if (MRTE_FAILED(res)) >+ { >+ LOG_ERROR("Can not get VM thread stack traces info.") >+ return; >+ } >+ >+ // Report related events and get initial shadow stacks >+ ReportThreadsStart(threadInfoArray); >+ >+ ReportMethodsEnter(threadInfoArray); >+ >+ SaveAllShadowStacksMethods(threadInfoArray); >+ >+ DestroyThreadInfoArray(threadInfoArray); >+ (m_refProfEnv.m_pMpiApi)->ResumeVM(); >+} >+ >+void CCGShadowStackTracker::TrackECDetach() >+{ >+ if (!(m_refProfEnv.IsSupportedEG(EG_CALL_GRAPH))) >+ {// For profilers' common events, just handle for call graph >+ return; >+ } >+ >+ if (!isNeedTrack()) >+ { >+ return; >+ } >+ >+ ReportLeftStackTrackDataMethodsLeave(); >+} >+ >+void CCGShadowStackTracker::ReportMethodLeave(TId threadId, TId methodId, >+ TTimeStamp uiCpuNanos) >+{ >+ SMethodInfo methodInfo; >+ TResult iRes = (m_refProfEnv.m_pMpiApi)->GetMethodInfo(m_refProfEnv.m_clientId, >+ methodId, DR_CLASS_ID | DR_CLASS_NAME, &methodInfo); >+ LOG_ASSERT(iRes == MRTE_RESULT_OK); >+ LOG_ASSERT((methodInfo.validData & DR_CLASS_ID) != 0); >+ LOG_ASSERT((methodInfo.validData & DR_CLASS_NAME) != 0); >+ >+ if (m_refProfEnv.IsExcludedClass(methodInfo.szClassName)) >+ { >+ return; >+ } >+ >+ // Just for Exec Details >+ U64 cpuTime = uiCpuNanos - m_refProfEnv.m_Tickets.GetCpuTime(threadId); >+ unsigned long ticket = m_refProfEnv.m_Tickets.ReleaseTicket(threadId); >+ >+ if (m_refProfEnv.m_profilerIsActive) >+ { >+ (m_refProfEnv.ec_env)->PrintMethodExitElement(threadId, methodId, >+ methodInfo.classId, ticket, cpuTime); >+ } >+ else if (ticket != -1) >+ { >+ m_refProfEnv.AddMethodLeaveData(threadId, methodId, methodInfo.classId, >+ ticket, cpuTime); >+ } >+} >+ >+void CCGShadowStackTracker::UpdateShadowStack(stack< TId >& tmpShadowStack, >+ stack< TId >& shadowStack, const SMethodEnterEventData& data) >+{ >+ // Because normal stack is empty now, the tmpShadowStack must less or equal shadowStack >+ while (tmpShadowStack.size() < shadowStack.size()) >+ {// Geneate method leave events for shadow stack method >+ TId methodId = shadowStack.top(); >+ shadowStack.pop(); >+ ReportMethodLeave(data.threadId, methodId, data.uiCpuNanos); >+ } >+} >+ >+void CCGShadowStackTracker::TrackMethodEnter(SMethodEnterEventData &data) >+{ >+ if (!isNeedTrack()) >+ { >+ return; >+ } >+ >+ m_lockVMStackDataMap->Enter(); >+ map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.find(data.threadId); >+ >+ if (pos == m_VMStacktraceDataMap.end()) >+ {// Enter a new thread after attach, it has no shadow stack record and can be handled normally >+ m_lockVMStackDataMap->Leave(); >+ return; >+ } >+ >+ CVMStackTrackData& refVmStacks = pos->second; >+ >+ if (refVmStacks.normalStack.empty()) >+ { >+ SStackTrace_ stackTrace = {0}; >+ >+ m_refProfEnv.GetStackTrace(data.threadId, &stackTrace); >+ >+ std::stack< MPI::TId > tmpShadowStack; >+ // Ignore the new entered method, CGProxy.EarlyMethodEnter and CGProxy.MethodEnter on the stack top >+ const int ignoredMethodNum = 3; >+ for (int stackTraceIdx = stackTrace.uiSize - 1; stackTraceIdx > ignoredMethodNum - 1; stackTraceIdx--) >+ { >+ tmpShadowStack.push(stackTrace.pStackEntries[stackTraceIdx].methodId); >+ } >+ >+ UpdateShadowStack(tmpShadowStack, refVmStacks.shadowStack, data); >+ >+ if (NULL != stackTrace.pStackEntries) >+ { >+ stackTrace.uiSize = 0; >+ free(stackTrace.pStackEntries); >+ } >+ } >+ >+ refVmStacks.normalStack.push(data.methodId); >+ m_lockVMStackDataMap->Leave(); >+} >+ >+// return value: If continue to handle the MethodLeave events >+bool CCGShadowStackTracker::TrackMethodLeave(SMethodLeaveEventData &data) >+{ >+ if (!isNeedTrack()) >+ { >+ return true; >+ } >+ >+ m_lockVMStackDataMap->Enter(); >+ map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.find(data.threadId); >+ >+ if (pos == m_VMStacktraceDataMap.end()) >+ {// Enter a new thread after attach, it has no shadow stack record and can be handled normally >+ m_lockVMStackDataMap->Leave(); >+ return true; >+ } >+ >+ CVMStackTrackData& refVmStacks = pos->second; >+ >+ if (refVmStacks.normalStack.empty()) >+ {// Method leave notification is generated by instrumet before reattach, ignore it >+ m_lockVMStackDataMap->Leave(); >+ return false; >+ } >+ else >+ { >+ refVmStacks.normalStack.pop(); >+ m_lockVMStackDataMap->Leave(); >+ return true; >+ } >+} >+ >+void CCGShadowStackTracker::TrackThreadEnd(SThreadEventData &data) >+{ >+ if (!isNeedTrack()) >+ { >+ return; >+ } >+ >+ m_lockVMStackDataMap->Enter(); >+ map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.find(data.threadId); >+ >+ if (pos == m_VMStacktraceDataMap.end()) >+ {// Enter a new thread after attach, it has no shadow stack record and can be handled normally >+ m_lockVMStackDataMap->Leave(); >+ return; >+ } >+ >+ CVMStackTrackData& refVmStacks = pos->second; >+ >+ // refVmStacks.shadowStack report method leave events >+ while (!refVmStacks.shadowStack.empty()) >+ { >+ TId methodId = refVmStacks.shadowStack.top(); >+ refVmStacks.shadowStack.pop(); >+ ReportMethodLeave(data.threadId, methodId, m_refProfEnv.m_Tickets.GetCpuTime(data.threadId)); >+ } >+ m_lockVMStackDataMap->Leave(); >+} >+ >+void CCGShadowStackTracker::ReportLeftStackTrackDataMethodsLeave() >+{ >+ m_lockVMStackDataMap->Enter(); >+ >+ map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.begin(); >+ for(; pos != m_VMStacktraceDataMap.end(); pos++) >+ { >+ CVMStackTrackData& refVmStacks = pos->second; >+ >+ while (!refVmStacks.normalStack.empty()) >+ { >+ TId methodId = refVmStacks.normalStack.top(); >+ refVmStacks.normalStack.pop(); >+ ReportMethodLeave(pos->first, methodId, m_refProfEnv.m_Tickets.GetCpuTime(pos->first)); >+ } >+ >+ while (!refVmStacks.shadowStack.empty()) >+ { >+ TId methodId = refVmStacks.shadowStack.top(); >+ refVmStacks.shadowStack.pop(); >+ ReportMethodLeave(pos->first, methodId, m_refProfEnv.m_Tickets.GetCpuTime(pos->first)); >+ } >+ } >+ m_lockVMStackDataMap->Leave(); >+} >+// Add for bug 194081 >Index: src-native/src/BaseProf/DetachEvent.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/BaseProf/DetachEvent.cpp,v >retrieving revision 1.5 >diff -u -r1.5 DetachEvent.cpp >--- src-native/src/BaseProf/DetachEvent.cpp 29 Feb 2008 19:09:12 -0000 1.5 >+++ src-native/src/BaseProf/DetachEvent.cpp 20 May 2009 04:42:49 -0000 >@@ -40,7 +40,10 @@ > if (!m_pProfEnv->m_bVMInitDone) { > return; > } >- m_pProfEnv->ec_env->SetProfileOption("EXECDETAILS", "false"); >+ // Modify for bug 194081 >+ // m_pProfEnv->ec_env->SetProfileOption("EXECDETAILS", "false"); >+ m_pProfEnv->m_pShadowStackTracker->TrackECDetach(); >+ // Modify for bug 194081 > if (!m_pProfEnv->IsSupportedEG(EG_CALL_GRAPH) && !m_pProfEnv->IsSupportedEG(EG_HEAP)) { > return; > } >Index: src-native/src/BaseProf/ProfEnv.h >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/BaseProf/ProfEnv.h,v >retrieving revision 1.24 >diff -u -r1.24 ProfEnv.h >--- src-native/src/BaseProf/ProfEnv.h 8 Dec 2008 13:37:37 -0000 1.24 >+++ src-native/src/BaseProf/ProfEnv.h 20 May 2009 04:42:50 -0000 >@@ -15,6 +15,11 @@ > #ifndef _PROF_ENV_H_ > #define _PROF_ENV_H_ > >+// Add for bug 194081 >+#include <stack> >+#include <map> >+// Add for bug 194081 >+ > #include "MpiAPI.h" > #include "OSA.h" > >@@ -50,6 +55,76 @@ > MPI::SThreadInfo threadInfo; //For THREAD_START_EVENT only > MPI::TId objectId; //For THREAD_START_EVENT only > }; >+ >+ // Add for bug 194081 >+ class CCGShadowStackTracker >+ { >+ class CVMStackTrackData >+ { >+ public: >+ MPI::TId threadId; >+ std::stack< MPI::TId > shadowStack; >+ std::stack< MPI::TId > normalStack; >+ }; >+ >+ public: >+ CCGShadowStackTracker(CProfEnv& profEnv); >+ ~CCGShadowStackTracker(); >+ >+ // Assure init process is successful, called by CProfEnv init >+ bool ValidateCGShadowStackTracker(); >+ >+ //--------------------------------------------------------------------- >+ // Common profiler events need to be tracked, except for VMInit, ECStart and ECStop event >+ void TrackVMShutdown(); >+ >+ void TrackECAttach(); >+ void TrackECDetach(); >+ >+ //--------------------------------------------------------------------- >+ // Call Graph profiler specialized events, except for NewMethod and ThreadStart >+ void TrackMethodEnter(MPI::SMethodEnterEventData& data); >+ >+ // TrackMethodLeave return bool to avoid handle MethodLeave events before reattach >+ bool TrackMethodLeave(MPI::SMethodLeaveEventData& data); >+ >+ void TrackThreadEnd(MPI::SThreadEventData &data); >+ >+ private: >+ // Functions for deciding whether to track corresponding events >+ bool isNeedTrack(); >+ >+ // Used by ECAttach tracker >+ TResult InitNewThreadInfoArray(MPI::SThreadInfoArray& threadInfoArray, >+ int MAX_THREADS, int MAX_FRAMES); >+ void DestroyThreadInfoArray(MPI::SThreadInfoArray& threadInfoArray); >+ >+ TResult GetInitialShadowStackTraces(MPI::SThreadInfoArray& threadInfoArray); >+ void ReportThreadsStart(MPI::SThreadInfoArray& threadInfoArray); // Refer to CGProf ThreadStartHandler >+ >+ void ReportMethodEnter(MPI::TId threadId, MPI::SThreadInfo* pThreadInfo, MPI::TId methodId); >+ void ReportMethodsEnter(MPI::SThreadInfoArray& threadInfoArray); >+ >+ void SaveAllShadowStacksMethods(MPI::SThreadInfoArray& threadInfoArray); >+ >+ // Used by MethodEnter and ThreadEnd trackers, ReportLeftStackTrackDataMethodsLeave >+ void ReportMethodLeave(MPI::TId threadId, MPI::TId methodId, MPI::TTimeStamp uiCpuNanos); >+ >+ // Used by MethodEnter tracker >+ void UpdateShadowStack(std::stack< MPI::TId >&, std::stack< MPI::TId >&, >+ const MPI::SMethodEnterEventData&); >+ >+ // Used by VMShutdown and Detach trackers >+ // Generate method leave events for each left methods in track stack >+ void ReportLeftStackTrackDataMethodsLeave(); >+ >+ private: >+ CProfEnv& m_refProfEnv; >+ >+ OSA::IThreadSync* m_lockVMStackDataMap; >+ std::map< MPI::TId, CVMStackTrackData > m_VMStacktraceDataMap; >+ }; >+ // Add for bug 194081 > > class CProfEnv > { >@@ -82,6 +157,9 @@ > bool IsObjectStored(MPI::TId objectId); > // > // void AddNewMethodData(MPI::SMethodInfo* pSMethodInfo, MPI::TId methodId); >+ // Add for bug 194081 >+ void DeleteMethodsData(); >+ // Add for bug 194081 > void AddNewMethodData(MPI::SMethodInfo* pSMethodInfo, MPI::TId methodId, bool isPrinted); > // > MPI::SMethodInfo* GetMethodData(MPI::TId methodId); >@@ -151,6 +229,14 @@ > MPI::TId m_clientId; > // Profiler library name > char* profName; >+ >+ // Add for bug 194081 >+ CCGShadowStackTracker* m_pShadowStackTracker; >+ >+ // Filter some additional classes after reattach >+ bool IsExcludedClass(const char* szClassName); >+ // Add for bug 194081 >+ > private: > CClassDefDataSet* m_pClassSData; > OSA::IThreadSync* m_pClassSDataLockObject; >Index: src-native/src/BaseProf/AttachEvent.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/BaseProf/AttachEvent.cpp,v >retrieving revision 1.15 >diff -u -r1.15 AttachEvent.cpp >--- src-native/src/BaseProf/AttachEvent.cpp 7 Mar 2008 18:16:16 -0000 1.15 >+++ src-native/src/BaseProf/AttachEvent.cpp 20 May 2009 04:42:49 -0000 >@@ -41,10 +41,33 @@ > if (!m_pProfEnv->m_bVMInitDone) { > return; > } >- >+ > m_pProfEnv->DeleteAggCallGraphData(); > m_pProfEnv->DeleteStoredThreadEvents(); > >+ // Add for bug 194081 >+ if (m_pProfEnv->ec_env->isCGExecDetails()) >+ { >+ m_pProfEnv->DeleteMethodsData(); >+ m_pProfEnv->m_pShadowStackTracker->TrackECAttach(); >+ >+ TResult res = m_pProfEnv->EnableSupportedEG(); >+ if (MRTE_FAILED(res)) >+ { >+ if (MRTE_ERROR_PHASE_FAILURE == res) >+ { >+ LOG_DIE("Attach failed (too early)"); >+ } >+ else >+ { >+ LOG_DIE("Attach failed"); >+ } >+ } >+ >+ return; >+ } >+ // Add for bug 194081 >+ > const int MAX_THREADS = 100; > const int MAX_FRAMES = 100; > TResult res; >@@ -161,7 +184,7 @@ > } > } > for (i = 0; i < MAX_THREADS; i++) { >- delete threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries; >+ delete [](threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries); > } > } else { > res = m_pProfEnv->m_pMpiApi->GetAllThreadsInfo(m_pProfEnv->m_clientId, 0, DR_THREAD_INFO, &threadInfoArray); >Index: src-native/src/BaseProf/BaseProfiler.h >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/BaseProf/BaseProfiler.h,v >retrieving revision 1.4 >diff -u -r1.4 BaseProfiler.h >--- src-native/src/BaseProf/BaseProfiler.h 23 Mar 2007 14:04:45 -0000 1.4 >+++ src-native/src/BaseProf/BaseProfiler.h 20 May 2009 04:42:49 -0000 >@@ -35,7 +35,7 @@ > // Constructor > CBaseProfiler(); > // Destructor >- ~CBaseProfiler(); >+ virtual ~CBaseProfiler(); > // Initialization > TResult Init(MPI::IMpi *pMpiApi, MPI::TId clientId, const char *szOptions); > >Index: src-native/src/BaseProf/VMShutdownEvent.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/BaseProf/VMShutdownEvent.cpp,v >retrieving revision 1.4 >diff -u -r1.4 VMShutdownEvent.cpp >--- src-native/src/BaseProf/VMShutdownEvent.cpp 23 Mar 2007 14:04:45 -0000 1.4 >+++ src-native/src/BaseProf/VMShutdownEvent.cpp 20 May 2009 04:42:50 -0000 >@@ -41,6 +41,16 @@ > if (!m_pProfEnv->m_profilerIsActive) { > return; > } >- m_pProfEnv->PrintAggCallGraph(); >+ // Modified for bug 194081 >+ if (m_pProfEnv->ec_env->isCGExecDetails()) >+ { >+ m_pProfEnv->m_pShadowStackTracker->TrackVMShutdown(); >+ } >+ else >+ { >+ m_pProfEnv->PrintAggCallGraph(); >+ } >+ // Modified for bug 194081 >+ > m_pProfEnv->ec_env->PrintRuntimeShutdownElement(); > } >Index: src-native/src/CGProf/ThreadEndEvent.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/CGProf/ThreadEndEvent.cpp,v >retrieving revision 1.7 >diff -u -r1.7 ThreadEndEvent.cpp >--- src-native/src/CGProf/ThreadEndEvent.cpp 20 Nov 2007 09:12:40 -0000 1.7 >+++ src-native/src/CGProf/ThreadEndEvent.cpp 20 May 2009 04:42:50 -0000 >@@ -40,6 +40,10 @@ > { > if ((data.validData & DR_THREAD_ID) != 0) > { >+ // Add for bug 194081 >+ m_pProfEnv->m_pShadowStackTracker->TrackThreadEnd(data); >+ // Add for bug 194081 >+ > m_pProfEnv->m_Tickets.DeleteThread(data.threadId); > if (!m_pProfEnv->m_profilerIsActive) { > m_pProfEnv->StoreThreadEvent(data.threadId, THREAD_END_EVENT, &data, 0); >Index: src-native/src/CGProf/MethodEnterEvent.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/CGProf/MethodEnterEvent.cpp,v >retrieving revision 1.12 >diff -u -r1.12 MethodEnterEvent.cpp >--- src-native/src/CGProf/MethodEnterEvent.cpp 8 Dec 2008 13:37:37 -0000 1.12 >+++ src-native/src/CGProf/MethodEnterEvent.cpp 20 May 2009 04:42:50 -0000 >@@ -44,6 +44,10 @@ > LOG_ASSERT((data.validData & DR_METHOD_ID) != 0); > LOG_ASSERT((data.validData & DR_THREAD_ID) != 0); > LOG_ASSERT((data.validData & DR_THREAD_CPU_TIME) != 0); >+ >+ // Add for bug 194081 >+ m_pProfEnv->m_pShadowStackTracker->TrackMethodEnter(data); >+ // Add for bug 194081 > > SMethodInfo classInfo; > TResult iRes = m_pProfEnv->m_pMpiApi->GetMethodInfo(m_pProfEnv->m_clientId, data.methodId, >Index: src-native/src/CGProf/MethodLeaveEvent.cpp >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/CGProf/MethodLeaveEvent.cpp,v >retrieving revision 1.13 >diff -u -r1.13 MethodLeaveEvent.cpp >--- src-native/src/CGProf/MethodLeaveEvent.cpp 28 Feb 2008 02:20:33 -0000 1.13 >+++ src-native/src/CGProf/MethodLeaveEvent.cpp 20 May 2009 04:42:50 -0000 >@@ -42,6 +42,14 @@ > LOG_ASSERT((data.validData & DR_METHOD_ID) != 0); > LOG_ASSERT((data.validData & DR_THREAD_ID) != 0); > LOG_ASSERT((data.validData & DR_THREAD_CPU_TIME) != 0); >+ >+ // Add for bug 194081 >+ bool isContinueHandleMethodLeave = m_pProfEnv->m_pShadowStackTracker->TrackMethodLeave(data); >+ if (!isContinueHandleMethodLeave) >+ { >+ return; >+ } >+ // Add for bug 194081 > > SMethodInfo classInfo; > TResult iRes = m_pProfEnv->m_pMpiApi->GetMethodInfo(m_pProfEnv->m_clientId, data.methodId, >Index: src-native/src/JPIAgent/Options.h >=================================================================== >RCS file: /cvsroot/tptp/platform/org.eclipse.tptp.platform.jvmti.runtime/src-native/src/JPIAgent/Options.h,v >retrieving revision 1.21 >diff -u -r1.21 Options.h >--- src-native/src/JPIAgent/Options.h 5 Jun 2008 22:04:51 -0000 1.21 >+++ src-native/src/JPIAgent/Options.h 20 May 2009 04:42:50 -0000 >@@ -144,7 +144,10 @@ > > // is CG pfofiler aggregated > bool isCGExecDetails() { >- return (!isEnabled()) && (m_jvmtiAgent_Options.cgExecDetails == 1); //in enabled mode we support aggregated cg profiler only >+ // Modified for bug 194081 >+ //return (!isEnabled()) && (m_jvmtiAgent_Options.cgExecDetails == 1); //in enabled mode we support aggregated cg profiler only >+ return (m_jvmtiAgent_Options.cgExecDetails == 1); >+ // Modified for bug 194081 > } > > // if cg memory should be freed after snapshot then returns true
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 194081
:
102226
|
133879
|
133881
|
135756
|
136422
|
139720
|
140395
|
140396
|
140397