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

Fix function end detection #2636

Merged
merged 1 commit into from
Mar 26, 2024
Merged

Conversation

umanwizard
Copy link
Contributor

When constructing unwind tables, we add a synthetic entry marking the end of functions. This serves to allow the unwinder to detect program counters that fall between two functions. We only insert this synthetic row if it's possible to give it a program counter that doesn't overlap with anything else; that is, if there is a gap between the end of the function in question and the beginning of the next.

It's fine to omit the synthetic entries in the case where there is no gap, because in those cases, there isn't any way the PC can lie between to functions.

However, currently we also use the synthetic entries for another purpose: determining where it's okay to break the unwind table into shards (as it's not acceptable for a function to cross a shard boundary). This is imprecise, because the synthetic entries are not added in all cases, as described above. Indeed, binaries that have no gaps in a long enough sequence of functions can't be split anywhere and thus fail to be profiled.

This commit fixes that issue by looking at the original FDEs (which have actual function begin and end information) directly, rather than trying to find function boundaries by using the synthetic rows. It also factors out the chunk-splitting logic into a separate function so it can be tested.

@umanwizard umanwizard requested a review from a team as a code owner March 21, 2024 16:22
@umanwizard umanwizard force-pushed the fix-function-end branch 2 times, most recently from b8a6695 to 709a4e2 Compare March 21, 2024 16:51
When constructing unwind tables, we add a synthetic entry marking the
end of functions. This serves to allow the unwinder to detect program
counters that fall between two functions. We only insert this
synthetic row if it's possible to give it a program counter that
doesn't overlap with anything else; that is, if there is a gap between
the end of the function in question and the beginning of the next.

It's fine to omit the synthetic entries in the case where there is no
gap, because in those cases, there isn't any way the PC can lie
between to functions.

However, currently we _also_ use the synthetic entries for another
purpose: determining where it's okay to break the unwind table into
shards (as it's not acceptable for a function to cross a shard
boundary). This is imprecise, because the synthetic entries are not
added in all cases, as described above. Indeed, binaries that have no
gaps in a long enough sequence of functions can't be split anywhere
and thus fail to be profiled.

This commit fixes that issue by looking at the original FDEs (which
have actual function begin and end information) directly, rather than
trying to find function boundaries by using the synthetic rows. It
also factors out the chunk-splitting logic into a separate function so
it can be tested.
Copy link
Contributor

@gnurizen gnurizen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@@ -1821,6 +1823,44 @@ func (m *Maps) allocateNewShard() error {
return nil
}

// Get the largest chunk of `ut` (up to `maxLen`) that
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI some linters require the first word of a function doc comment to be the function name itself, apparently we don't have such a linter which surprises me.

@brancz brancz merged commit 19f413d into parca-dev:main Mar 26, 2024
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants