.NET Framework Bookmark and Share   
 index > Building Development and Diagnostic Tools for .Net > Thread Crash scenarios with ICorProfilerCallback
 

Thread Crash scenarios with ICorProfilerCallback

Hello
I am writing a profiler using ICorProfilerCallback
During function ID mapper callback, i update a map from function ID to a function info structure. I have put this portion of code within a critical section (plan to replace it with mutex). If another thread causes this thread to terminate while it is updating the map then the map would end up in an inconsistent state. the approaches that i have thought of are:
1. Create a thread that reads a pipe for updating the map. the threads write to the pipe a packet that contains the information to be added to the map. if the information is completely received then the change is reflected in the map else it is discarded. this means we have less information in the end.
2. instead of a map, use a linked list so that updating it involves just updating head of the list. this however makes using the list during function enter/leave difficult.

are you aware of a design pattern that can solve this problem.

a related problem is the following. multiple managed threads can be mapped to the same os level thread. so if i use a tls to store data specific to each managed thread, i need to put a lock to access the shared data. now when i have obtained a lock and updating the managed thread specific data in the tls, then a thread switch may occur and another thread mapped to the same os level thread can put the thread with the lock to sleep and when this thread requires a lock to update the tls data, then a deadlock would occur.
is there a solution to this problem

another thing i want to know is that on which thread's stack is the thread destroyed callback executed. can we receive thread destroyed callback while we are processing another callback.
i don't think so. we cannot receive another callback in all other cases while we are processing another callback. is it right?
  • Edited byiamrohitbanga Sunday, July 12, 2009 1:53 PManother question
  •  

Answers

  • Monday, July 13, 2009 5:41 PMDavid BromanMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hi, Rohit.

    I would not worry about making your profiler code resilient to sudden thread killing. An app that suddenly goes and kills another thread will have bad synchronization problems whether your profiler is attached or not. Your enter probe is called as amanaged function is entered. Any number of critical sections could theoretically be entered during the course of executing managed code (either user locks, CLR locks, OS locks, etc.), even without your profiler around. So it's generally bad practice for the user code to just go killing threads. It's likely to deadlock on its own without your help.

    If the user code does a more structured thread killing (e.g., using the BCL to do a thread abort, or AppDomain unload), then the CLR will wait until that thread is no longer executing native code before allowing the abort / unload to occur. So your profiler native code will block those exceptions from occurring until you return.

    There is no guarantee that ThreadDestroyed is called on the same thread that's actually getting destroyed (which is why the profapi must specify the ThreadID as a parameter to your profiler in ThreadDestroyed). It is very common for your profiler to receive multiple callbacks simultaneously on different threads. Though I think you're asking whether one thread could be executing in your profiler's callback implementation, and then have that thread be suddenly redirected (hijacked) to execute in another of your profiler callback implementations. That should not happen.


    Thanks,
    Dave

All Replies

  • Monday, July 13, 2009 5:41 PMDavid BromanMSFT, OwnerUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hi, Rohit.

    I would not worry about making your profiler code resilient to sudden thread killing. An app that suddenly goes and kills another thread will have bad synchronization problems whether your profiler is attached or not. Your enter probe is called as amanaged function is entered. Any number of critical sections could theoretically be entered during the course of executing managed code (either user locks, CLR locks, OS locks, etc.), even without your profiler around. So it's generally bad practice for the user code to just go killing threads. It's likely to deadlock on its own without your help.

    If the user code does a more structured thread killing (e.g., using the BCL to do a thread abort, or AppDomain unload), then the CLR will wait until that thread is no longer executing native code before allowing the abort / unload to occur. So your profiler native code will block those exceptions from occurring until you return.

    There is no guarantee that ThreadDestroyed is called on the same thread that's actually getting destroyed (which is why the profapi must specify the ThreadID as a parameter to your profiler in ThreadDestroyed). It is very common for your profiler to receive multiple callbacks simultaneously on different threads. Though I think you're asking whether one thread could be executing in your profiler's callback implementation, and then have that thread be suddenly redirected (hijacked) to execute in another of your profiler callback implementations. That should not happen.


    Thanks,
    Dave
  • Tuesday, July 14, 2009 5:31 AMiamrohitbanga Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello Dave
    Thanks a lot for the reply.
    What about a thread sleep. I assume that the same holds for this. If a sleep is sent to a thread while it is executing profiler code then the sleep will not be affected till the code returns.
    by native code you mean any native code or profiler code only.

    but another situation can arise which i don't think can be handled now.
    when we are executing enter leave hooks (fast path) then if we receive a thread sleep the CLR would not know that we are executing in native code. if during entry leave hooks we acquire a lock then what happens?

    how do we map multiple managed threads to a single os thread?
    same behaviour there also right.

    Thanks
    Rohit Banga
  • Tuesday, July 14, 2009 5:41 AMiamrohitbanga Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    could you write a blog on it - Not so frequently asked questions
iamrohitbanga
Hi, Rohit. What do you mean by a sleep "sent" to the thread? A thread can make itself sleep. But one thread doesn't make another thread sleep. Perhaps you're talking about thread suspension / resume? These are similarly dangerous things for an app to do (because of the risk of deadlock), regardless of whether a profiler is attached. However, when a managed app requests to suspend a thread via the BCL, the CLR makes it a safer operation by allowing the target thread to get to a "safe point" before getting blocked. So a managed suspend request should not stop the thread while it's inside profiler code. This also holds true for fast path enter/leave/tailcall hooks.

When I used "native code" above I meant any code that's not JITted or NGENd. (Your profiler code qualifies as native code.)

A managed thread maps to one and only one OS thread. An OS thread maps to at most one managed thread. You will not see a many-to-one relationship in either direction.


Thanks,
Dave

David Broman

You can use google to search for other answers

Custom Search

More Threads

• Running Mdbg in my app (was Re: Custom Debugging)
• What Mocking Framework to use?
• profiler: filter "system calls"
• How to capture Trace.WriteLine output via DbgView on Vista?
• tracking context scheduling events
• ICorProfilerInfo::GetILFunctionBody doesn't return the correct size on methods with SEH?
• Performance Monitor Command Line Question
• CLRProfiler crashes aspnet_wp
• COMException "Bad binary signature"
• Converting header types when using SetILFunctionBody