dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.29k stars 4.74k forks source link

Ability to get managed threads handles via DAC API #54414

Open k15tfu opened 3 years ago

k15tfu commented 3 years ago

I have an idea of getting managed thread names in ClrMD which is based on ISOSDacInterface interface.

At the moment there is no fast way to get this via DAC SOS API, we can only do this by enumerating all objects and taking the ones of type System.Threading.Thread. This takes about 2.2 seconds for my application, versus ~1ms when using ClrmdRuntime.Threads (https://github.com/microsoft/clrmd/blob/957981f36eeccb6e9d266407df6522ca5cfbd899/src/Microsoft.Diagnostics.Runtime/src/Implementation/ClrmdRuntime.cs#L27).

Now it looks like we can extend DAC API to get Thread::m_ExposedObject (https://github.com/dotnet/runtime/blob/556582d964cc21b82a88d7154e915076f6f9008e/src/coreclr/src/vm/threads.h#L2342-L2346) of given thread, so we will be able to read object fields to get the managed thread name (https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.name). The same thing is already used for debuggers in DacDbiInterfaceImpl::GetThreadObject(), but we cannot use it with ClrMD because it requires an initialized IDacDbiInterface interface.

As an advantage, the SOS clrstack command (https://github.com/dotnet/diagnostics/blob/main/documentation/sos-debugging-extension.md) can also use it to show managed thread names.

Linked issues: https://github.com/Microsoft/clrmd/issues/57

cc @mikem8361 @leculver

ghost commented 3 years ago

Tagging subscribers to this area: @tommcdon See info in area-owners.md if you want to be subscribed.

Issue Details
I have an idea of getting managed thread names in ClrMD which is based on `ISOSDacInterface` interface. At the moment there is no fast way to get this via DAC SOS API, we can only do this by enumerating all objects and taking the ones of type `System.Threading.Thread`. This takes about 2.2 seconds for my application, versus ~1ms when using `ClrmdRuntime.Threads` (https://github.com/microsoft/clrmd/blob/957981f36eeccb6e9d266407df6522ca5cfbd899/src/Microsoft.Diagnostics.Runtime/src/Implementation/ClrmdRuntime.cs#L27). Now it looks like we can extend DAC API to get `Thread::m_ExposedObject` (https://github.com/dotnet/runtime/blob/556582d964cc21b82a88d7154e915076f6f9008e/src/coreclr/src/vm/threads.h#L2342-L2346) of given thread, so we will be able to read object fields to get the managed thread name (https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.name). The same thing is already used for debuggers in `DacDbiInterfaceImpl::GetThreadObject()`, but we cannot use it with ClrMD because it requires an initialized `IDacDbiInterface` interface. As an advantage, the SOS `clrstack` command (https://github.com/dotnet/diagnostics/blob/main/documentation/sos-debugging-extension.md) can also use it to show managed thread names. Linked issues: https://github.com/Microsoft/clrmd/issues/57 cc @mikem8361 @leculver
Author: k15tfu
Assignees: -
Labels: `area-Diagnostics-coreclr`, `untriaged`
Milestone: -