Hi,
In my CLR profiler, I am going to get stack trace of each thread.
For that, i set the event mask COR_PRF_MONITOR_THREADS | COR_PRF_ENABLE_STACK_SNAPSHOT in my profiler initialize function.
When a thread created|destroyed modify the respected threadid in a set.( m_registeredThreadIds)
My sample webapplication as follows ,
public void method22() { int kl = 0; kl++; while (true) { if (kl == 20) break; kl++; Thread.Sleep(100); } method23(); } public void method23() { Thread.Sleep(3000); method24(); } public void method24() { int kl = 0; kl++; while (true) { if (kl == 70) break; kl++; Thread.Sleep(100); } method25(); } public void method25() { Thread.Sleep(1000); method26(); } public void method26() { int kl = 0; kl++; while (true) { if (kl == 50) break; kl++; Thread.Sleep(100); } method27(); } public static void method2() { // It prints numbers from 0 to 10 // for (int J = 0; J <= 10; J++) { //Console.WriteLine("Method2 is : {0}", J); } test t = new test(); t.method22(); } protected void Page_Load(object sender, EventArgs e) { // Main Method Thread thr2 = new Thread(method2); thr2.Start(); }
below piece of code got it from CLR profiler project. This sample method calling from separate thread,
D
WORD WINAPI StackWalker::Sample(void * data){ StackWalker * pThis = (StackWalker *) data; vector<FunctionID> functionIdsSnapshot; HRESULT hr = 0; int i =0; wofstream of; of.open("c:\\temp\\stackwalk.txt", ios::app); of << "Sampling method started.."<<pThis->m_continueSampling << endl; while(pThis->m_continueSampling){ EnterCriticalSection(pThis->m_stackLock); { of << "m_registeredThreadIds.size:"<<pThis->m_registeredThreadIds.size() << endl; for(set<ThreadID>::iterator it = pThis->m_registeredThreadIds.begin(); it != pThis->m_registeredThreadIds.end(); it++){ ThreadID threadId = *it; functionIdsSnapshot.clear(); hr = pThis->m_nativeCallback->m_pProfilerInfo->DoStackSnapshot(threadId,&MakeFrameWalk,0, &functionIdsSnapshot,0,0); if(SUCCEEDED(hr)) { of << "functionIdsSnapshot.size:"<<functionIdsSnapshot.size() << endl; vector<FunctionID>::iterator it_fun = functionIdsSnapshot.begin(); of << "Threadid :" << *it << endl; for(;it_fun!=functionIdsSnapshot.end();it_fun++) { if((*it_fun)!=0) of << " ------>function name :" << pThis->m_nativeCallback->GetFunctionNameFromID(*it_fun) << endl; else of << " ------>function is zero - 0"<<endl; } } else of << "make frame method failed....:"<<hr<<endl; } } LeaveCriticalSection(pThis->m_stackLock); //if(!pThis->m_continueSampling) break; if(i==100) break; Sleep(pThis->m_samplingPeriodMs); i++; } of.close(); DWORD success = 1; return success;}
am getting the stack trace of thread (thr2) and written into a file as follows,
Threadid :1016953202368
------>function name :System.Void System.Threading.Thread:Sleep(System.Int32)
------>function name :System.Void WebApplication1.sample:method26()
------>function name :System.Void System.Threading.ExecutionContext:RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, System.Boolean)
------>function name :System.Void System.Threading.ExecutionContext:Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, System.Boolean)
------>function name :System.Void System.Threading.ExecutionContext:Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
------>function name :System.Void System.Threading.ThreadHelper:ThreadStart()
while executing method26() am getting the output as above, why i didn;t get method25(),method24(),method23(),method22() for the thread?
In my web application execution as follows,
pageload()->threadcreation-> method2()->method22()-> method23()-> method24()-> method25()-> method26()
when method26() getting executed i have to get complete callgraph,
what i am missing here?