Skip to content

MAUI Android Line Numbers & File Names Don't Appear in .NET 9 (But They Do in .NET 8) #4209

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

Open
lswdowcoombs opened this issue May 20, 2025 · 11 comments · May be fixed by #4221
Open

MAUI Android Line Numbers & File Names Don't Appear in .NET 9 (But They Do in .NET 8) #4209

lswdowcoombs opened this issue May 20, 2025 · 11 comments · May be fixed by #4221

Comments

@lswdowcoombs
Copy link

Package

Sentry.Maui

.NET Flavor

.NET

.NET Version

9.0.203

OS

Android

OS Version

Android 13

Development Environment

Visual Studio v17.x

SDK Version

5.7.0

Self-Hosted Sentry Version

No response

Workload Versions

Installed Workload Id Manifest Version Installation Source
android 35.0.61/9.0.100 SDK 9.0.200, VS 17.13.35931.197
aspire 8.2.2/8.0.100 SDK 9.0.200, VS 17.13.35931.197
ios 18.4.9288/9.0.100 SDK 9.0.200, VS 17.13.35931.197
maccatalyst 18.4.9288/9.0.100 SDK 9.0.200, VS 17.13.35931.197
maui-windows 9.0.51/9.0.100 SDK 9.0.200, VS 17.13.35931.197
wasm-tools 9.0.4/9.0.100 SDK 9.0.200, VS 17.13.35931.197
wasm-tools-net8 9.0.4/9.0.100 SDK 9.0.200

UseSentry or SentrySdk.Init call

options.Dsn = "MY-SENTRY-DSN";

Steps to Reproduce

  1. Create a new .NET MAUI App Project in Visual Studio. Be sure to select .NET 9.
  2. Install Sentry.Maui version 5.7.0.
  3. Add the block of code for UseSentry() above to add the Dsn to startup options.
  4. In the sample app, open up MainPage.xaml.cs and throw an exception in the OnCounterClicked() method, for example, just so that can be logged to Sentry.
  5. In the sample app csproj file, add the following so that debug symbols are created and uploaded to Sentry automatically during the build. Replace SentryOrg, SentryProject, and SentryAuthToken accordingly:
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <SentryOrg>MY-SENTRY-ORG-NAME</SentryOrg>
  <SentryProject>MY-SENTRY-PROJECT-NAME</SentryProject>
  <SentryAuthToken>MY-SENTRY-AUTH-TOKEN</SentryAuthToken>
  <SentryUploadSymbols>true</SentryUploadSymbols>
</PropertyGroup>
  1. Build for Release, targeting Android.
  2. Verify that debug symbols are uploaded to Sentry for your project in the Outputs section of Visual Studio.
  3. Run the sample app without a debugger, targeting Android.
  4. Click/tap on the Click me button to increment the counter.
  5. Observe that the sample app should crash. Reopen the app to ensure that the crash details are sent up to Sentry.

Expected Result

An unhandled exception should be sent to Sentry and when viewing the details of the associated event, the stack trace should include line numbers and file names.

Actual Result

An unhandled exception is sent to Sentry, but when viewing the details of the associated event, the stack trace does not include line numbers and file names.

NOTE: If you repeat the above steps but use a project that targets .NET 8, line numbers and file names DO appear in the stack trace on Sentry.

@jamescrosswell
Copy link
Collaborator

I'm unable to reproduce this. Here's an example of a fully symbolicated unhandled crash on Android from the Sentry.Samples.Maui app included in the repository:

Image

If you can provide a minimal reproducible example of the problem then we could take a further look at it.

@lswdowcoombs
Copy link
Author

@jamescrosswell Thanks for the response.

The steps I outlined use the sample project created by Visual Studio for .NET MAUI, but I've uploaded a copy of it for your convenience to here: https://github.com/lswdowcoombs/MauiAndroidSentryTest

All you should have to do is search for TODO and replace the Dsn and Sentry properties accordingly, then build and run the app for release. Here is a screenshot of the exception that gets uploaded to Sentry when clicking the Click me button. As you can see, the stack trace does not contain line numbers or file names.

Hopefully this is just a simple matter of additional configuration needed on my end, but I've combed through the sample project you mentioned and nothing has jumped out at me that I've missed...

Image

@jamescrosswell
Copy link
Collaborator

jamescrosswell commented May 22, 2025

@lswdowcoombs the line numbers (and even source code) shows fine for me when I run your sample:

Image

About the only thing that tripped me up was that you've guarded the symbol upload so that it only occurs for release builds:
https://github.com/lswdowcoombs/MauiAndroidSentryTest/blob/22b9380becfc72d8a1b4b053159f594fe22fdd54/MauiAndroidSentryTest.csproj#L44-L52 and there didn't appear to be any configurations defined for the project/solution (Debug or Release).

When I removed that condition from the property group, the Sentry CLI was executed and debug symbols uploaded correctly on build... so that might be the issue you're running into?

Basically, when you're running a build, you should see something like this when the symbol upload is working correctly:

"/Users/jamescrosswell/.nuget/packages/sentry/5.7.0/tools/sentry-cli-Darwin-arm64" info --no-defaults
Preparing upload to Sentry for project 'MauiAndroidSentryTest' (Debug/net9.0-android): collecting debug symbols from bin/Debug/net9.0-android/ obj/Debug/net9.0-android/app_shared_libraries/arm64-v8a/libxamarin-app.so obj/Debug/net9.0-android/lp/176/jl/jni/arm64-v8a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/arm64-v8a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/jni/armeabi-v7a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/armeabi-v7a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/jni/x86/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/x86/libsentry.so obj/Debug/net9.0-android/lp/176/jl/jni/x86_64/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/x86_64/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.arm64-v8a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.armeabi-v7a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.x86/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.x86_64/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.arm64-v8a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.armeabi-v7a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.x86/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.x86_64/libsentry.so obj/Debug/net9.0-android/lp/177/jl/jni/arm64-v8a/libsentrysupplemental.so obj/Debug/net9.0-android/lp/177/jl/jni/armeabi-v7a/libsentrysupplemental.so obj/Debug/net9.0-android/lp/177/jl/jni/x86/libsentrysupplemental.so obj/Debug/net9.0-android/lp/177/jl/jni/x86_64/libsentrysupplemental.so
"/Users/jamescrosswell/.nuget/packages/sentry/5.7.0/tools/sentry-cli-Darwin-arm64" debug-files upload --org sentry-sdks --project sentry-dotnet -t pdb -t portablepdb -t elf bin/Debug/net9.0-android/ obj/Debug/net9.0-android/app_shared_libraries/arm64-v8a/libxamarin-app.so obj/Debug/net9.0-android/lp/176/jl/jni/arm64-v8a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/arm64-v8a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/jni/armeabi-v7a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/armeabi-v7a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/jni/x86/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/x86/libsentry.so obj/Debug/net9.0-android/lp/176/jl/jni/x86_64/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/jni/x86_64/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.arm64-v8a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.armeabi-v7a/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.x86/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry-android/libs/android.x86_64/libsentry-android.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.arm64-v8a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.armeabi-v7a/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.x86/libsentry.so obj/Debug/net9.0-android/lp/176/jl/prefab/modules/sentry/libs/android.x86_64/libsentry.so obj/Debug/net9.0-android/lp/177/jl/jni/arm64-v8a/libsentrysupplemental.so obj/Debug/net9.0-android/lp/177/jl/jni/armeabi-v7a/libsentrysupplemental.so obj/Debug/net9.0-android/lp/177/jl/jni/x86/libsentrysupplemental.so obj/Debug/net9.0-android/lp/177/jl/jni/x86_64/libsentrysupplemental.so
> Found 22 debug information files (1 with embedded sources)
> Prepared debug information files for upload
> Uploaded 1 missing debug information file
> File upload complete:

  UPLOADED 6c0d3fa0-f288-4b1c-b6e1-48d0170bed1d-e2704389 (MauiAndroidSentryTest.pdb;  debug companion)

That's the Sentry CLI being run to find and upload debug symbols so that symbolication of stack traces works as expected.

@lswdowcoombs
Copy link
Author

@jamescrosswell Thanks for the response. So the reason I had that guard in place was to mimic our production application - because the whole point is to detect and log exceptions in our release builds easily across all platforms.

But even with that guard removed entirely, Android Release builds never show line numbers on Sentry. Debug builds do though. In both cases, I see output from the Sentry CLI, and the fact that events are being uploaded suggests that the setup is correct. But something about being a Release build seems to prevent line numbers from appearing.

Below is my output from a Release build, which seems to match yours above for the most part.

1>      Preparing upload to Sentry for project 'MauiAndroidSentryTest' (Release/net9.0-android): collecting debug symbols from bin\Release\net9.0-android\ obj\Release\net9.0-android\app_shared_libraries\arm64-v8a\assemblies.arm64-v8a.blob.so obj\Release\net9.0-android\app_shared_libraries\arm64-v8a\libxamarin-app.so obj\Release\net9.0-android\app_shared_libraries\x86_64\assemblies.x86_64.blob.so obj\Release\net9.0-android\app_shared_libraries\x86_64\libxamarin-app.so obj\Release\net9.0-android\lp\173\jl\jni\arm64-v8a\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\jni\arm64-v8a\libsentry.so obj\Release\net9.0-android\lp\173\jl\jni\armeabi-v7a\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\jni\armeabi-v7a\libsentry.so obj\Release\net9.0-android\lp\173\jl\jni\x86\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\jni\x86\libsentry.so obj\Release\net9.0-android\lp\173\jl\jni\x86_64\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\jni\x86_64\libsentry.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.arm64-v8a\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.armeabi-v7a\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.x86\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.x86_64\libsentry-android.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.arm64-v8a\libsentry.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.armeabi-v7a\libsentry.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.x86\libsentry.so obj\Release\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.x86_64\libsentry.so obj\Release\net9.0-android\lp\174\jl\jni\arm64-v8a\libsentrysupplemental.so obj\Release\net9.0-android\lp\174\jl\jni\armeabi-v7a\libsentrysupplemental.so obj\Release\net9.0-android\lp\174\jl\jni\x86\libsentrysupplemental.so obj\Release\net9.0-android\lp\174\jl\jni\x86_64\libsentrysupplemental.so
1>      > Found 23 debug information files (1 with embedded sources)
1>      > Prepared debug information files for upload
1>      > Uploaded 3 missing debug information files
1>      > File upload complete:
1>
1>        UPLOADED 8c21ce8a-660d-915d-540e-efd83b6de357-da57a303 (MauiAndroidSentryTest.pdb;  debug companion)
1>        UPLOADED d317d8cf-000a-befc-0000-000000000000 (libxamarin-app.so; arm64 library)
1>        UPLOADED 1d374f9e-90be-8d31-0000-000000000000 (libxamarin-app.so; x86_64 library)

And for posterity, here is the output from a Debug build:

1>        Preparing upload to Sentry for project 'MauiAndroidSentryTest' (Debug/net9.0-android): collecting debug symbols from bin\Debug\net9.0-android\ obj\Debug\net9.0-android\app_shared_libraries\x86_64\libxamarin-app.so obj\Debug\net9.0-android\lp\173\jl\jni\arm64-v8a\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\jni\arm64-v8a\libsentry.so obj\Debug\net9.0-android\lp\173\jl\jni\armeabi-v7a\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\jni\armeabi-v7a\libsentry.so obj\Debug\net9.0-android\lp\173\jl\jni\x86\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\jni\x86\libsentry.so obj\Debug\net9.0-android\lp\173\jl\jni\x86_64\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\jni\x86_64\libsentry.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.arm64-v8a\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.armeabi-v7a\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.x86\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry-android\libs\android.x86_64\libsentry-android.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.arm64-v8a\libsentry.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.armeabi-v7a\libsentry.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.x86\libsentry.so obj\Debug\net9.0-android\lp\173\jl\prefab\modules\sentry\libs\android.x86_64\libsentry.so obj\Debug\net9.0-android\lp\174\jl\jni\arm64-v8a\libsentrysupplemental.so obj\Debug\net9.0-android\lp\174\jl\jni\armeabi-v7a\libsentrysupplemental.so obj\Debug\net9.0-android\lp\174\jl\jni\x86\libsentrysupplemental.so obj\Debug\net9.0-android\lp\174\jl\jni\x86_64\libsentrysupplemental.so
1>        > Found 22 debug information files (1 with embedded sources)
1>        > Prepared debug information files for upload
1>
1>      Done building project "MauiAndroidSentryTest.csproj".
1>    > Uploaded 2 missing debug information files
1>    > File upload complete:
1>
1>      UPLOADED 1a330269-e058-4164-bfa7-440d3b5114d0-a3055c61 (MauiAndroidSentryTest.pdb;  debug companion)
1>      UPLOADED d62890a4-53b1-eb8c-0000-000000000000 (libxamarin-app.so; x86_64 library)

@jamescrosswell
Copy link
Collaborator

@lswdowcoombs just checking in to say that I can reproduce the issue from the sample you provided. Still trying to work out what the cause is though...

@jamescrosswell
Copy link
Collaborator

When running Sentry.Samples.Maui in Release mode, I see this being logged to LogCat:

Skipping debug image for module 'Sentry.Samples.Maui.dll' because assembly wasn't found: 'Sentry.Samples.Maui.dll'

Which is coming from here:

options.LogDebug("Skipping debug image for module '{0}' because assembly wasn't found: '{1}'",
moduleName, assemblyName);
return null;

Basically it can't resolve the DebugImage.

Digging a little further in the logs I'm also seeing this:

Debug: Couldn't find assembly Sentry.Samples.Maui.dll in the APK

Which is coming from the V2 Assembly Reader:

Logger?.Invoke("Couldn't find assembly {0} in the APK", name);

What's curious is that we have this scenario tested here (not AOT and not using the AssemblyStore):

<MSBuild Projects="$(MSBuildProjectFile)" Targets="_BuildTestAPK" Properties="_Aot=False;_Store=False;_Compressed=False" />
<MSBuild Projects="$(MSBuildProjectFile)" Targets="_BuildTestAPK" Properties="_Aot=False;_Store=False;_Compressed=True" />

Needs further investigation.

@lswdowcoombs
Copy link
Author

Thanks for the update, @jamescrosswell

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 May 26, 2025
@jamescrosswell
Copy link
Collaborator

jamescrosswell commented May 26, 2025

OK so I've made a bit more progress here. The APK files that we're testing against aren't the same as the APKs that get installed on a simulator/device.

We adapted our AndroidAssemblyDirectoryReaderV2 from here but those utils aren't necessarily kept up to date and I don't think that one has been updated to support the AAB/APK file format used by .NET 9.

In Release mode when targeting net9.0-android, an AAB file is built instead of an APK. This contains all of the files required to deploy the application on any device. The AAB is what sits in the Google Play store. When someone actually installs the application though, they don't download the AAB... instead Google splits the AAB up into a bunch of separate smaller packages, some of which are required for some devices and some of which are required for others. Among these "device specific" things are all the processor specific natively compiled files in the lib directory.

Our Assembly Reader is currently looking for modules in a base.apk... if we compare that base.apk to the APK that we build and test against, we can see it's missing a /lib folder. However on the device (or simulator in my case) there is a split_config.arm64_v8a.apk next to the base.apk. This contains the /lib files required to run the application on an arm64_v8a device.

To cut a long story short, in some situations we should be loading modules from the appropriate split_config file rather than the base.apk.

There is a secondary problem, however... which is that all of the .NET assemblies in the split_config file are prefixed with libaot- and they don't appear to contain any ELF payload.

Note that when using AssemblyStores (which is the default) the modules will not be embedded directly in the lib/[arch] folder of either the base.apk or the split_config.[arch].apk file. Instead they're lumped together in the libassemblies.arm64-v8a.blob.so file (that's the assembly store).

@jamescrosswell
Copy link
Collaborator

It looks like AndroidStudio uses something called the bundletool and this can be used to both pull out device specific APKs from an AAB file and deploy APKs to a device.

The bundletool is open source so potentially we could find out from the source code how the files are being deployed.

@jamescrosswell
Copy link
Collaborator

@lswdowcoombs after a couple of days of digging, I've finally found a fix for this. Hopefully we'll have a new release including this by late this week or early next week.

@lswdowcoombs
Copy link
Author

@jamescrosswell Thank you! I appreciate your digging into this one and look forward to the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Status: No status
Development

Successfully merging a pull request may close this issue.

3 participants