赞
踩
dumpsys采用了binder机制调用了服务里的dump方法,
Binder.java 里有dump方法,
这里我们来研究下dump的调用
使用binder进行通信
vi ./frameworks/native/cmds/dumpsys/dumpsys.cpp
#define LOG_TAG "dumpsys"
#include <utils/Log.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/TextOutput.h>
#include <utils/Vector.h>
#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
using namespace android;
static int sort_func(const String16* lhs, const String16* rhs)
{
return lhs->compare(*rhs);
}
int main(int argc, char* const argv[])
{
signal(SIGPIPE, SIG_IGN);
sp<IServiceManager> sm = defaultServiceManager();
fflush(stdout);
if (sm == NULL) {
ALOGE("Unable to get default service manager!");
aerr << "dumpsys: Unable to get default service manager!" << endl;
return 20;
}
Vector<String16> services;
Vector<String16> args;
bool showListOnly = false;
if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
showListOnly = true;
}
if ((argc == 1) || showListOnly) {
services = sm->listServices();
services.sort(sort_func);
args.add(String16("-a"));
} else {
services.add(String16(argv[1]));
for (int i=2; i<argc; i++) {
args.add(String16(argv[i]));
}
}
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<N; i++) {
sp<IBinder> service = sm->checkService(services[i]);
if (service != NULL) {
aout << " " << services[i] << endl;
}
}
}
if (showListOnly) {
return 0;
}
for (size_t i=0; i<N; i++) {
sp<IBinder> service = sm->checkService(services[i]);
if (service != NULL) {
if (N > 1) {
aout << "------------------------------------------------------------"
"-------------------" << endl;
aout << "DUMP OF SERVICE " << services[i] << ":" << endl;
}
//10-10, 这里能够这样写是因为class sp {里对->进行了重载
// inline T* operator-> () const { return m_ptr; }
int err = service->dump(STDOUT_FILENO, args);
if (err != 0) {
aerr << "Error dumping service info: (" << strerror(err)
<< ") " << services[i] << endl;
}
} else {
aerr << "Can't find service: " << services[i] << endl;
}
}
return 0;
}
发起调用
android/frameworks/native/libs/binder
vi BpBinder.cpp
status_t BpBinder::dump(int fd, const Vector<String16>& args)
{
Parcel send;
Parcel reply;
send.writeFileDescriptor(fd);
const size_t numArgs = args.size();
send.writeInt32(numArgs);
for (size_t i = 0; i < numArgs; i++) {
send.writeString16(args[i]);
}
status_t err = transact(DUMP_TRANSACTION, send, &reply);
return err;
}
PMS里的dump的调用堆栈
10-08 10:42:19.099: D/PackageManagerService(1103): ===== begin =====
10-08 10:42:19.099: D/PackageManagerService(1103): com.android.server.pm.PackageManagerService.dump(PackageManagerService.java:16865)
10-08 10:42:19.099: D/PackageManagerService(1103): android.os.Binder.dump(Binder.java:331)
10-08 10:42:19.099: D/PackageManagerService(1103): android.os.Binder.onTransact(Binder.java:297)
10-08 10:42:19.099: D/PackageManagerService(1103): android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2161)
10-08 10:42:19.099: D/PackageManagerService(1103): com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3146)
10-08 10:42:19.099: D/PackageManagerService(1103): android.os.Binder.execTransact(Binder.java:458)
注意
public class PackageManagerService extends IPackageManager.Stub {
PackageManagerService里有
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
try {
return super.onTransact(code, data, reply, flags);
} catch (RuntimeException e) {
if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
Slog.wtf(TAG, "Package Manager Crash", e);
}
throw e;
}
}
super即binder.java
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
if (code == INTERFACE_TRANSACTION) {
reply.writeString(getInterfaceDescriptor());
return true;
} else if (code == DUMP_TRANSACTION) {
ParcelFileDescriptor fd = data.readFileDescriptor();
String[] args = data.readStringArray();
if (fd != null) {
try {
dump(fd.getFileDescriptor(), args);
} finally {
IoUtils.closeQuietly(fd);
}
Android 7上
调用 dumpsys battery的堆栈
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。