diff options
| author | 2017-02-01 15:54:01 -0800 | |
|---|---|---|
| committer | 2017-02-01 16:10:16 -0800 | |
| commit | f4bee849129bd1b1e557c4e3cb1a4e5ef501d71d (patch) | |
| tree | f3bde5fac1de0898aaeb407a535226d097802a02 /cmds | |
| parent | 50752b732ee0a899433d2ad05d9c524ef2c38634 (diff) | |
lshal: print pids of client processes.
Bug: 34777099
Bug: 34861460
Test: lshal
Test: NFC / light / audio with and without persistent.hal.binderized;
run lshal to reflect this.
Change-Id: I50aa5d99fb14957b1e40a405836e68c235a22006
Diffstat (limited to 'cmds')
| -rw-r--r-- | cmds/lshal/Android.bp | 1 | ||||
| -rw-r--r-- | cmds/lshal/lshal.cpp | 69 |
2 files changed, 66 insertions, 4 deletions
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp index dd8104d180..c3805985c4 100644 --- a/cmds/lshal/Android.bp +++ b/cmds/lshal/Android.bp @@ -15,6 +15,7 @@ cc_binary { name: "lshal", shared_libs: [ + "libbase", "libutils", "libhidlbase", "android.hidl.manager@1.0", diff --git a/cmds/lshal/lshal.cpp b/cmds/lshal/lshal.cpp index 19374750d6..bc5eaf24c5 100644 --- a/cmds/lshal/lshal.cpp +++ b/cmds/lshal/lshal.cpp @@ -18,25 +18,69 @@ #include <getopt.h> #include <map> +#include <fstream> #include <iomanip> #include <iostream> #include <sstream> +#include <regex> +#include <android-base/parseint.h> #include <android/hidl/manager/1.0/IServiceManager.h> #include <hidl/ServiceManagement.h> -template <typename A, typename B, typename C, typename D> +template <typename A, typename B, typename C, typename D, typename E> void printColumn(std::stringstream &stream, - const A &a, const B &b, const C &c, const D &d) { + const A &a, const B &b, const C &c, const D &d, const E &e) { using namespace ::std; stream << left << setw(70) << a << "\t" << setw(20) << b << "\t" << setw(10) << c << "\t" << setw(5) << d << "\t" + << setw(0) << e << endl; } +std::string toHexString(uint64_t t) { + std::ostringstream os; + os << std::hex << std::setfill('0') << std::setw(16) << t; + return os.str(); +} + +::android::status_t getReferencedPids( + pid_t serverPid, std::map<uint64_t, std::string> *objects) { + + std::ifstream ifs("/d/binder/proc/" + std::to_string(serverPid)); + if (!ifs.is_open()) { + return ::android::PERMISSION_DENIED; + } + + static const std::regex prefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+"); + + std::string line; + std::smatch match; + while(getline(ifs, line)) { + if (!std::regex_search(line, match, prefix)) { + // the line doesn't start with the correct prefix + continue; + } + std::string ptrString = "0x" + match.str(2); // use number after c + uint64_t ptr; + if (!::android::base::ParseUint(ptrString.c_str(), &ptr)) { + // Should not reach here, but just be tolerant. + std::cerr << "Could not parse number " << ptrString << std::endl; + continue; + } + const std::string proc = " proc "; + auto pos = line.rfind(proc); + if (pos != std::string::npos) { + (*objects)[ptr] += line.substr(pos + proc.size()); + } + } + return ::android::OK; +} + + int dump() { using namespace ::std; using namespace ::android::hardware; @@ -51,7 +95,7 @@ int dump() { stream << "All services:" << endl; stream << left; - printColumn(stream, "Interface", "Instance", "Transport", "Ref"); + printColumn(stream, "Interface", "Instance", "Transport", "Server", "Clients"); for (const auto &pair : mapping) { const std::string &mode = pair.first; @@ -63,12 +107,29 @@ int dump() { } auto ret = manager->debugDump([&](const auto ®istered) { + // server pid, .ptr value of binder object, child pids + std::map<pid_t, std::map<uint64_t, std::string>> allPids; + for (const auto &info : registered) { + if (info.pid < 0) { + continue; + } + pid_t serverPid = info.pid; + allPids[serverPid].clear(); + } + for (auto &pair : allPids) { + pid_t serverPid = pair.first; + if (getReferencedPids(serverPid, &allPids[serverPid]) != ::android::OK) { + std::cerr << "Warning: no information for PID " << serverPid + << ", are you root?" << std::endl; + } + } for (const auto &info : registered) { printColumn(stream, info.interfaceName, info.instanceName.empty() ? "N/A" : info.instanceName, mode, - info.refCount < 0 ? "N/A" : std::to_string(info.refCount)); + info.pid < 0 ? "N/A" : std::to_string(info.pid), + info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]); } }); if (!ret.isOk()) { |