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

Perfetto incorrectly resolves symbol names in libunity.so #1005

Closed
jsjtxietian opened this issue Feb 8, 2025 · 4 comments
Closed

Perfetto incorrectly resolves symbol names in libunity.so #1005

jsjtxietian opened this issue Feb 8, 2025 · 4 comments

Comments

@jsjtxietian
Copy link

jsjtxietian commented Feb 8, 2025

Summary:
When I use perfetto to collect callstack for a demo built by official Unity2022.3.47, perfetto incorrectly resolves symbol names in libunity.so. Then I found the following log in prefetto's log:
local_symbolizer.cc:526 Correcting load bias by 5468160 for /data/app/~~S8bkoKJAPz8aBIZMYJhwbQ==/com.DefaultCompany.ForProfile-BdMMYGfVyo-Hk4y2sI7RlQ==/lib/arm64/libunity.so
which is produced by:

if (binary->load_bias > load_bias) {
// On Android 10, there was a bug in libunwindstack that would incorrectly
// calculate the load_bias, and thus the relative PC. This would end up in
// frames that made no sense. We can fix this up after the fact if we
// detect this situation.
load_bias_correction = binary->load_bias - load_bias;
PERFETTO_LOG("Correcting load bias by %" PRIu64 " for %s",
load_bias_correction, mapping_name.c_str());
}

I strongly suspect it is responsible for the incorrect symbol names (I'm confident that the libunity.so itself is ok), May I ask what does this code do and is it still necessary?

Reproduction steps:
I use Pixel9, which is Android 14, make a demo release version apk by official Unity2022.3.47 ( create symbols.zip debugging and do not choose development build) , after that modify the apk to make it debuggable.

After setting PERFETTO_SYMBOLIZER_MODE and PERFETTO_BINARY_PATH to the correct path, use https://github.com/google/perfetto/blob/main/tools/cpu_profile for sampling, observe the log and drag output file to perfetto to obverse callstack.

Let me know if I can provide more info.

@primiano
Copy link
Collaborator

Oh it is very possible that that code is causing the issue you describe.
Thanks so much for doing the research.

Would it be possible to share the problematic trace and the libunity.so with symbols (and let us know a frame that looks suspiciously bad) ?

I can ask @rsavitski to have a look then

You can share privately with Google Drive with [email protected] and [email protected] to avoid a public attachment here

Thanks for reporting it. This corner of ELF bites me anecdotally once every 10y (and when it does is never fun) :D

@jsjtxietian
Copy link
Author

jsjtxietian commented Feb 14, 2025

Oh it is very possible that that code is causing the issue you describe.

I'm confident now it is the culprit ( I asked my friend to reverse engineering the provided traceconv.exe to get rid of the if, then the result is right)

This is the evidence, which can be told from the simple flame graph, all symbol names from libunity.so are wrong:

Good:
Image

Bad:
Image

Here is the good trace and the bad one, along with libunity.so, the so is directly retrieved from unity's install location so I can attatch it here:

Build.zip

@jsjtxietian
Copy link
Author

jsjtxietian commented Feb 19, 2025

Also see android/ndk#2125 (comment)
I guess maybe it's the incorrect Offset for the executable LOAD segment of libunity.so makes perfetto went into the if mentioned earlier, so probably it's not perfetto's issue.

@LalitMaganti
Copy link
Collaborator

Ack thanks for confirming. Will close this out.

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

No branches or pull requests

3 participants