Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12c4b01f authored by Devin Moore's avatar Devin Moore Committed by Automerger Merge Worker
Browse files

Merge changes I0daebc18,I87df46d1 am: b438f33e am: 42a68613 am: e7ddbe0b

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1788708

Change-Id: I544472d56b08565cb039cf1330240d8a13578313
parents c7027c37 e7ddbe0b
Loading
Loading
Loading
Loading
+67 −30
Original line number Diff line number Diff line
@@ -21,7 +21,9 @@

#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <binder/BpBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/Stability.h>
@@ -58,17 +60,20 @@ static int sort_func(const String16* lhs, const String16* rhs)
}

static void usage() {
    fprintf(stderr,
    fprintf(
        stderr,
        "usage: dumpsys\n"
        "         To dump all services.\n"
        "or:\n"
            "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--dump] [--pid] [--thread] [--help | "
        "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--clients] [--dump] [--pid] [--thread] "
        "[--help | "
        "-l | --skip SERVICES "
        "| SERVICE [ARGS]]\n"
        "         --help: shows this help\n"
        "         -l: only list services, do not dump them\n"
        "         -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n"
        "         -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n"
        "         --clients: dump client PIDs instead of usual dump\n"
        "         --dump: ask the service to dump itself (this is the default)\n"
        "         --pid: dump PID instead of usual dump\n"
        "         --proto: filter services that support dumping data in proto format. Dumps\n"
@@ -131,15 +136,12 @@ int Dumpsys::main(int argc, char* const argv[]) {
    int dumpTypeFlags = 0;
    int timeoutArgMs = 10000;
    int priorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL;
    static struct option longOptions[] = {{"help", no_argument, 0, 0},
                                          {"dump", no_argument, 0, 0},
                                          {"pid", no_argument, 0, 0},
                                          {"priority", required_argument, 0, 0},
                                          {"proto", no_argument, 0, 0},
                                          {"skip", no_argument, 0, 0},
                                          {"stability", no_argument, 0, 0},
                                          {"thread", no_argument, 0, 0},
                                          {0, 0, 0, 0}};
    static struct option longOptions[] = {
        {"help", no_argument, 0, 0},           {"clients", no_argument, 0, 0},
        {"dump", no_argument, 0, 0},           {"pid", no_argument, 0, 0},
        {"priority", required_argument, 0, 0}, {"proto", no_argument, 0, 0},
        {"skip", no_argument, 0, 0},           {"stability", no_argument, 0, 0},
        {"thread", 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).
@@ -178,6 +180,8 @@ int Dumpsys::main(int argc, char* const argv[]) {
                dumpTypeFlags |= TYPE_STABILITY;
            } else if (!strcmp(longOptions[optionIndex].name, "thread")) {
                dumpTypeFlags |= TYPE_THREAD;
            } else if (!strcmp(longOptions[optionIndex].name, "clients")) {
                dumpTypeFlags |= TYPE_CLIENTS;
            }
            break;

@@ -373,6 +377,35 @@ static status_t dumpThreadsToFd(const sp<IBinder>& service, const unique_fd& fd)
    return OK;
}

static status_t dumpClientsToFd(const sp<IBinder>& service, const unique_fd& fd) {
    std::string clientPids;
    const auto remoteBinder = service->remoteBinder();
    if (remoteBinder == nullptr) {
        WriteStringToFd("Client PIDs are not available for local binders.\n", fd.get());
        return OK;
    }
    const auto handle = remoteBinder->getDebugBinderHandle();
    if (handle == std::nullopt) {
        return OK;
    }
    std::vector<pid_t> pids;
    pid_t myPid = getpid();
    pid_t servicePid;
    status_t status = service->getDebugPid(&servicePid);
    if (status != OK) {
        return status;
    }
    status =
        getBinderClientPids(BinderDebugContext::BINDER, myPid, servicePid, handle.value(), &pids);
    if (status != OK) {
        return status;
    }
    pids.erase(std::remove_if(pids.begin(), pids.end(), [&](pid_t pid) { return pid == myPid; }),
               pids.end());
    WriteStringToFd("Client PIDs: " + ::android::base::Join(pids, ", ") + "\n", fd.get());
    return OK;
}

static void reportDumpError(const String16& serviceName, status_t error, const char* context) {
    if (error == OK) return;

@@ -413,6 +446,10 @@ status_t Dumpsys::startDumpThread(int dumpTypeFlags, const String16& serviceName
            status_t err = dumpThreadsToFd(service, remote_end);
            reportDumpError(serviceName, err, "dumping thread info");
        }
        if (dumpTypeFlags & TYPE_CLIENTS) {
            status_t err = dumpClientsToFd(service, remote_end);
            reportDumpError(serviceName, err, "dumping clients info");
        }

        // other types always act as a header, this is usually longer
        if (dumpTypeFlags & TYPE_DUMP) {
+5 −4
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ class Dumpsys {
        TYPE_PID = 0x2,        // dump pid of server only
        TYPE_STABILITY = 0x4,  // dump stability information of server
        TYPE_THREAD = 0x8,     // dump thread usage of server only
        TYPE_CLIENTS = 0x10,   // dump pid of clients
    };

    /**
+23 −0
Original line number Diff line number Diff line
@@ -627,6 +627,29 @@ TEST_F(DumpsysTest, ListServiceWithThread) {
    AssertOutputFormat(format);
}

// Tests 'dumpsys --clients'
TEST_F(DumpsysTest, ListAllServicesWithClients) {
    ExpectListServices({"Locksmith", "Valet"});
    ExpectCheckService("Locksmith");
    ExpectCheckService("Valet");

    CallMain({"--clients"});

    AssertRunningServices({"Locksmith", "Valet"});

    const std::string format("(.|\n)*((Client PIDs are not available for local binders.)(.|\n)*){2}");
    AssertOutputFormat(format);
}

// Tests 'dumpsys --clients service_name'
TEST_F(DumpsysTest, ListServiceWithClients) {
    ExpectCheckService("Locksmith");

    CallMain({"--clients", "Locksmith"});

    const std::string format("Client PIDs are not available for local binders.\n");
    AssertOutputFormat(format);
}
// Tests 'dumpsys --thread --stability'
TEST_F(DumpsysTest, ListAllServicesWithMultipleOptions) {
    ExpectListServices({"Locksmith", "Valet"});
+8 −0
Original line number Diff line number Diff line
@@ -188,6 +188,14 @@ int32_t BpBinder::binderHandle() const {
    return std::get<BinderHandle>(mHandle).handle;
}

std::optional<int32_t> BpBinder::getDebugBinderHandle() const {
    if (!isRpcBinder()) {
        return binderHandle();
    } else {
        return std::nullopt;
    }
}

bool BpBinder::isDescriptorCached() const {
    Mutex::Autolock _l(mLock);
    return mDescriptorCache.size() ? true : false;
+2 −0
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ public:
    static void         setLimitCallback(binder_proxy_limit_callback cb);
    static void         setBinderProxyCountWatermarks(int high, int low);

    std::optional<int32_t> getDebugBinderHandle() const;

    class ObjectManager {
    public:
        ObjectManager();
Loading