[R8] [Optimization] Public fields in bindings are not protected by proguard rules
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 22/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Ambito
- build-system, mobile
Direzione di ricerca
Start with the generated proguard_project_references.cfg and compare its keep rules for com.facebook.LoggingBehavior and androidx.media3.exoplayer.ExoPlaybackException with the workaround rules in the issue. Then reproduce with TrimMode=full and AndroidLinkTool=r8 and check the R8 usage and proguard.map output for the removed enum value and the int to byte field change. Done means public fields and enum members used by bindings are kept, and the Type getter still matches the DEX field type.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Android framework version
net11.0-android (Preview)
Affected platform version
.NET 11.0.100-rc2
Description
It seems like public/protected fields in Java classes and enums, which managed code is accessing via bingings, are not protected by the generated proguard rules. This issue seems to be related to the optimization from https://github.com/dotnet/android/issues/12270, although most likely not caused by it.
Here are details that we discovered in our project, which is using native Facebook SDK binding and Xamarin.AndroidX.Media3.ExoPlayer nuget. During the build the following rules are generated in proguard_project_references.cfg:
-keep class com.facebook.LoggingBehavior
-keepclassmembers class com.facebook.LoggingBehavior {
}
-keep class androidx.media3.exoplayer.ExoPlaybackException
-keepclassmembers class androidx.media3.exoplayer.ExoPlaybackException {
}
com.facebook.LoggingBehavior is actually an enum, which values we are using via bindings, specifically
FacebookSdk.AddLoggingBehavior(LoggingBehavior.AppEvents);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.Cache);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.DeveloperErrors);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.GraphApiDebugInfo);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.GraphApiDebugWarning);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.IncludeAccessTokens);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.IncludeRawResponses);
FacebookSdk.AddLoggingBehavior(LoggingBehavior.Requests);
But because none of the enum values are protected by the generated rules, and with optimization enabled R8 decided to remove one of the values (seems like the only value with no explicit internal usage in Facebook SDK, at least after trimming). In the R8 "print usage" output there's the following record:
com.facebook.LoggingBehavior:
public static final enum com.facebook.LoggingBehavior CACHE
The case with androidx.media3.exoplayer.ExoPlaybackException is a bit different. We are using it's public Type field of type int like that:
if (exception is ExoPlaybackException error)
{
switch (error.Type)
{
...
}
}
In this case R8 does not remove the field completely, but performs another type of optimization (extracted from the proguard.map):
androidx.media3.exoplayer.ExoPlaybackException -> androidx.media3.exoplayer.ExoPlaybackException:
# {"id":"sourceFile","fileName":"ExoPlaybackException.java"}
boolean isRecoverable -> g
int type -> type
# {"id":"com.android.tools.r8.residualsignature","signature":"B"}
So the type of the field was optimized to be byte instead of int in DEX, while the binding code is still expecting int:
public int Type {
get {
return _members.InstanceFields.GetInt32Value ("type.I", this);
}
}
The issue probably become noticeable only after enabling R8 optimizations. We double-checked that with older .NET 10.0.200 same public fields are also not protected by default:
-keep class com.facebook.LoggingBehavior
-keepclassmembers class com.facebook.LoggingBehavior {
*** valueOf(...);
*** values(...);
}
-keep class androidx.media3.exoplayer.ExoPlaybackException
-keepclassmembers class androidx.media3.exoplayer.ExoPlaybackException {
*** getRendererException(...);
*** getSourceException(...);
*** getUnexpectedException(...);
*** createForRemote(...);
*** createForRenderer(...);
*** createForRenderer(...);
*** createForSource(...);
*** createForUnexpected(...);
*** createForUnexpected(...);
}
Steps to Reproduce
Seems like the issue can be reproduced on any .NET and Android workload version, but may lead to runtime crashes only in setup with R8 optimization enabled (11.0.100-rc.2/10.0.402)
- Android project with
TrimMode=fullandAndroidLinkTool=r8 - Access any native public field (like enum value) via binding
- Build project and check generated
proguard_project_references.cfg
Did you find any workaround?
Custom proguard rules file to protect public fields and enums:
-keepclassmembers enum * {
*;
}
-keepclassmembers class * {
public protected !static <fields>;
public protected static !final <fields>;
public protected static final ** *;
public protected static final **[] *;
}
Relevant log output
- Lingua principale
- C#
- Stelle
- 2.1k
- Fork
- 581
- Merge medio
- 1g 21h
- PR unite (30g)
- 241
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di dotnet/android
-
Area: App+Library Build
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Area: Mono.Android
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
dotnet/android#9192 · 4 commenti · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Area: Mono.Android needs-triage
Difficoltà 4/5 3-5 giorni Idoneità per principianti 30/100
I maintainer di solito rispondono entro 1 giorno
-
Area: App Runtime needs-triage
Difficoltà 4/5 3-5 giorni Idoneità per principianti 22/100
I maintainer di solito rispondono entro 1 giorno
-
flaky-ci flaky-tests needs-triage
Difficoltà 5/5 Più di una settimana Idoneità per principianti 8/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di dotnet/android
Issue simili
-
area: design documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
eyalgolan/statecraft-israel#883 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 3 giorni
-
area/indexing bug package/core triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
enhancement needs triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
elastic/docs-builder#4495 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
protobuf-net/protobuf-net#1375 · 2 commenti ·
I maintainer di solito rispondono entro 2 giorni