summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYifan Hong <elsk@google.com>2020-08-07 18:24:06 -0700
committerYifan Hong <elsk@google.com>2020-08-07 20:02:16 -0700
commit30528a2d917aae624f01a89213147da44fee2ab9 (patch)
treefd7a79c4fd8142d287a76cabaa6f0bfe69bc2054
parent52e3b47cae759317fb4a87df25568b897b132585 (diff)
downloadnative-30528a2d917aae624f01a89213147da44fee2ab9.tar.gz
lshal: Add --all --types=all, and use in bugreport
Also clang-format. When --all is specified, put "clients" at the end because it is usually the longest. Test: lshal --all Test: lshal --all --cmdline Test: lshal --types=all Test: adb bugreport Bug: 163060248 Change-Id: If95a18cff50d3b6ef3f70b300f16105b41ca28ed
-rw-r--r--cmds/dumpstate/dumpstate.cpp4
-rw-r--r--cmds/lshal/ListCommand.cpp110
-rw-r--r--cmds/lshal/ListCommand.h3
-rw-r--r--cmds/lshal/TableEntry.h14
-rw-r--r--cmds/lshal/test.cpp69
5 files changed, 152 insertions, 48 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 78c09f2b5a..e2884e578c 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1237,12 +1237,12 @@ static Dumpstate::RunStatus RunDumpsysNormal() {
static void DumpHals() {
if (!ds.IsZipping()) {
- RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
+ RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all", "--debug"},
CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
return;
}
DurationReporter duration_reporter("DUMP HALS");
- RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
+ RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all"},
CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
using android::hidl::manager::V1_0::IServiceManager;
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index a805a4844a..92958d957b 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -916,6 +916,18 @@ void ListCommand::initFetchTypes() {
}
}
+// Get all values of enum type T, assuming the first value is 0 and the last value is T::LAST.
+// T::LAST is not included in the returned list.
+template <typename T>
+std::vector<T> GetAllValues() {
+ using BaseType = std::underlying_type_t<T>;
+ std::vector<T> ret;
+ for (BaseType i = 0; i < static_cast<BaseType>(T::LAST); ++i) {
+ ret.push_back(static_cast<T>(i));
+ }
+ return ret;
+}
+
void ListCommand::registerAllOptions() {
int v = mOptions.size();
// A list of acceptable command line options
@@ -989,6 +1001,15 @@ void ListCommand::registerAllOptions() {
" - declared: only declared in VINTF manifest but is not registered to hwservicemanager;\n"
" - N/A: no information for passthrough HALs."});
+ mOptions.push_back({'A', "all", no_argument, v++,
+ [](ListCommand* thiz, const char*) {
+ auto allColumns = GetAllValues<TableColumnType>();
+ thiz->mSelectedColumns.insert(thiz->mSelectedColumns.end(),
+ allColumns.begin(), allColumns.end());
+ return OK;
+ },
+ "print all columns"});
+
// long options without short alternatives
mOptions.push_back({'\0', "init-vintf", no_argument, v++, [](ListCommand* thiz, const char* arg) {
thiz->mVintf = true;
@@ -1019,46 +1040,55 @@ void ListCommand::registerAllOptions() {
thiz->mNeat = true;
return OK;
}, "output is machine parsable (no explanatory text).\nCannot be used with --debug."});
- mOptions.push_back({'\0', "types", required_argument, v++, [](ListCommand* thiz, const char* arg) {
- if (!arg) { return USAGE; }
-
- static const std::map<std::string, HalType> kHalTypeMap {
- {"binderized", HalType::BINDERIZED_SERVICES},
- {"b", HalType::BINDERIZED_SERVICES},
- {"passthrough_clients", HalType::PASSTHROUGH_CLIENTS},
- {"c", HalType::PASSTHROUGH_CLIENTS},
- {"passthrough_libs", HalType::PASSTHROUGH_LIBRARIES},
- {"l", HalType::PASSTHROUGH_LIBRARIES},
- {"vintf", HalType::VINTF_MANIFEST},
- {"v", HalType::VINTF_MANIFEST},
- {"lazy", HalType::LAZY_HALS},
- {"z", HalType::LAZY_HALS},
- };
-
- std::vector<std::string> halTypesArgs = split(std::string(arg), ',');
- for (const auto& halTypeArg : halTypesArgs) {
- if (halTypeArg.empty()) continue;
-
- const auto& halTypeIter = kHalTypeMap.find(halTypeArg);
- if (halTypeIter == kHalTypeMap.end()) {
-
- thiz->err() << "Unrecognized HAL type: " << halTypeArg << std::endl;
- return USAGE;
- }
-
- // Append unique (non-repeated) HAL types to the reporting list
- HalType halType = halTypeIter->second;
- if (std::find(thiz->mListTypes.begin(), thiz->mListTypes.end(), halType) ==
- thiz->mListTypes.end()) {
- thiz->mListTypes.push_back(halType);
- }
- }
-
- if (thiz->mListTypes.empty()) { return USAGE; }
- return OK;
- }, "comma-separated list of one or more sections.\nThe output is restricted to the selected "
- "section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
- "passthrough_libs), (v|vintf), and (z|lazy).\nDefault is `bcl`."});
+ mOptions.push_back(
+ {'\0', "types", required_argument, v++,
+ [](ListCommand* thiz, const char* arg) {
+ if (!arg) {
+ return USAGE;
+ }
+
+ static const std::map<std::string, std::vector<HalType>> kHalTypeMap{
+ {"binderized", {HalType::BINDERIZED_SERVICES}},
+ {"b", {HalType::BINDERIZED_SERVICES}},
+ {"passthrough_clients", {HalType::PASSTHROUGH_CLIENTS}},
+ {"c", {HalType::PASSTHROUGH_CLIENTS}},
+ {"passthrough_libs", {HalType::PASSTHROUGH_LIBRARIES}},
+ {"l", {HalType::PASSTHROUGH_LIBRARIES}},
+ {"vintf", {HalType::VINTF_MANIFEST}},
+ {"v", {HalType::VINTF_MANIFEST}},
+ {"lazy", {HalType::LAZY_HALS}},
+ {"z", {HalType::LAZY_HALS}},
+ {"all", GetAllValues<HalType>()},
+ {"a", GetAllValues<HalType>()},
+ };
+
+ std::vector<std::string> halTypesArgs = split(std::string(arg), ',');
+ for (const auto& halTypeArg : halTypesArgs) {
+ if (halTypeArg.empty()) continue;
+
+ const auto& halTypeIter = kHalTypeMap.find(halTypeArg);
+ if (halTypeIter == kHalTypeMap.end()) {
+ thiz->err() << "Unrecognized HAL type: " << halTypeArg << std::endl;
+ return USAGE;
+ }
+
+ // Append unique (non-repeated) HAL types to the reporting list
+ for (auto halType : halTypeIter->second) {
+ if (std::find(thiz->mListTypes.begin(), thiz->mListTypes.end(), halType) ==
+ thiz->mListTypes.end()) {
+ thiz->mListTypes.push_back(halType);
+ }
+ }
+ }
+
+ if (thiz->mListTypes.empty()) {
+ return USAGE;
+ }
+ return OK;
+ },
+ "comma-separated list of one or more sections.\nThe output is restricted to the "
+ "selected section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
+ "passthrough_libs), (v|vintf), (z|lazy), and (a|all).\nDefault is `b,c,l`."});
}
// Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h
index acc0dcfc2e..412aadd7e4 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -52,6 +52,9 @@ enum class HalType {
PASSTHROUGH_LIBRARIES,
VINTF_MANIFEST,
LAZY_HALS,
+
+ // Not a real HalType. Used to determine all HalTypes.
+ LAST,
};
class ListCommand : public Command {
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 0ff0c96d38..3c368132a5 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -35,19 +35,25 @@ using android::procpartition::Partition;
using Pids = std::vector<int32_t>;
enum class TableColumnType : unsigned int {
- INTERFACE_NAME,
+ INTERFACE_NAME = 0,
TRANSPORT,
SERVER_PID,
- SERVER_CMD,
SERVER_ADDR,
- CLIENT_PIDS,
- CLIENT_CMDS,
ARCH,
THREADS,
RELEASED,
HASH,
VINTF,
SERVICE_STATUS,
+ CLIENT_PIDS,
+
+ // Not a real TableColumnType. Used to determine all TableColumnTypes.
+ LAST,
+
+ // Not included in all TableColumnTypes because they replace *PID(S) when the
+ // --cmdline option is set.
+ SERVER_CMD,
+ CLIENT_CMDS,
};
enum : unsigned int {
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index afe5d63575..9964888233 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -708,8 +708,8 @@ TEST_F(ListTest, DumpEmptyAndDuplicateHalTypes) {
TEST_F(ListTest, UnknownHalType) {
optind = 1; // mimic Lshal::parseArg()
- EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,a"})));
- EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: a"));
+ EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,r"})));
+ EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: r"));
}
TEST_F(ListTest, Vintf) {
@@ -793,6 +793,71 @@ TEST_F(ListTest, Vintf) {
EXPECT_EQ("", err.str());
}
+TEST_F(ListTest, AllColumns) {
+ // clang-format off
+ const std::string expected =
+ "[fake description 0]\n"
+ "Interface Transport Server PTR Arch Thread Use R Hash VINTF Status Clients\n"
+ "a.h.foo1@1.0::IFoo/1 hwbinder 1 0000000000002711 64 11/21 N 0000000000000000000000000000000000000000000000000000000000000000 X alive 2 4\n"
+ "a.h.foo2@2.0::IFoo/2 hwbinder 2 0000000000002712 64 12/22 Y 0202020202020202020202020202020202020202020202020202020202020202 X alive 3 5\n"
+ "\n"
+ "[fake description 1]\n"
+ "Interface Transport Server PTR Arch Thread Use R Hash VINTF Status Clients\n"
+ "a.h.foo3@3.0::IFoo/3 passthrough N/A N/A 32 N/A ? X N/A 4 6\n"
+ "a.h.foo4@4.0::IFoo/4 passthrough N/A N/A 32 N/A ? X N/A 5 7\n"
+ "\n"
+ "[fake description 2]\n"
+ "Interface Transport Server PTR Arch Thread Use R Hash VINTF Status Clients\n"
+ "a.h.foo5@5.0::IFoo/5 passthrough N/A N/A 32 N/A ? X N/A 6 8\n"
+ "a.h.foo6@6.0::IFoo/6 passthrough N/A N/A 32 N/A ? X N/A 7 9\n"
+ "\n";
+ // clang-format on
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--all"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, AllColumnsWithCmd) {
+ // clang-format off
+ const std::string expected =
+ "[fake description 0]\n"
+ "Interface Transport Server CMD PTR Arch Thread Use R Hash VINTF Status Clients CMD\n"
+ "a.h.foo1@1.0::IFoo/1 hwbinder command_line_1 0000000000002711 64 11/21 N 0000000000000000000000000000000000000000000000000000000000000000 X alive command_line_2;command_line_4\n"
+ "a.h.foo2@2.0::IFoo/2 hwbinder command_line_2 0000000000002712 64 12/22 Y 0202020202020202020202020202020202020202020202020202020202020202 X alive command_line_3;command_line_5\n"
+ "\n"
+ "[fake description 1]\n"
+ "Interface Transport Server CMD PTR Arch Thread Use R Hash VINTF Status Clients CMD\n"
+ "a.h.foo3@3.0::IFoo/3 passthrough N/A 32 N/A ? X N/A command_line_4;command_line_6\n"
+ "a.h.foo4@4.0::IFoo/4 passthrough N/A 32 N/A ? X N/A command_line_5;command_line_7\n"
+ "\n"
+ "[fake description 2]\n"
+ "Interface Transport Server CMD PTR Arch Thread Use R Hash VINTF Status Clients CMD\n"
+ "a.h.foo5@5.0::IFoo/5 passthrough N/A 32 N/A ? X N/A command_line_6;command_line_8\n"
+ "a.h.foo6@6.0::IFoo/6 passthrough N/A 32 N/A ? X N/A command_line_7;command_line_9\n"
+ "\n";
+ // clang-format on
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-Am"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, AllSections) {
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--types=all"})));
+ using HalTypeBase = std::underlying_type_t<HalType>;
+ for (HalTypeBase i = 0; i < static_cast<HalTypeBase>(HalType::LAST); ++i) {
+ EXPECT_THAT(out.str(), HasSubstr("[fake description " + std::to_string(i) + "]"));
+ }
+ EXPECT_THAT(out.str(),
+ Not(HasSubstr("[fake description " +
+ std::to_string(static_cast<HalTypeBase>(HalType::LAST)) + "]")));
+ EXPECT_EQ("", err.str());
+}
+
// Fake service returned by mocked IServiceManager::get for DumpDebug.
// The interfaceChain and getHashChain functions returns
// foo(id - 1) -> foo(id - 2) -> ... foo1 -> IBase.