Merge "Fix potential overflow with casting long to int in AppExitInfoTracker" into sc-dev am: 6d3b5033d7
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14848023 Change-Id: I7570fafceb04fb9e6bea9eeae68c6e230d4e44b0
This commit is contained in:
@@ -24,6 +24,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
|
||||
import android.annotation.CurrentTimeMillisLong;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ApplicationExitInfo;
|
||||
import android.app.ApplicationExitInfo.Reason;
|
||||
@@ -287,8 +288,8 @@ public final class AppExitInfoTracker {
|
||||
if (!mAppExitInfoLoaded.get()) {
|
||||
return;
|
||||
}
|
||||
mKillHandler.obtainMessage(KillHandler.MSG_PROC_DIED, obtainRawRecord(app))
|
||||
.sendToTarget();
|
||||
mKillHandler.obtainMessage(KillHandler.MSG_PROC_DIED,
|
||||
obtainRawRecord(app, System.currentTimeMillis())).sendToTarget();
|
||||
}
|
||||
|
||||
void scheduleNoteAppKill(final ProcessRecord app, final @Reason int reason,
|
||||
@@ -300,7 +301,7 @@ public final class AppExitInfoTracker {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationExitInfo raw = obtainRawRecord(app);
|
||||
ApplicationExitInfo raw = obtainRawRecord(app, System.currentTimeMillis());
|
||||
raw.setReason(reason);
|
||||
raw.setSubReason(subReason);
|
||||
raw.setDescription(msg);
|
||||
@@ -542,7 +543,8 @@ public final class AppExitInfoTracker {
|
||||
return AppExitInfoTracker.FOREACH_ACTION_NONE;
|
||||
});
|
||||
|
||||
Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
|
||||
Collections.sort(list,
|
||||
(a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
|
||||
int size = list.size();
|
||||
if (maxNum > 0) {
|
||||
size = Math.min(size, maxNum);
|
||||
@@ -976,7 +978,7 @@ public final class AppExitInfoTracker {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ApplicationExitInfo obtainRawRecord(ProcessRecord app) {
|
||||
ApplicationExitInfo obtainRawRecord(ProcessRecord app, @CurrentTimeMillisLong long timestamp) {
|
||||
ApplicationExitInfo info = mRawRecordsPool.acquire();
|
||||
if (info == null) {
|
||||
info = new ApplicationExitInfo();
|
||||
@@ -998,7 +1000,7 @@ public final class AppExitInfoTracker {
|
||||
info.setImportance(procStateToImportance(app.mState.getSetProcState()));
|
||||
info.setPss(app.mProfile.getLastPss());
|
||||
info.setRss(app.mProfile.getLastRss());
|
||||
info.setTimestamp(System.currentTimeMillis());
|
||||
info.setTimestamp(timestamp);
|
||||
}
|
||||
|
||||
return info;
|
||||
@@ -1298,7 +1300,7 @@ public final class AppExitInfoTracker {
|
||||
results.add(mInfos.valueAt(i));
|
||||
}
|
||||
Collections.sort(results,
|
||||
(a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
|
||||
(a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
|
||||
} else {
|
||||
if (maxNum == 1) {
|
||||
// Most of the caller might be only interested with the most recent one
|
||||
@@ -1318,7 +1320,7 @@ public final class AppExitInfoTracker {
|
||||
list.add(mInfos.valueAt(i));
|
||||
}
|
||||
Collections.sort(list,
|
||||
(a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
|
||||
(a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
|
||||
for (int i = 0; i < maxNum; i++) {
|
||||
results.add(list.get(i));
|
||||
}
|
||||
@@ -1412,7 +1414,7 @@ public final class AppExitInfoTracker {
|
||||
for (int i = mInfos.size() - 1; i >= 0; i--) {
|
||||
list.add(mInfos.valueAt(i));
|
||||
}
|
||||
Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
|
||||
Collections.sort(list, (a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
|
||||
int size = list.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.get(i).dump(pw, prefix + " ", "#" + i, sdf);
|
||||
@@ -1629,7 +1631,8 @@ public final class AppExitInfoTracker {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFresh(long timestamp) {
|
||||
@VisibleForTesting
|
||||
boolean isFresh(long timestamp) {
|
||||
// A process could be dying but being stuck in some state, i.e.,
|
||||
// being TRACED by tombstoned, thus the zygote receives SIGCHILD
|
||||
// way after we already knew the kill (maybe because we did the kill :P),
|
||||
|
||||
@@ -36,10 +36,12 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.annotation.CurrentTimeMillisLong;
|
||||
import android.app.ApplicationExitInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -163,14 +165,15 @@ public class ApplicationExitInfoTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateExitInfo(ProcessRecord app) {
|
||||
ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app);
|
||||
private void updateExitInfo(ProcessRecord app, @CurrentTimeMillisLong long timestamp) {
|
||||
ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app, timestamp);
|
||||
mAppExitInfoTracker.handleNoteProcessDiedLocked(raw);
|
||||
mAppExitInfoTracker.recycleRawRecord(raw);
|
||||
}
|
||||
|
||||
private void noteAppKill(ProcessRecord app, int reason, int subReason, String msg) {
|
||||
ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app);
|
||||
private void noteAppKill(ProcessRecord app, int reason, int subReason, String msg,
|
||||
@CurrentTimeMillisLong long timestamp) {
|
||||
ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app, timestamp);
|
||||
raw.setReason(reason);
|
||||
raw.setSubReason(subReason);
|
||||
raw.setDescription(msg);
|
||||
@@ -190,6 +193,7 @@ public class ApplicationExitInfoTest {
|
||||
|
||||
// Test application calls System.exit()
|
||||
doNothing().when(mAppExitInfoTracker).schedulePersistProcessExitInfo(anyBoolean());
|
||||
doReturn(true).when(mAppExitInfoTracker).isFresh(anyLong());
|
||||
|
||||
final int app1Uid = 10123;
|
||||
final int app1Pid1 = 12345;
|
||||
@@ -216,7 +220,7 @@ public class ApplicationExitInfoTest {
|
||||
final byte[] app1Cookie2 = {(byte) 0x08, (byte) 0x07, (byte) 0x06, (byte) 0x05,
|
||||
(byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01};
|
||||
|
||||
final long now1 = System.currentTimeMillis();
|
||||
final long now1 = 1;
|
||||
ProcessRecord app = makeProcessRecord(
|
||||
app1Pid1, // pid
|
||||
app1Uid, // uid
|
||||
@@ -240,7 +244,7 @@ public class ApplicationExitInfoTest {
|
||||
doReturn(null)
|
||||
.when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
|
||||
.remove(anyInt(), anyInt());
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now1);
|
||||
|
||||
ArrayList<ApplicationExitInfo> list = new ArrayList<ApplicationExitInfo>();
|
||||
mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, app1Pid1, 0, list);
|
||||
@@ -290,11 +294,11 @@ public class ApplicationExitInfoTest {
|
||||
.when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
|
||||
.remove(anyInt(), anyInt());
|
||||
noteAppKill(app, ApplicationExitInfo.REASON_USER_REQUESTED,
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, null);
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, null, now1s);
|
||||
|
||||
// Case 2: create another app1 process record with a different pid
|
||||
sleep(1);
|
||||
final long now2 = System.currentTimeMillis();
|
||||
final long now2 = 2;
|
||||
app = makeProcessRecord(
|
||||
app1Pid2, // pid
|
||||
app1Uid, // uid
|
||||
@@ -316,16 +320,15 @@ public class ApplicationExitInfoTest {
|
||||
doReturn(new Pair<Long, Object>(now2, Integer.valueOf(makeExitStatus(exitCode))))
|
||||
.when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
|
||||
.remove(anyInt(), anyInt());
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now2);
|
||||
list.clear();
|
||||
|
||||
// Get all the records for app1Uid
|
||||
mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
|
||||
assertEquals(3, list.size());
|
||||
|
||||
info = list.get(0);
|
||||
info = list.get(1);
|
||||
|
||||
// Verify the most recent one
|
||||
verifyApplicationExitInfo(
|
||||
info, // info
|
||||
now2, // timestamp
|
||||
@@ -346,7 +349,7 @@ public class ApplicationExitInfoTest {
|
||||
assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie2,
|
||||
app1Cookie2.length));
|
||||
|
||||
info = list.get(1);
|
||||
info = list.get(0);
|
||||
verifyApplicationExitInfo(
|
||||
info, // info
|
||||
now1s, // timestamp
|
||||
@@ -386,7 +389,7 @@ public class ApplicationExitInfoTest {
|
||||
doReturn(new Pair<Long, Object>(now3, Integer.valueOf(makeSignalStatus(sigNum))))
|
||||
.when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
|
||||
.remove(anyInt(), anyInt());
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now3);
|
||||
list.clear();
|
||||
mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1PidUser2, 0, list);
|
||||
|
||||
@@ -463,7 +466,7 @@ public class ApplicationExitInfoTest {
|
||||
app2Rss1, // rss
|
||||
app2ProcessName, // processName
|
||||
app2PackageName); // packageName
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now4);
|
||||
list.clear();
|
||||
mAppExitInfoTracker.getExitInfo(app2PackageName, app2UidUser2, app2PidUser2, 0, list);
|
||||
assertEquals(1, list.size());
|
||||
@@ -523,9 +526,9 @@ public class ApplicationExitInfoTest {
|
||||
app3ProcessName, // processName
|
||||
app3PackageName); // packageName
|
||||
noteAppKill(app, ApplicationExitInfo.REASON_CRASH_NATIVE,
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description);
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description, now5);
|
||||
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now5);
|
||||
list.clear();
|
||||
mAppExitInfoTracker.getExitInfo(app3PackageName, app3UidUser2, app3PidUser2, 0, list);
|
||||
assertEquals(1, list.size());
|
||||
@@ -648,11 +651,11 @@ public class ApplicationExitInfoTest {
|
||||
app3PackageName); // packageName
|
||||
mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app3IsolatedUid, app3Uid);
|
||||
noteAppKill(app, ApplicationExitInfo.REASON_CRASH,
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description2);
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description2, now6);
|
||||
|
||||
assertEquals(app3Uid, mAppExitInfoTracker.mIsolatedUidRecords
|
||||
.getUidByIsolatedUid(app3IsolatedUid).longValue());
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now6);
|
||||
assertNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(app3IsolatedUid));
|
||||
|
||||
list.clear();
|
||||
@@ -736,9 +739,9 @@ public class ApplicationExitInfoTest {
|
||||
|
||||
mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUidUser2, app1UidUser2);
|
||||
noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, app1Description);
|
||||
ApplicationExitInfo.SUBREASON_UNKNOWN, app1Description, now8);
|
||||
|
||||
updateExitInfo(app);
|
||||
updateExitInfo(app, now8);
|
||||
list.clear();
|
||||
mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1PidUser2, 1, list);
|
||||
assertEquals(1, list.size());
|
||||
@@ -802,8 +805,8 @@ public class ApplicationExitInfoTest {
|
||||
traceFile, traceStart, traceEnd);
|
||||
|
||||
noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
|
||||
ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, app1Description2);
|
||||
updateExitInfo(app);
|
||||
ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, app1Description2, now9);
|
||||
updateExitInfo(app, now9);
|
||||
list.clear();
|
||||
mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1Pid2User2, 1, list);
|
||||
assertEquals(1, list.size());
|
||||
@@ -859,7 +862,7 @@ public class ApplicationExitInfoTest {
|
||||
mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
|
||||
assertEquals(3, list.size());
|
||||
|
||||
info = list.get(0);
|
||||
info = list.get(1);
|
||||
|
||||
exitCode = 6;
|
||||
verifyApplicationExitInfo(
|
||||
@@ -879,7 +882,7 @@ public class ApplicationExitInfoTest {
|
||||
IMPORTANCE_SERVICE, // importance
|
||||
null); // description
|
||||
|
||||
info = list.get(1);
|
||||
info = list.get(0);
|
||||
verifyApplicationExitInfo(
|
||||
info, // info
|
||||
now1s, // timestamp
|
||||
|
||||
Reference in New Issue
Block a user