简体   繁体   中英

Crashlytics with StrictMode enabled (detect all) gives “untagged socket detected”

I've tried adding Crashlytics to my app, which already has StrictMode enabled with detectAll() . The result was Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage .

Full Stack:

E/StrictMode: null
java.lang.Throwable: Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage
    at android.os.StrictMode.onUntaggedSocket(StrictMode.java:2012)
    at com.android.server.NetworkManagementSocketTagger.tag(NetworkManagementSocketTagger.java:78)
    at libcore.io.BlockGuardOs.tagSocket(BlockGuardOs.java:47)
    at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:310)
    at libcore.io.IoBridge.socket(IoBridge.java:667)
    at java.net.PlainSocketImpl.socketCreate(PlainSocketImpl.java:116)
    at java.net.AbstractPlainSocketImpl.create(AbstractPlainSocketImpl.java:98)
    at java.net.Socket.createImpl(Socket.java:484)
    at java.net.Socket.getImpl(Socket.java:547)
    at java.net.Socket.setSoTimeout(Socket.java:1175)
    at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:139)
    at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(Unknown Source:0)
    at io.fabric.sdk.android.services.network.HttpRequest.code(HttpRequest.java:1357)
    at io.fabric.sdk.android.services.settings.DefaultSettingsSpiCall.handleResponse(DefaultSettingsSpiCall.java:104)
    at io.fabric.sdk.android.services.settings.DefaultSettingsSpiCall.invoke(DefaultSettingsSpiCall.java:88)
    at io.fabric.sdk.android.services.settings.DefaultSettingsController.loadSettingsData(DefaultSettingsController.java:88)
    at io.fabric.sdk.android.services.settings.DefaultSettingsController.loadSettingsData(DefaultSettingsController.java:65)
    at io.fabric.sdk.android.services.settings.Settings.loadSettingsData(Settings.java:153)
    at io.fabric.sdk.android.Onboarding.retrieveSettingsData(Onboarding.java:126)
    at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:99)
    at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:45)
    at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:63)
    at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:28)
    at io.fabric.sdk.android.services.concurrency.AsyncTask$2.call(AsyncTask.java:311)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
W/System.err: StrictMode VmPolicy violation with POLICY_DEATH; shutting down.

I tried to create a new project and it was the same, the code in MainActivity in the test project:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setCrashlytics();
    setStrictMode();
}

private void setCrashlytics() {
    Fabric.with(this, new Crashlytics());
}

private void setStrictMode() {
    if (BuildConfig.DEBUG) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .penaltyDeath()
                .build());
    }
}

I did see that Okhttp has this issue (as well as other libs) but I do not know if that is relevant.
I'll add a workaround as an answer (basically don't use detectAll() ), but I wonder if there is a proper solution for this, maybe there's a way to add the tag to the socket?

A workaround is to not use detectAll() , I've copied the the code of detectAll() (from Crashlytics) and modified it; however I had to remove part of code since there are classes that are inaccessible.
I'm not a huge fan of this workaround but I'm not sure there's a better solution.

private void setStrictMode() {
    if (BuildConfig.DEBUG) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectAll()   // detectDiskReads, detectDiskWrites, detectNetwork
                .penaltyLog()
                .build());

        StrictMode.setVmPolicy(getStrictModeBuilder().build());
    }
}

private StrictMode.VmPolicy.Builder getStrictModeBuilder() {
    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();

    builder.detectLeakedSqlLiteObjects();

    final int sdkInt = Build.VERSION.SDK_INT;
    if (sdkInt >= Build.VERSION_CODES.HONEYCOMB) {
        builder.detectActivityLeaks();
        builder.detectLeakedClosableObjects();
    }

    if (sdkInt >= Build.VERSION_CODES.JELLY_BEAN) {
        builder.detectLeakedRegistrationObjects();
    }

    if (sdkInt >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        builder.detectFileUriExposure();
    }

    if (sdkInt >= Build.VERSION_CODES.O) {
        builder.detectContentUriWithoutPermission();
    }

    builder.penaltyLog().penaltyDeath();
    return builder;
}

Option two - remove the penaltyDeath() from the VmPolicy - this is what I'm currently doing:

private void setStrictMode() {
if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()   // detectDiskReads, detectDiskWrites, detectNetwork
            .penaltyLog()
            .build());

    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .build());
}

Api 28 has introduced:

public StrictMode.VmPolicy.Builder penaltyListener (Executor executor,
                StrictMode.OnVmViolationListener listener)

So at least you can listen for specific violations (like UntaggedSocketViolation) and choose to ignore them. Of course, it would be better if Crashlytics were to tag their sockets appropriately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM