1-dumpsys 使用
命令格式:
adb shell dumpsys activity [options] [WHAT]
option 参数:
options | 含义 |
---|---|
-a | 包括所有可用 Servier 状态 |
-c | 包括 Client 状态,即 App 端情况 |
-p PACKAGE | 限定输出指定包名 |
WHAT 参数:
WHAT | 解释 | 对应源码 |
---|---|---|
a[ctivities] | activity状态 | dumpActivitiesLocked() |
b[roadcasts] [PACKAGE_NAME] | broadcast状态 | dumpBroadcastsLocked() |
s[ervices] [COMP_SPEC …] | service状态 | newServiceDumperLocked().dumpLocked |
prov[iders] [COMP_SPEC …] | content provider状态 | dumpProvidersLocked() |
p[rocesses] [PACKAGE_NAME] | 进程状态 | dumpProcessesLocked() |
o[om] | 内存管理 | dumpOomLocked() |
i[ntents] [PACKAGE_NAME] | pending intent状态 | dumpPendingIntentsLocked() |
r[ecents] | 最近activity | dumpRecentsLocked() |
perm[issions] | URI授权情况 | dumpPermissionsLocked() |
all | 所有activities信息 | dumpActivity() |
top | 顶部activity信息 | dumpActivity() |
package | package相关信息 | dump() |
重要的服务:
服务名 | 类名 | 功能 |
---|---|---|
activity | ActivityManagerService | AMS相关信息 |
package | PackageManagerService | PMS相关信息 |
window | WindowManagerService | WMS相关信息 |
input | InputManagerService | IMS相关信息 |
power | PowerManagerService | PMS相关信息 |
batterystats | BatterystatsService | 电池统计信息 |
battery | BatteryService | 电池信息 |
alarm | AlarmManagerService | 闹钟信息 |
dropbox | DropboxManagerService | 调试相关 |
procstats | ProcessStatsService | 进程统计 |
cpuinfo | CpuBinder | CPU |
meminfo | MemBinder | 内存 |
gfxinfo | GraphicsBinder | 图像 |
dbinfo | DbBinder | 数据库 |
其他重要服务:
服务名 | 功能 |
---|---|
SurfaceFlinger | 图像相关 |
appops | app使用情况 |
permission | 权限 |
processinfo | 进程服务 |
batteryproperties | 电池相关 |
audio | 查看声音信息 |
netstats | 查看网络统计信息 |
diskstats | 查看空间free状态 |
jobscheduler | 查看任务计划 |
wifi | wifi信息 |
diskstats | 磁盘情况 |
usagestats | 用户使用情况 |
devicestoragemonitor | 设备信息 |
指令:
adb shell dumpsys activity
adb shell dumpsys activity intents //主要输出 PendingIntentRecord
adb shell dumpsys activity broadcasts
adb shell dumpsys activity providers
adb shell dumpsys activity permissions
adb shell dumpsys activity services
adb shell dumpsys activity recents
adb shell dumpsys activity activities
adb shell dumpsys activity processes
adb shell dumpsys activity top
adb shell dumpsys activity oom //查看进程状态
adb shell dumpsys activity activities //输出任务栈
adb shell dumpsys meminfo //查询内存情况
adb shell dumpsys package
adb shell dumpsys window //查询WMS服务相关信息
adb shell dumpsys cpuinfo //查询CPU情况
adb shell dumpsys -l //可以dump的 service
adb shell service list //可以看到所有的service
//重要的指令
adb shell dumpsys activity top |grep mResumed=true -C 10
adb shell dumpsys activity s com.example.helloworld //查询某个App所有service状态
adb shell dumpsys activity a com.example.helloworld //查询某个App的所有Activity状态
adb shell dumpsys activity p com.example.helloworld //查询某个App的进程状态
举个例子:
adb shell dumpsys activity p com.example.helloworld
ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)
All known processes:
*APP* UID 10070 ProcessRecord{3ab962e 8727:com.example.helloworld/u0a70}
user #0 uid=10070 gids={50070, 20070, 9997}
requiredAbi=arm64-v8a instructionSet=null
dir=/data/app/com.example.helloworld-MVDRQ1v8KVafsDRbTEH_HA==/base.apk publicDir=/data/app/com.example.helloworld-MVDRQ1v8KVafsDRbTEH_HA==/base.apk data=/data/user/0/com.example.helloworld
packageList={com.example.helloworld}
compat={560dpi}
thread=android.app.IApplicationThread$Stub$Proxy@cb84feb
pid=8727 starting=false
lastActivityTime=-56s649ms lastPssTime=-38s529ms nextPssTime=+1m21s429ms
adjSeq=18860 lruSeq=0 lastPss=75MB lastSwapPss=0.00 lastCachedPss=31MB lastCachedSwapPss=0.00
cached=false empty=false
oom: max=1001 curRaw=0 setRaw=0 cur=0 set=0
curSchedGroup=2 setSchedGroup=2 systemNoUi=false trimMemoryLevel=0
curProcState=2 repProcState=2 pssProcState=2 setProcState=2 lastStateTime=-2h44m52s244ms
hasShownUi=true pendingUiClean=true hasAboveClient=false treatLikeActivity=false
reportedInteraction=true time=-56s650ms
hasClientActivities=false foregroundActivities=true (rep=true)
lastRequestedGc=-2h47m10s361ms lastLowMemory=-2h47m10s361ms reportLowMemory=false
Activities:
- ActivityRecord{a06206e u0 com.example.helloworld/.MainActivity t13}
Connected Providers:
- 922a9b5/com.android.providers.settings/.SettingsProvider->8727:com.example.helloworld/u0a70 s1/1 u0/0 +2h47m10s322ms
UID states:
UID u0a70: UidRecord{d6525cf u0a70 TOP procs:1 seq(0,0,0)}
UID validation:
UID u0a70: UidRecord{d95d148 u0a70 TOP procs:0 seq(0,0,0)}
Process LRU list (sorted by oom_adj, 35 total, non-act at 3, non-svc at 3):
Proc # 0: fore T/A/TOP trm: 0 8727:com.example.helloworld/u0a70 (top-activity)
PID mappings:
PID #8727: ProcessRecord{3ab962e 8727:com.example.helloworld/u0a70}
mPreviousProcessVisibleTime: +6h44m56s167ms
mConfigWillChange: false
mDeviceIdleWhitelist=[1000, 1001, 2000, 10008, 10013]
mDeviceIdleTempWhitelist=[]
mVrController=[VrState=0x0,VrRenderThreadTid=0]
对应的source code
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
boolean needSep = false;
boolean printedAnything = false;
int numPers = 0;
//在dumpsys 指令中,这个数据被dump 出来了
pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
if (dumpAll) {
final int NP = mProcessNames.getMap().size();
for (int ip=0; ip procs = mProcessNames.getMap().valueAt(ip);
final int NA = procs.size();
for (int ia=0; ia
2-dumpsys 源码介绍
frameworks/native/cmds/dumpsys/Android.bp
cc_defaults {
name: "dumpsys_defaults",
cflags: [
"-Wall",
"-Werror",
],
srcs: [
"dumpsys.cpp",
],
shared_libs: [
"libbase",
"libutils",
"liblog",
"libbinder",
],
clang: true,
}
//
// Static library used in testing and executable
//
cc_library_static {
name: "libdumpsys",
defaults: ["dumpsys_defaults"],
export_include_dirs: ["."],
}
//
// Executable
//
cc_binary {
name: "dumpsys",
defaults: ["dumpsys_defaults"],
srcs: [
"main.cpp",
],
}
subdirs = ["tests"]
main.cpp 可以看出main 就是defaultServiceManager, 根据参数获取对应的service
int main(int argc, char* const argv[]) {
signal(SIGPIPE, SIG_IGN);
sp sm = defaultServiceManager();
fflush(stdout);
if (sm == nullptr) {
ALOGE("Unable to get default service manager!");
aerr << "dumpsys: Unable to get default service manager!" << endl;
return 20;
}
Dumpsys dumpsys(sm.get());
return dumpsys.main(argc, argv);
}
frameworks/native/cmds/dumpsys/dumpsys.cpp
static int sort_func(const String16* lhs, const String16* rhs)
{
return lhs->compare(*rhs);
}
//使用说明
static void usage() {
fprintf(stderr,
"usage: dumpsys\n"
" To dump all services.\n"
"or:\n"
" dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
" --help: shows this help\n"
" -l: only list services, do not dump them\n"
" -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
" --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
" SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
}
static bool IsSkipped(const Vector& skipped, const String16& service) {
for (const auto& candidate : skipped) {
if (candidate == service) {
return true;
}
}
return false;
}
int Dumpsys::main(int argc, char* const argv[]) {
Vector services;
Vector args;
Vector skippedServices;
bool showListOnly = false;
bool skipServices = false;
int timeoutArg = 10;
static struct option longOptions[] = {
{"skip", no_argument, 0, 0 },
{"help", no_argument, 0, 0 },
{ 0, 0, 0, 0 }
};
// Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
// happens on test cases).
optind = 1;
while (1) {
int c;
int optionIndex = 0;
c = getopt_long(argc, argv, "+t:l", longOptions, &optionIndex);
if (c == -1) {
break;
}
switch (c) {
case 0:
if (!strcmp(longOptions[optionIndex].name, "skip")) {
skipServices = true; //携带的参数skip
} else if (!strcmp(longOptions[optionIndex].name, "help")) {
usage();
return 0;
}
break;
case 't':
{
char *endptr;
timeoutArg = strtol(optarg, &endptr, 10);
if (*endptr != '\0' || timeoutArg <= 0) {
fprintf(stderr, "Error: invalid timeout number: '%s'\n", optarg);
return -1;
}
}
break;
case 'l':
showListOnly = true;
break;
default:
fprintf(stderr, "\n");
usage();
return -1;
}
}
for (int i = optind; i < argc; i++) {
if (skipServices) {
skippedServices.add(String16(argv[i]));
} else {
if (i == optind) {
services.add(String16(argv[i])); //把service 添加services
} else {
args.add(String16(argv[i]));
}
}
}
if ((skipServices && skippedServices.empty()) ||
(showListOnly && (!services.empty() || !skippedServices.empty()))) {
usage();
return -1;
}
if (services.empty() || showListOnly) {
// gets all services
services = sm_->listServices();
services.sort(sort_func);
args.add(String16("-a"));
}
const size_t N = services.size();
if (N > 1) {
// first print a list of the current services
aout << "Currently running services:" << endl;
for (size_t i=0; i service = sm_->checkService(services[i]);
if (service != nullptr) {
bool skipped = IsSkipped(skippedServices, services[i]);
aout << " " << services[i] << (skipped ? " (skipped)" : "") << endl;
}
}
}
if (showListOnly) {
return 0;
}
for (size_t i = 0; i < N; i++) {
String16 service_name = std::move(services[i]);
if (IsSkipped(skippedServices, service_name)) continue;
sp service = sm_->checkService(service_name);
if (service != nullptr) {
int sfd[2];
if (pipe(sfd) != 0) {
aerr << "Failed to create pipe to dump service info for " << service_name
<< ": " << strerror(errno) << endl;
continue;
}
unique_fd local_end(sfd[0]);
unique_fd remote_end(sfd[1]);
sfd[0] = sfd[1] = -1;
if (N > 1) {
aout << "------------------------------------------------------------"
"-------------------" << endl;
aout << "DUMP OF SERVICE " << service_name << ":" << endl;
}
// dump blocks until completion, so spawn a thread..
std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable {
//对每个service dump , dump 信息全部都在里面
int err = service->dump(remote_end.get(), args);
// It'd be nice to be able to close the remote end of the socketpair before the dump
// call returns, to terminate our reads if the other end closes their copy of the
// file descriptor, but then hangs for some reason. There doesn't seem to be a good
// way to do this, though.
remote_end.reset();
if (err != 0) {
aerr << "Error dumping service info: (" << strerror(err) << ") " << service_name
<< endl;
}
});
........
}
return 0;
}
这个指令比较简单,就是getservice dump 信息,关键是要对service 比较熟悉
1-main.cpp中defaultServiceManager()函数用来获取ServiceManager对象,并传递到dumpsys.cpp中。
2-sm_->listServices(),获取系统中所有向ServiceManager中注册过的服务。
3-如果命令加入了--skip SERVICES.则加入到skippedServices中,过滤service_name,最后sm_->checkService(service_name)用来获取指定的service。
4-最后调用service->dump()。这是最核心的方法,主要是service去掉用各自的dump()方法来获取相关dump信息。
REF:
https://developer.android.com/studio/command-line/dumpsys
https://www.jianshu.com/p/436f3c592974