Trim internal JFR stacktraces to match OpenJDK #10385
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary:
OpenJDK JFR does not record VM level frames. Previously, Native Image JFR reported internal SubstrateVM frames in stacktraces. This is bad because it makes it confusing/difficult for users to see where events are coming from since the ends of every trace look the same. For example, this adds noise to flamegraphs. It can also mislead to users to believing that SubstrateVM internals are the cause of event emissions if they are accustomed to the way stacktraces are reported in OpenJDK.
This PR adds trimming of internal JFR stacktraces by default. I've also added a runtime option to disable this (and revert to the old behavior) to aid in Native Image development/debugging. Now, any SubstrateVM frames in samples taken by the CPU profiler or regular events are filtered out.
Use
-XX:-JfrTrimInternalStackTraces
to disable the filtering at runtime.Related Issue: #7095
Note:
In this PR, the filtering is done at the time of stacktrace serialization. This happens at a chunk rotation. The problem with this approach is that we have already computed the stacktraces up to the maximum depth specified by the user (default is 64). So, it the point of sampling, we may need to truncate at the max depth, then later we may further reduce the stacktrace size by filtering during serialization. This means we would have truncated some frames unnecessarily. In reality, this is probably not much of an issue since there's only 3-5 internal frames being filtered out for most events. I've considered the below alternatives:
FrameInfoCursor
instance. This isn't possible because we need to do the stack-walking inside the JFR sampler signal handler. It's also not possible to allocate a newFrameInfoCursor
whenever we need to use it. One solution is to preallocate an instance ofFrameInfoCursor
for each thread and useJfrExecutionSampler.preventSamplingInCurrentThread()
to prevent races if preempted for signal handling. But this seems overly complex and unnecessary compared to the current solution.