Android dropbox介绍
Posted Kevin张俊杰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android dropbox介绍相关的知识,希望对你有一定的参考价值。
简介
系统服务dropbox
以文件形式记录了系统各种异常信息,例如app crash
、native crash
、anr
、kernel panic
等等。
ADB查询
adb shell dumpsys dropbox
app接口
源码10.0
1、DropBoxManager dropbox = (DropBoxManager) getSystemService(Context.DROPBOX_SERVICE)
例如,dropbox.addText
可实现把需要记录的数据丢给dropbox进行存储
2、监听广播android.intent.action.DROPBOX_ENTRY_ADDED
,可知系统发生了异常
注意权限:android.permission.READ_LOGS --- 平台签名或priv-app
dropbox启动
-
SystemServer:run
SystemServer
启动服务private void startOtherServices() ··· mSystemServiceManager.startService(DropBoxManagerService.class); ···
-
DropBoxManagerService
继承SystemService
,启动顺序:构造方法 -->onStart
a) 构造方法
public DropBoxManagerService(final Context context, File path) super(context); mDropBoxDir = path;//dropbox路径/data/system/dropbox mContentResolver = getContext().getContentResolver(); mHandler = new Handler() @Override public void handleMessage(Message msg) if (msg.what == MSG_SEND_BROADCAST) getContext().sendBroadcastAsUser((Intent)msg.obj, UserHandle.SYSTEM, android.Manifest.permission.READ_LOGS); ;
b) onStart启动
public void onStart() // 监听低内存,保证dropbox不占用更多空间 IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW); getContext().registerReceiver(mReceiver, filter); mContentResolver.registerContentObserver( Settings.Global.CONTENT_URI, true, new ContentObserver(new Handler()) @Override public void onChange(boolean selfChange) mReceiver.onReceive(getContext(), (Intent) null); ); //注册dropbox服务 publishBinderService(Context.DROPBOX_SERVICE, mStub);
-
接口运用,发送广播
DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED
dropbox.add
public void add(DropBoxManager.Entry entry) ··· try ··· final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED); dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag); dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time); if (!mBooted) dropboxIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); ··· mHandler.sendMessage(mHandler.obtainMessage(MSG_SEND_BROADCAST, dropboxIntent)); catch (IOException e) Slog.e(TAG, "Can't write: " + tag, e); finally IoUtils.closeQuietly(output); IoUtils.closeQuietly(input); entry.close(); if (temp != null) temp.delete();
dropbox日志路径
/data/system/dropbox
adb shell ls -al /data/system/dropbox
total 432
drwx------ 2 system system 4096 2021-12-23 06:02 .
drwxrwxr-x 16 system system 4096 2021-12-23 06:01 ..
-rw------- 1 system system 335 2022-01-25 14:40 SYSTEM_BOOT@1640210494810.txt
-rw------- 1 system system 334 2022-01-25 15:05 SYSTEM_BOOT@1640210494823.txt
-rw------- 1 system system 334 2021-12-23 06:01 SYSTEM_BOOT@1640210496077.txt
-rw------- 1 system system 19264 2022-01-25 14:40 SYSTEM_RECOVERY_KMSG@1640210494811.txt.gz
-rw------- 1 system system 19191 2022-01-25 15:05 SYSTEM_RECOVERY_KMSG@1640210494824.txt.gz
-rw------- 1 system system 5661 2022-01-25 14:40 SYSTEM_RECOVERY_LOG@1640210494809.txt.gz
-rw------- 1 system system 5076 2022-01-25 15:05 SYSTEM_RECOVERY_LOG@1640210494822.txt.gz
-rw------- 1 system system 30 2022-01-25 14:40 storage_trim@1640210494803.txt
-rw------- 1 system system 4192 2022-01-25 14:40 system_app_strictmode@1640210494804.txt.gz
记录的系统错误
系统正常启动后的自检工作
-
SYSTEM_BOOT
开机一次,记录一次 -
SYSTEM_RESTART
如果system_server在设备运行过程中异常,则会有记录 -
SYSTEM_LAST_KMSG
kernel异常。
pstore是persistent storage的缩写,内核发生异常通过此把异常日志记录下来,方便定位问题。
ramoops指的是采用ram保存oops信息(kernel 异常信息)的一个功能,利用pstore技术实现。kernel异常信息保存地: panic /proc/last_kmsg oops /sys/fs/pstore/console-ramoops /sys/fs/pstore/console-ramoops-0
-
SYSTEM_TOMBSTONE
TOMBSTONE是Android用来记录native进程崩溃的core dump日志, 系统服务在启动完成后会增加一个Observer来侦测tombstone日志文件的变化, 每当生成新的tombstone文件, 就会增加一条 SYSTEM_TOMBSTONE记录到DropBoxManager中。 -
SYSTEM_RECOVERY_LOG/SYSTEM_RECOVERY_KMSG
SYSTEM_RECOVERY_KMSG:recovery kerenl日志 SYSTEM_RECOVERY_LOG:recovery 升级或恢复出厂设置等等日志
-
SYSTEM_FSCK
文件系统完整性校验日志 -
SYSTEM_AUDIT
kernel 异常信息的查漏补缺日志
BootReceiver.javaprivate void logBootEvents(Context ctx) throws IOException final DropBoxManager db = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE); final String headers = getBootHeadersToLogAndUpdate(); final String bootReason = SystemProperties.get("ro.boot.bootreason", null); String recovery = RecoverySystem.handleAftermath(ctx); if (recovery != null && db != null) db.addText("SYSTEM_RECOVERY_LOG", headers + recovery); String lastKmsgFooter = ""; if (bootReason != null) lastKmsgFooter = new StringBuilder(512) .append("\\n") .append("Boot info:\\n") .append("Last boot reason: ").append(bootReason).append("\\n") .toString(); HashMap<String, Long> timestamps = readTimestamps(); if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) if (StorageManager.inCryptKeeperBounce()) // Encrypted, first boot to get PIN/pattern/password so data is tmpfs // Don't set ro.runtime.firstboot so that we will do this again // when data is properly mounted else String now = Long.toString(System.currentTimeMillis()); SystemProperties.set("ro.runtime.firstboot", now); if (db != null) db.addText("SYSTEM_BOOT", headers); // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile()) // kernel panic日志,例如异常重启 addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter, "/proc/last_kmsg", -LOG_SIZE, "SYSTEM_LAST_KMSG"); addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter, "/sys/fs/pstore/console-ramoops", -LOG_SIZE, "SYSTEM_LAST_KMSG"); addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter, "/sys/fs/pstore/console-ramoops-0", -LOG_SIZE, "SYSTEM_LAST_KMSG"); //recovery日志。例如OTA升级或恢复出厂设置的时候 addFileToDropBox(db, timestamps, headers, "/cache/recovery/log", -LOG_SIZE, "SYSTEM_RECOVERY_LOG"); addFileToDropBox(db, timestamps, headers, "/cache/recovery/last_kmsg", -LOG_SIZE, "SYSTEM_RECOVERY_KMSG"); //kernel日志的查漏补缺备份 addAuditErrorsToDropBox(db, timestamps, headers, -LOG_SIZE, "SYSTEM_AUDIT"); else if (db != null) db.addText("SYSTEM_RESTART", headers); // log always available fs_stat last so that logcat collecting tools can wait until // fs_stat to get all file system metrics. logFsShutdownTime(); logFsMountTime(); //fsck文件系统校验日志收集 //fsck(file system consistency check)是Unix和类Unix系统上用于检查文件系统完整性的工具 addFsckErrorsToDropBoxAndLogFsStat(db, timestamps, headers, -LOG_SIZE, "SYSTEM_FSCK"); logSystemServerShutdownTimeMetrics(); // Scan existing tombstones (in case any new ones appeared) //native进程崩溃日志收集 File[] tombstoneFiles = TOMBSTONE_DIR.listFiles(); for (int i = 0; tombstoneFiles != null && i < tombstoneFiles.length; i++) if (tombstoneFiles[i].isFile()) addFileToDropBox(db, timestamps, headers, tombstoneFiles[i].getPath(), LOG_SIZE, "SYSTEM_TOMBSTONE"); writeTimestamps(timestamps); // Start watching for new tombstone files; will record them as they occur. // This gets registered with the singleton file observer thread. // /data/tombstones目录监听收集 sTombstoneObserver = new FileObserver(TOMBSTONE_DIR.getPath(), FileObserver.CREATE) @Override public void onEvent(int event, String path) HashMap<String, Long> timestamps = readTimestamps(); try File file = new File(TOMBSTONE_DIR, path); if (file.isFile() && file.getName().startsWith("tombstone_")) addFileToDropBox(db, timestamps, headers, file.getPath(), LOG_SIZE, TAG_TOMBSTONE); catch (IOException e) Slog.e(TAG, "Can't log tombstone", e); writeTimestamps(timestamps); ; sTombstoneObserver.startWatching();
java/native crash--- crash/native_crash
java/native层异常的区分在于eventType:crash/native_crash
ActivityManagerService
void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
ApplicationErrorReport.CrashInfo crashInfo)
//event事件的日志记录:EventLogTags.AM_CRASH --> am_crash
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
crashInfo.throwFileName,
crashInfo.throwLineNumber);
···
//加入到dropbox
addErrorToDropBox(
eventType, r, processName, null, null, null, null, null, null, crashInfo);
//其他业务处理
mAppErrors.crashApplication(r, crashInfo);
java层:handleApplicationCrashInner("crash", r, processName, crashInfo);
native层: mAm.handleApplicationCrashInner("native_crash", mApp, mApp.processName, ci);
anr 异常— anr
这里涉及广播、Service、Provider等组件的anr以及触摸按键事件的anr
ProcessRecord
void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo,
String parentShortComponentName, WindowProcessController parentProcess,
boolean aboveSystem, String annotation)
···
//event事件的日志记录:EventLogTags.AM_ANR --> am_anr
EventLog.writeEvent(EventLogTags.AM_ANR, userId, pid, processName, info.flags,
annotation);
···
//加入到dropbox
mService.addErrorToDropBox("anr", this, processName, activityShortComponentName,
parentShortComponentName, parentPr, annotation, cpuInfo, tracesFile, null);
···
wtf(What a Terrible Failure)— wtf
android.util.Log.wtf(String, String),应用可调用布局异常点
ActivityManagerService
ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
final ApplicationErrorReport.CrashInfo crashInfo)
final ProcessRecord r = findAppProcess(app, "WTF");
final String processName = app == null ? "system_server"
: (r == null ? "unknown" : r.processName);
//event事件的日志记录:EventLogTags.AM_WTF --> am_wtf
EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
···
//加入到dropbox
addErrorToDropBox("wtf", r, processName, null, null, null, tag, null, null, crashInfo);
return r;
注意:
当系统设置Settings.Global.WTF_IS_FATAL为1时,发送wtf可kill应用
strict mode—**_strictmode
严格模式,主要为性能监测使用
StrictMode (严格模式), 顾名思义, 就是在比正常模式检测得更严格, 通常用来监测不应当在主线程执行的网络, 文件等操作。任何 StrictMode 违例都会被 ActivityManagerService 在 DropBoxManager 中记录为一次 strict_mode 违例。
ActivityManagerService
public void handleApplicationStrictModeViolation(
IBinder app,
int penaltyMask,
StrictMode.ViolationInfo info)
···
//需要满足触发dropbox的条件
if ((penaltyMask & StrictMode.PENALTY_DROPBOX) != 0)
Integer stackFingerprint = info.hashCode();
boolean logIt = true;
···
if (logIt) //执行dropbox业务
logStrictModeViolationToDropBox(r, info);
···
private void logStrictModeViolationToDropBox(
ProcessRecord process,
StrictMode.ViolationInfo info)
if (info == null)
return;
//收集信息,tag:***_strictmode
···省略···
//加入到dropbox
IoThread.getHandler().post(() ->
dbox.addText(dropboxTag, res);
);
lowmem—低内存报告
ActivityManagerService
final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc)
// If there are no longer any background processes running,
// and the app that died was not running instrumentation,
// then tell everyone we are now low on memory.
if (!mProcessList.haveBackgroundProcessLocked())
···
//event事件的日志记录:EventLogTags.AM_LOW_MEMORY --> am_low_memory
EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mProcessList.getLruSizeLocked());
···
if (doReport) //如果报告,最后调入reportMemUsage
Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
mHandler.sendMessage(msg);
···
void reportMemUsage(ArrayList<ProcessMemInfo> memInfos)
···
addErrorToDropBox("lowmem", null, "system_server", null,
null, null, tag.toString(), dropBuilder.toString(), null, null);
···
watchdog
如果 WatchDog 监测到系统进程(system_server)出现问题, 会增加一条 watchdog 记录到 DropBoxManager 中, 并终止系统进程的执行。
WatchDog
public void run()
···
while (true)
···
//event事件的日志记录:EventLogTags.WATCHDOG --> watchdog
EventLog.writeEvent(EventLogTags.WATCHDOG, name.isEmpty() ? subject : name);<以上是关于Android dropbox介绍的主要内容,如果未能解决你的问题,请参考以下文章
appium 已解决Android,每次启动手机中都会安装Appium settings和Unclock的方法
302 使用 Dropbox 短超链接在 Android 中从 http 重定向到 https
在 android app 中访问 Dropbox、google drive、microsoft onedrive 等中的云共享文件