-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SampleProfiler incorrectly marks all samples as external code on Windows #45179
Comments
Tagging subscribers to this area: @tommcdon Issue DetailsThe SampleProfiler sends ThreadSample events that reference stacks. The payload of these events is supposed to indicate what type of code was executing in the leaf frame at the time of suspension. runtime/src/coreclr/src/vm/sampleprofiler.cpp Lines 238 to 250 in 3f89665
The SampleProfiler uses a cached value of runtime/src/coreclr/src/vm/threads.h Lines 4627 to 4654 in 73a7993
Currently, runtime/src/coreclr/src/vm/threadsuspend.cpp Lines 6071 to 6096 in c8c0790
Unfortunately, this code is only used for thread suspension on non-Windows platforms. This means that all sample events on Windows are marked as "external" code since the underlying value is never changed from the uninitialized value of This value is used in tools like PerfView to do analysis on things like CPU blocking time. We need to determine a location to call One spot I'm vetting is here: runtime/src/coreclr/src/vm/threadsuspend.cpp Lines 3519 to 3526 in 93cbc09
in I'm not sure how long this has been an issue, but I'm guessing it has been since this logic went in (~4 years ago circa .NET Core 2.2). Is there another way we could transmit this information? We could save the 4 bytes per sample event if we do away with this payload. That can add up fast when you have ~1000 samples per thread per second. That's roughly 4kb/s for a value that will always be 1 or 2. Could we intern this information directly into the stack events? That would require a format change, though. CC @sywhang @noahfalk @brianrob @tommcdon
|
Good catch @josalem. I suspect you are right that this has been this way since 2.2, as the initial EventPipe implementation in 2.0 was limited to UNIX which uses a different suspension mechanism. |
The SampleProfiler sends ThreadSample events that reference stacks. The payload of these events is supposed to indicate what type of code was executing in the leaf frame at the time of suspension.
runtime/src/coreclr/src/vm/sampleprofiler.cpp
Lines 238 to 250 in 3f89665
The SampleProfiler uses a cached value of
m_fPreemptiveGCDisabled
to determine whether to mark a sample as "managed" (GC was in COOP mode) or "external" (GC was in preemptive mode).runtime/src/coreclr/src/vm/threads.h
Lines 4627 to 4654 in 73a7993
Currently,
SaveGCModeOnSuspension
is only called fromHandleGCSuspensionForInterruptedThread
.runtime/src/coreclr/src/vm/threadsuspend.cpp
Lines 6071 to 6096 in c8c0790
Unfortunately, this code is only used for thread suspension on non-Windows platforms. This means that all sample events on Windows are marked as "external" code since the underlying value is never changed from the uninitialized value of
0
(meaning preemptive mode). On Linux/Mac systems, however, stacks are correctly labeled.This value is used in tools like PerfView to do analysis on things like CPU blocking time.
We need to determine a location to call
SaveGCModeOnSuspension
that works for both platforms or add a call to the equivalent location on Windows.One spot I'm vetting is here:
runtime/src/coreclr/src/vm/threadsuspend.cpp
Lines 3519 to 3526 in 93cbc09
in
ThreadSuspend::SuspendRuntime
where it enumerates all the threads it is about to suspend.I'm not sure how long this has been an issue, but I'm guessing it has been since this logic went in (~4 years ago circa .NET Core 2.2).
Is there another way we could transmit this information? We could save the 4 bytes per sample event if we do away with this payload. That can add up fast when you have ~1000 samples per thread per second. That's roughly 4 kb/s per thread for a value that will always be 1 or 2. Could we intern this information directly into the stack events? That would require a format change, though.
CC @sywhang @noahfalk @brianrob @tommcdon
The text was updated successfully, but these errors were encountered: