OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.components.minidump_uploader; | 5 package org.chromium.components.minidump_uploader; |
6 | 6 |
7 import org.chromium.base.Log; | 7 import org.chromium.base.Log; |
8 import org.chromium.base.ThreadUtils; | 8 import org.chromium.base.ThreadUtils; |
9 import org.chromium.base.VisibleForTesting; | 9 import org.chromium.base.VisibleForTesting; |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... | |
41 * The thread used for the actual work of uploading minidumps. | 41 * The thread used for the actual work of uploading minidumps. |
42 */ | 42 */ |
43 private Thread mWorkerThread; | 43 private Thread mWorkerThread; |
44 | 44 |
45 @VisibleForTesting | 45 @VisibleForTesting |
46 public static final int MAX_UPLOAD_TRIES_ALLOWED = 3; | 46 public static final int MAX_UPLOAD_TRIES_ALLOWED = 3; |
47 | 47 |
48 @VisibleForTesting | 48 @VisibleForTesting |
49 public MinidumpUploaderImpl(MinidumpUploaderDelegate delegate) { | 49 public MinidumpUploaderImpl(MinidumpUploaderDelegate delegate) { |
50 mDelegate = delegate; | 50 mDelegate = delegate; |
51 mFileManager = createCrashFileManager(mDelegate.createCrashDir()); | 51 mFileManager = createCrashFileManager(mDelegate.getCacheDir()); |
52 if (!mFileManager.ensureCrashDirExists()) { | 52 if (!mFileManager.ensureCrashDirExists()) { |
53 Log.e(TAG, "Crash directory doesn't exist!"); | 53 Log.e(TAG, "Crash directory doesn't exist!"); |
54 } | 54 } |
55 } | 55 } |
56 | 56 |
57 /** | 57 /** |
58 * Utility method to allow tests to customize the behavior of the crash file manager. | 58 * Utility method to allow tests to customize the behavior of the crash file manager. |
59 * @param {crashDir} The directory in which to store crash files (i.e. minid umps). | 59 * @param {cacheDir} The cache directory, which contains the crash directory , in which crash |
60 * files (i.e. minidumps) are stored. | |
60 */ | 61 */ |
61 @VisibleForTesting | 62 @VisibleForTesting |
62 public CrashFileManager createCrashFileManager(File crashDir) { | 63 public CrashFileManager createCrashFileManager(File cacheDir) { |
63 return new CrashFileManager(crashDir); | 64 return new CrashFileManager(cacheDir); |
64 } | 65 } |
65 | 66 |
66 /** | 67 /** |
67 * Utility method to allow us to test the logic of this class by injecting | 68 * Utility method to allow us to test the logic of this class by injecting |
68 * test-specific MinidumpUploadCallables. | 69 * test-specific MinidumpUploadCallables. |
69 */ | 70 */ |
70 @VisibleForTesting | 71 @VisibleForTesting |
71 public MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFile , File logfile) { | 72 public MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFile , File logfile) { |
72 return new MinidumpUploadCallable( | 73 return new MinidumpUploadCallable( |
73 minidumpFile, logfile, mDelegate.createCrashReportingPermissionM anager()); | 74 minidumpFile, logfile, mDelegate.createCrashReportingPermissionM anager()); |
74 } | 75 } |
75 | 76 |
76 /** | 77 /** |
77 * Runnable that upload minidumps. | 78 * Runnable that upload minidumps. |
78 * This is where the actual uploading happens - an upload job consists of po sting this Runnable | 79 * This is where the actual uploading happens - an upload job consists of po sting this Runnable |
79 * to the worker thread. | 80 * to the worker thread. |
80 */ | 81 */ |
81 private class UploadRunnable implements Runnable { | 82 private class UploadRunnable implements Runnable { |
82 private final MinidumpUploader.UploadsFinishedCallback mUploadsFinishedC allback; | 83 private final MinidumpUploader.UploadsFinishedCallback mUploadsFinishedC allback; |
83 | 84 |
84 public UploadRunnable(MinidumpUploader.UploadsFinishedCallback uploadsFi nishedCallback) { | 85 public UploadRunnable(MinidumpUploader.UploadsFinishedCallback uploadsFi nishedCallback) { |
85 mUploadsFinishedCallback = uploadsFinishedCallback; | 86 mUploadsFinishedCallback = uploadsFinishedCallback; |
86 } | 87 } |
87 | 88 |
88 @Override | 89 @Override |
89 public void run() { | 90 public void run() { |
90 File[] minidumps = mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES _ALLOWED); | 91 File[] minidumps = mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES _ALLOWED); |
92 Log.i(TAG, "Attempting to upload %d minidumps ", minidumps.length); | |
91 for (File minidump : minidumps) { | 93 for (File minidump : minidumps) { |
94 Log.i(TAG, "Attempting to upload " + minidump.getName()); | |
92 MinidumpUploadCallable uploadCallable = createMinidumpUploadCall able( | 95 MinidumpUploadCallable uploadCallable = createMinidumpUploadCall able( |
93 minidump, mFileManager.getCrashUploadLogFile()); | 96 minidump, mFileManager.getCrashUploadLogFile()); |
94 int uploadResult = uploadCallable.call(); | 97 int uploadResult = uploadCallable.call(); |
95 | 98 |
96 // Bail if the job was canceled. Note that the cancelation statu s is checked AFTER | 99 // Bail if the job was canceled. Note that the cancelation statu s is checked AFTER |
97 // trying to upload a minidump. This is to ensure that the sched uler attempts to | 100 // trying to upload a minidump. This is to ensure that the sched uler attempts to |
98 // upload at least one minidump per job. Otherwise, it's possibl e for a crash loop | 101 // upload at least one minidump per job. Otherwise, it's possibl e for a crash loop |
99 // to continually write files to the crash directory; each such write would | 102 // to continually write files to the crash directory; each such write would |
100 // reschedule the job, and therefore cancel any pending jobs. In such a scenario, | 103 // reschedule the job, and therefore cancel any pending jobs. In such a scenario, |
101 // it's important to make at least *some* progress uploading min idumps. | 104 // it's important to make at least *some* progress uploading min idumps. |
102 // Note that other likely cancelation reasons are not a concern, because the upload | 105 // Note that other likely cancelation reasons are not a concern, because the upload |
103 // callable checks relevant state prior to uploading. For exampl e, if the job is | 106 // callable checks relevant state prior to uploading. For exampl e, if the job is |
104 // canceled because the network connection is lost, or because t he user switches | 107 // canceled because the network connection is lost, or because t he user switches |
105 // over to a metered connection, the callable will detect the ch anged network state, | 108 // over to a metered connection, the callable will detect the ch anged network state, |
106 // and not attempt an upload. | 109 // and not attempt an upload. |
107 if (mCancelUpload) return; | 110 if (mCancelUpload) return; |
108 | 111 |
109 // Note that if the job was canceled midway through, the attempt number is not | 112 // Note that if the job was canceled midway through, the attempt number is not |
110 // incremented, even if the upload failed. This is because a com mon reason for | 113 // incremented, even if the upload failed. This is because a com mon reason for |
111 // cancelation is loss of network connectivity, which does resul t in a failure, but | 114 // cancelation is loss of network connectivity, which does resul t in a failure, but |
112 // it's a transient failure rather than something non-recoverabl e. | 115 // it's a transient failure rather than something non-recoverabl e. |
113 if (uploadResult == MinidumpUploadCallable.UPLOAD_FAILURE) { | 116 if (uploadResult == MinidumpUploadCallable.UPLOAD_FAILURE) { |
114 String newName = CrashFileManager.tryIncrementAttemptNumber( minidump); | 117 String newName = CrashFileManager.tryIncrementAttemptNumber( minidump); |
115 if (newName == null) { | 118 if (newName == null) { |
116 Log.w(TAG, "Failed to increment attempt number of " + mi nidump); | 119 Log.w(TAG, "Failed to increment attempt number of " + mi nidump); |
117 } | 120 } |
118 } | 121 } |
122 | |
123 // TODO(isherman): Log success/failure metrics for Chrome. | |
Ilya Sherman
2017/03/13 03:12:09
I'm actually not sure how to do this. The upload
gsennton
2017/03/13 17:57:17
Sounds reasonable (but I don't know much about UMA
Ilya Sherman
2017/03/14 02:18:55
Actually, now that I realize that it's okay to use
gsennton
2017/03/14 18:17:28
It's fine as long as we do it just from the browse
| |
119 } | 124 } |
120 | 125 |
121 // Clean out old/uploaded minidumps. Note that this clean-up method is more strict than | 126 // Clean out old/uploaded minidumps. Note that this clean-up method is more strict than |
122 // our copying mechanism in the sense that it keeps fewer minidumps. | 127 // our copying mechanism in the sense that it keeps fewer minidumps. |
123 mFileManager.cleanOutAllNonFreshMinidumpFiles(); | 128 mFileManager.cleanOutAllNonFreshMinidumpFiles(); |
124 | 129 |
125 // Reschedule if there are still minidumps to upload. | 130 // Reschedule if there are still minidumps to upload. |
126 boolean reschedule = | 131 boolean reschedule = |
127 mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES_ALLOWED).l ength > 0; | 132 mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES_ALLOWED).l ength > 0; |
128 mUploadsFinishedCallback.uploadsFinished(reschedule); | 133 mUploadsFinishedCallback.uploadsFinished(reschedule); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 | 172 |
168 // Reschedule if there are still minidumps to upload. | 173 // Reschedule if there are still minidumps to upload. |
169 return mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES_ALLOWED).length > 0; | 174 return mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES_ALLOWED).length > 0; |
170 } | 175 } |
171 | 176 |
172 @VisibleForTesting | 177 @VisibleForTesting |
173 public void joinWorkerThreadForTesting() throws InterruptedException { | 178 public void joinWorkerThreadForTesting() throws InterruptedException { |
174 mWorkerThread.join(); | 179 mWorkerThread.join(); |
175 } | 180 } |
176 } | 181 } |
OLD | NEW |