Skip to content
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

Trim internal JFR stacktraces to match OpenJDK #10385

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

roberttoyonaga
Copy link
Collaborator

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:

  1. Use "skipCount" instead of filtering. This would require maintaining a hardcoded skipcount for each event type. For some events (such ObjectAllocationSample) multiple paths could be taken leading up to event emission so a single event may require different hardcoded skipcounts depending on the code path taken. I don't like this approach because it becomes harder to maintain as more events are added and the internal code changes.
  2. Filter earlier at the time of stack-walking (long before stacktrace serialization). This would allow us to avoid truncating traces unless truly necessary. The problem with this is that we'd need to synchronize access to a 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 new FrameInfoCursor whenever we need to use it. One solution is to preallocate an instance of FrameInfoCursor for each thread and use JfrExecutionSampler.preventSamplingInCurrentThread() to prevent races if preempted for signal handling. But this seems overly complex and unnecessary compared to the current solution.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
native-image native-image-jfr OCA Verified All contributors have signed the Oracle Contributor Agreement. redhat-interest
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant