Loading cmds/dumpstate/bugreport-format.md +26 −9 Original line number Diff line number Diff line Loading @@ -59,18 +59,35 @@ files upon the end user’s request: On _Android O (Oreo)_, the following changes were made: - The ANR traces are added to the `FS` folder, typically under `FS/data/anr` (version `2.0-dev-split-anr`). ## Android P versions On _Android P (PleaseMightyAndroidWhatsYourNextReleaseName?)_, the following changes were made: - Dumpsys sections are dumped by priority (version `2.0-dev-priority-dumps`). Supported priorities can be specified when registering framework services. Section headers are changed to contain priority info. `DUMPSYS` -> `DUMPSYS CRITICAL/HIGH/NORMAL` `DUMP OF SERVICE <servicename>` -> `DUMP OF SERVICE CRITICAL/HIGH/NORMAL <servicename>` Supported Priorities: ## Version 2.0 (Android P) On _Android P_, the following changes were made: - Framework services are dumped by priority. Supported priorities can be specified when registering the service. If a service does not specify its priority, its assumed to be NORMAL. Supported priorities: - CRITICAL - services that must dump first, and fast (under 100ms). Ex: cpuinfo. - HIGH - services that also must dump first, but can take longer (under 250ms) to dump. Ex: meminfo. - HIGH - services that also must dump first, but can take longer (under 250ms) to dump. Ex: meminfo. - NORMAL - services that have no rush to dump and can take a long time (under 10s). Format changes: - Two additional dumpsys sections are generated. The two new sections can be identified by their HEADER `DUMPSYS CRITICAL` and `DUMPSYS HIGH`. - Services in the new sections will have a new header containing the priority. `DUMP OF SERVICE CRITICAL <servicename>` and `DUMP OF SERVICE HIGH <servicename>`. For example, cpuinfo will now move to `DUMPSYS CRITICAL` and will have a header `DUMP OF SERVICE CRITICAL CPUINFO`. - Bug report will contain proto dumps from all supporting services. Support can be specified when registering framework services. Format changes: - All protos will be generated into separate files per service, per priority. The files will be stored in `proto/<servicename>(_CRITICAL|_HIGH|).proto` - ANR trace feature has been pushed to version `3.0-dev-split-anr` ## Intermediate versions During development, the versions will be suffixed with _-devX_ or _-devX-EXPERIMENTAL_FEATURE_, where _X_ is a number that increases as the Loading cmds/dumpstate/dumpstate.cpp +47 −49 Original line number Diff line number Diff line Loading @@ -1110,20 +1110,14 @@ static void DumpIpAddrAndRules() { RunCommand("IP RULES v6", {"ip", "-6", "rule", "show"}); } void RunDumpsysText(const std::string& title, int priority, std::chrono::milliseconds timeout, static void RunDumpsysTextByPriority(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { auto start = std::chrono::steady_clock::now(); sp<android::IServiceManager> sm = defaultServiceManager(); Dumpsys dumpsys(sm.get()); DurationReporter duration_reporter(title); Vector<String16> args; Dumpsys::setServiceArgs(args, /* asProto = */ false, priority); if (!title.empty()) { dprintf(STDOUT_FILENO, "------ %s (%s) ------\n", title.c_str(), "/system/bin/dumpsys"); fsync(STDOUT_FILENO); } auto start = std::chrono::steady_clock::now(); Vector<String16> services = dumpsys.listServices(priority, /* supports_proto = */ false); for (const String16& service : services) { std::string path(title); Loading Loading @@ -1153,7 +1147,30 @@ void RunDumpsysText(const std::string& title, int priority, std::chrono::millise } } void RunDumpsysProto(const std::string& title, int priority, std::chrono::milliseconds timeout, static void RunDumpsysText(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { DurationReporter duration_reporter(title); dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str()); fsync(STDOUT_FILENO); RunDumpsysTextByPriority(title, priority, timeout, service_timeout); } /* Dump all services registered with Normal or Default priority. */ static void RunDumpsysTextNormalPriority(const std::string& title, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { DurationReporter duration_reporter(title); dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str()); fsync(STDOUT_FILENO); RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, timeout, service_timeout); RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT, timeout, service_timeout); } static void RunDumpsysProto(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { sp<android::IServiceManager> sm = defaultServiceManager(); Dumpsys dumpsys(sm.get()); Loading Loading @@ -1196,22 +1213,14 @@ void RunDumpsysProto(const std::string& title, int priority, std::chrono::millis // Runs dumpsys on services that must dump first and and will take less than 100ms to dump. static void RunDumpsysCritical() { if (ds.CurrentVersionSupportsPriorityDumps()) { RunDumpsysText("DUMPSYS CRITICAL", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL, /* timeout= */ 5s, /* service_timeout= */ 500ms); RunDumpsysProto("DUMPSYS CRITICAL PROTO", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL, /* timeout= */ 5s, /* service_timeout= */ 500ms); } else { RunDumpsys("DUMPSYS MEMINFO", {"meminfo", "-a"}, CommandOptions::WithTimeout(90).DropRoot().Build()); RunDumpsys("DUMPSYS CPUINFO", {"cpuinfo", "-a"}, CommandOptions::WithTimeout(10).DropRoot().Build()); } } // Runs dumpsys on services that must dump first but can take up to 250ms to dump. static void RunDumpsysHigh() { if (ds.CurrentVersionSupportsPriorityDumps()) { // TODO meminfo takes ~10s, connectivity takes ~5sec to dump. They are both // high priority. Reduce timeout once they are able to dump in a shorter time or // moved to a parallel task. Loading @@ -1219,22 +1228,13 @@ static void RunDumpsysHigh() { /* timeout= */ 90s, /* service_timeout= */ 30s); RunDumpsysProto("DUMPSYS HIGH PROTO", IServiceManager::DUMP_FLAG_PRIORITY_HIGH, /* timeout= */ 5s, /* service_timeout= */ 1s); } else { RunDumpsys("NETWORK DIAGNOSTICS", {"connectivity", "--diag"}); } } // Runs dumpsys on services that must dump but can take up to 10s to dump. static void RunDumpsysNormal() { if (ds.CurrentVersionSupportsPriorityDumps()) { RunDumpsysText("DUMPSYS", IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, /* timeout= */ 90s, /* service_timeout= */ 10s); RunDumpsysTextNormalPriority("DUMPSYS", /* timeout= */ 90s, /* service_timeout= */ 10s); RunDumpsysProto("DUMPSYS PROTO", IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, /* timeout= */ 90s, /* service_timeout= */ 10s); } else { RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10)); } } static void DumpHals() { Loading Loading @@ -1893,12 +1893,10 @@ int run_main(int argc, char* argv[]) { ds.version_ = VERSION_CURRENT; } if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR && ds.version_ != VERSION_PRIORITY_DUMPS) { MYLOGE( "invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s', '%s')\n", if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR) { MYLOGE("invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s')\n", ds.version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str(), VERSION_SPLIT_ANR.c_str(), VERSION_PRIORITY_DUMPS.c_str()); VERSION_SPLIT_ANR.c_str()); exit(1); } Loading cmds/dumpstate/dumpstate.h +3 −9 Original line number Diff line number Diff line Loading @@ -145,19 +145,13 @@ class Progress { * * See bugreport-format.md for more info. */ static std::string VERSION_CURRENT = "1.0"; static std::string VERSION_CURRENT = "2.0"; /* * Temporary version that adds a anr-traces.txt entry. Once tools support it, the current version * will be bumped to 2.0. * will be bumped to 3.0. */ static std::string VERSION_SPLIT_ANR = "2.0-dev-split-anr"; /* * Temporary version that adds priority based dumps. Once tools support it, the current version * will be bumped to 2.0. */ static std::string VERSION_PRIORITY_DUMPS = "2.0-dev-priority-dumps"; static std::string VERSION_SPLIT_ANR = "3.0-dev-split-anr"; /* * "Alias" for the current version. Loading cmds/dumpstate/utils.cpp +0 −4 Original line number Diff line number Diff line Loading @@ -259,10 +259,6 @@ std::string Dumpstate::GetPath(const std::string& suffix) const { name_.c_str(), suffix.c_str()); } bool Dumpstate::CurrentVersionSupportsPriorityDumps() const { return (version_ == VERSION_PRIORITY_DUMPS); } void Dumpstate::SetProgress(std::unique_ptr<Progress> progress) { progress_ = std::move(progress); } Loading cmds/dumpsys/dumpsys.cpp +16 −6 Original line number Diff line number Diff line Loading @@ -284,14 +284,23 @@ Vector<String16> Dumpsys::listServices(int priorityFilterFlags, bool filterByPro } void Dumpsys::setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags) { if ((priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL)) { args.add(String16("-a")); } // Add proto flag if dumping service as proto. if (asProto) { args.insertAt(String16(PriorityDumper::PROTO_ARG), 0); } if (priorityFlags != IServiceManager::DUMP_FLAG_PRIORITY_ALL) { // Add -a (dump all) flag if dumping all services, dumping normal services or // services not explicitly registered to a priority bucket (default services). if ((priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)) { args.insertAt(String16("-a"), 0); } // Add priority flags when dumping services registered to a specific priority bucket. if ((priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_HIGH) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL)) { String16 priorityType = ConvertBitmaskToPriorityType(priorityFlags); args.insertAt(String16(PriorityDumper::PRIORITY_ARG), 0); args.insertAt(priorityType, 1); Loading Loading @@ -349,7 +358,8 @@ void Dumpsys::writeDumpHeader(int fd, const String16& serviceName, int priorityF "----------------------------------------" "---------------------------------------\n"); if (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL || priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) { priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL || priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) { StringAppendF(&msg, "DUMP OF SERVICE %s:\n", String8(serviceName).c_str()); } else { String16 priorityType = ConvertBitmaskToPriorityType(priorityFlags); Loading Loading
cmds/dumpstate/bugreport-format.md +26 −9 Original line number Diff line number Diff line Loading @@ -59,18 +59,35 @@ files upon the end user’s request: On _Android O (Oreo)_, the following changes were made: - The ANR traces are added to the `FS` folder, typically under `FS/data/anr` (version `2.0-dev-split-anr`). ## Android P versions On _Android P (PleaseMightyAndroidWhatsYourNextReleaseName?)_, the following changes were made: - Dumpsys sections are dumped by priority (version `2.0-dev-priority-dumps`). Supported priorities can be specified when registering framework services. Section headers are changed to contain priority info. `DUMPSYS` -> `DUMPSYS CRITICAL/HIGH/NORMAL` `DUMP OF SERVICE <servicename>` -> `DUMP OF SERVICE CRITICAL/HIGH/NORMAL <servicename>` Supported Priorities: ## Version 2.0 (Android P) On _Android P_, the following changes were made: - Framework services are dumped by priority. Supported priorities can be specified when registering the service. If a service does not specify its priority, its assumed to be NORMAL. Supported priorities: - CRITICAL - services that must dump first, and fast (under 100ms). Ex: cpuinfo. - HIGH - services that also must dump first, but can take longer (under 250ms) to dump. Ex: meminfo. - HIGH - services that also must dump first, but can take longer (under 250ms) to dump. Ex: meminfo. - NORMAL - services that have no rush to dump and can take a long time (under 10s). Format changes: - Two additional dumpsys sections are generated. The two new sections can be identified by their HEADER `DUMPSYS CRITICAL` and `DUMPSYS HIGH`. - Services in the new sections will have a new header containing the priority. `DUMP OF SERVICE CRITICAL <servicename>` and `DUMP OF SERVICE HIGH <servicename>`. For example, cpuinfo will now move to `DUMPSYS CRITICAL` and will have a header `DUMP OF SERVICE CRITICAL CPUINFO`. - Bug report will contain proto dumps from all supporting services. Support can be specified when registering framework services. Format changes: - All protos will be generated into separate files per service, per priority. The files will be stored in `proto/<servicename>(_CRITICAL|_HIGH|).proto` - ANR trace feature has been pushed to version `3.0-dev-split-anr` ## Intermediate versions During development, the versions will be suffixed with _-devX_ or _-devX-EXPERIMENTAL_FEATURE_, where _X_ is a number that increases as the Loading
cmds/dumpstate/dumpstate.cpp +47 −49 Original line number Diff line number Diff line Loading @@ -1110,20 +1110,14 @@ static void DumpIpAddrAndRules() { RunCommand("IP RULES v6", {"ip", "-6", "rule", "show"}); } void RunDumpsysText(const std::string& title, int priority, std::chrono::milliseconds timeout, static void RunDumpsysTextByPriority(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { auto start = std::chrono::steady_clock::now(); sp<android::IServiceManager> sm = defaultServiceManager(); Dumpsys dumpsys(sm.get()); DurationReporter duration_reporter(title); Vector<String16> args; Dumpsys::setServiceArgs(args, /* asProto = */ false, priority); if (!title.empty()) { dprintf(STDOUT_FILENO, "------ %s (%s) ------\n", title.c_str(), "/system/bin/dumpsys"); fsync(STDOUT_FILENO); } auto start = std::chrono::steady_clock::now(); Vector<String16> services = dumpsys.listServices(priority, /* supports_proto = */ false); for (const String16& service : services) { std::string path(title); Loading Loading @@ -1153,7 +1147,30 @@ void RunDumpsysText(const std::string& title, int priority, std::chrono::millise } } void RunDumpsysProto(const std::string& title, int priority, std::chrono::milliseconds timeout, static void RunDumpsysText(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { DurationReporter duration_reporter(title); dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str()); fsync(STDOUT_FILENO); RunDumpsysTextByPriority(title, priority, timeout, service_timeout); } /* Dump all services registered with Normal or Default priority. */ static void RunDumpsysTextNormalPriority(const std::string& title, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { DurationReporter duration_reporter(title); dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str()); fsync(STDOUT_FILENO); RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, timeout, service_timeout); RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT, timeout, service_timeout); } static void RunDumpsysProto(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { sp<android::IServiceManager> sm = defaultServiceManager(); Dumpsys dumpsys(sm.get()); Loading Loading @@ -1196,22 +1213,14 @@ void RunDumpsysProto(const std::string& title, int priority, std::chrono::millis // Runs dumpsys on services that must dump first and and will take less than 100ms to dump. static void RunDumpsysCritical() { if (ds.CurrentVersionSupportsPriorityDumps()) { RunDumpsysText("DUMPSYS CRITICAL", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL, /* timeout= */ 5s, /* service_timeout= */ 500ms); RunDumpsysProto("DUMPSYS CRITICAL PROTO", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL, /* timeout= */ 5s, /* service_timeout= */ 500ms); } else { RunDumpsys("DUMPSYS MEMINFO", {"meminfo", "-a"}, CommandOptions::WithTimeout(90).DropRoot().Build()); RunDumpsys("DUMPSYS CPUINFO", {"cpuinfo", "-a"}, CommandOptions::WithTimeout(10).DropRoot().Build()); } } // Runs dumpsys on services that must dump first but can take up to 250ms to dump. static void RunDumpsysHigh() { if (ds.CurrentVersionSupportsPriorityDumps()) { // TODO meminfo takes ~10s, connectivity takes ~5sec to dump. They are both // high priority. Reduce timeout once they are able to dump in a shorter time or // moved to a parallel task. Loading @@ -1219,22 +1228,13 @@ static void RunDumpsysHigh() { /* timeout= */ 90s, /* service_timeout= */ 30s); RunDumpsysProto("DUMPSYS HIGH PROTO", IServiceManager::DUMP_FLAG_PRIORITY_HIGH, /* timeout= */ 5s, /* service_timeout= */ 1s); } else { RunDumpsys("NETWORK DIAGNOSTICS", {"connectivity", "--diag"}); } } // Runs dumpsys on services that must dump but can take up to 10s to dump. static void RunDumpsysNormal() { if (ds.CurrentVersionSupportsPriorityDumps()) { RunDumpsysText("DUMPSYS", IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, /* timeout= */ 90s, /* service_timeout= */ 10s); RunDumpsysTextNormalPriority("DUMPSYS", /* timeout= */ 90s, /* service_timeout= */ 10s); RunDumpsysProto("DUMPSYS PROTO", IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, /* timeout= */ 90s, /* service_timeout= */ 10s); } else { RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10)); } } static void DumpHals() { Loading Loading @@ -1893,12 +1893,10 @@ int run_main(int argc, char* argv[]) { ds.version_ = VERSION_CURRENT; } if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR && ds.version_ != VERSION_PRIORITY_DUMPS) { MYLOGE( "invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s', '%s')\n", if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR) { MYLOGE("invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s')\n", ds.version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str(), VERSION_SPLIT_ANR.c_str(), VERSION_PRIORITY_DUMPS.c_str()); VERSION_SPLIT_ANR.c_str()); exit(1); } Loading
cmds/dumpstate/dumpstate.h +3 −9 Original line number Diff line number Diff line Loading @@ -145,19 +145,13 @@ class Progress { * * See bugreport-format.md for more info. */ static std::string VERSION_CURRENT = "1.0"; static std::string VERSION_CURRENT = "2.0"; /* * Temporary version that adds a anr-traces.txt entry. Once tools support it, the current version * will be bumped to 2.0. * will be bumped to 3.0. */ static std::string VERSION_SPLIT_ANR = "2.0-dev-split-anr"; /* * Temporary version that adds priority based dumps. Once tools support it, the current version * will be bumped to 2.0. */ static std::string VERSION_PRIORITY_DUMPS = "2.0-dev-priority-dumps"; static std::string VERSION_SPLIT_ANR = "3.0-dev-split-anr"; /* * "Alias" for the current version. Loading
cmds/dumpstate/utils.cpp +0 −4 Original line number Diff line number Diff line Loading @@ -259,10 +259,6 @@ std::string Dumpstate::GetPath(const std::string& suffix) const { name_.c_str(), suffix.c_str()); } bool Dumpstate::CurrentVersionSupportsPriorityDumps() const { return (version_ == VERSION_PRIORITY_DUMPS); } void Dumpstate::SetProgress(std::unique_ptr<Progress> progress) { progress_ = std::move(progress); } Loading
cmds/dumpsys/dumpsys.cpp +16 −6 Original line number Diff line number Diff line Loading @@ -284,14 +284,23 @@ Vector<String16> Dumpsys::listServices(int priorityFilterFlags, bool filterByPro } void Dumpsys::setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags) { if ((priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL)) { args.add(String16("-a")); } // Add proto flag if dumping service as proto. if (asProto) { args.insertAt(String16(PriorityDumper::PROTO_ARG), 0); } if (priorityFlags != IServiceManager::DUMP_FLAG_PRIORITY_ALL) { // Add -a (dump all) flag if dumping all services, dumping normal services or // services not explicitly registered to a priority bucket (default services). if ((priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)) { args.insertAt(String16("-a"), 0); } // Add priority flags when dumping services registered to a specific priority bucket. if ((priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_HIGH) || (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL)) { String16 priorityType = ConvertBitmaskToPriorityType(priorityFlags); args.insertAt(String16(PriorityDumper::PRIORITY_ARG), 0); args.insertAt(priorityType, 1); Loading Loading @@ -349,7 +358,8 @@ void Dumpsys::writeDumpHeader(int fd, const String16& serviceName, int priorityF "----------------------------------------" "---------------------------------------\n"); if (priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL || priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) { priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_NORMAL || priorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) { StringAppendF(&msg, "DUMP OF SERVICE %s:\n", String8(serviceName).c_str()); } else { String16 priorityType = ConvertBitmaskToPriorityType(priorityFlags); Loading