1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_ 18 #define FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_ 19 20 #include <time.h> 21 #include <unistd.h> 22 #include <stdbool.h> 23 #include <stdio.h> 24 25 #include <string> 26 #include <vector> 27 28 #include <android-base/macros.h> 29 #include <android-base/unique_fd.h> 30 #include <android/hardware/dumpstate/1.1/types.h> 31 #include <android/os/BnIncidentAuthListener.h> 32 #include <android/os/IDumpstate.h> 33 #include <android/os/IDumpstateListener.h> 34 #include <utils/StrongPointer.h> 35 #include <ziparchive/zip_writer.h> 36 37 #include "DumpstateUtil.h" 38 #include "DumpPool.h" 39 #include "TaskQueue.h" 40 41 // Workaround for const char *args[MAX_ARGS_ARRAY_SIZE] variables until they're converted to 42 // std::vector<std::string> 43 // TODO: remove once not used 44 #define MAX_ARGS_ARRAY_SIZE 1000 45 46 // TODO: move everything under this namespace 47 // TODO: and then remove explicitly android::os::dumpstate:: prefixes 48 namespace android { 49 namespace os { 50 51 struct DumpstateOptions; 52 53 namespace dumpstate { 54 55 class DumpstateTest; 56 class ProgressTest; 57 class ZippedBugReportStreamTest; 58 59 } // namespace dumpstate 60 } // namespace os 61 } // namespace android 62 63 class ZipWriter; 64 65 // TODO: remove once moved to HAL 66 #ifdef __cplusplus 67 extern "C" { 68 #endif 69 70 /* 71 * Helper class used to report how long it takes for a section to finish. 72 * 73 * Typical usage: 74 * 75 * DurationReporter duration_reporter(title); 76 * 77 */ 78 class DurationReporter { 79 public: 80 explicit DurationReporter(const std::string& title, bool logcat_only = false, 81 bool verbose = false, int duration_fd = STDOUT_FILENO); 82 83 ~DurationReporter(); 84 85 private: 86 std::string title_; 87 bool logcat_only_; 88 bool verbose_; 89 uint64_t started_; 90 int duration_fd_; 91 92 DISALLOW_COPY_AND_ASSIGN(DurationReporter); 93 }; 94 95 /* 96 * Keeps track of current progress and estimated max, saving stats on file to tune up future runs. 97 * 98 * Each `dumpstate` section contributes to the total weight by an individual weight, so the overall 99 * progress can be calculated by dividing the estimate max progress by the current progress. 100 * 101 * The estimated max progress is initially set to a value (`kDefaultMax) defined empirically, but 102 * it's adjusted after each dumpstate run by storing the average duration in a file. 103 * 104 */ 105 class Progress { 106 friend class android::os::dumpstate::ProgressTest; 107 friend class android::os::dumpstate::DumpstateTest; 108 109 public: 110 /* 111 * Default estimation of the max duration of a bugreport generation. 112 * 113 * It does not need to match the exact sum of all sections, but ideally it should to be slight 114 * more than such sum: a value too high will cause the bugreport to finish before the user 115 * expected (for example, jumping from 70% to 100%), while a value too low will cause the 116 * progress to get stuck at an almost-finished value (like 99%) for a while. 117 * 118 * This constant is only used when the average duration from previous runs cannot be used. 119 */ 120 static const int kDefaultMax; 121 122 explicit Progress(const std::string& path = ""); 123 124 // Gets the current progress. 125 int32_t Get() const; 126 127 // Gets the current estimated max progress. 128 int32_t GetMax() const; 129 130 // Gets the initial estimated max progress. 131 int32_t GetInitialMax() const; 132 133 // Increments progress (ignored if not positive). 134 // Returns `true` if the max progress increased as well. 135 bool Inc(int32_t delta); 136 137 // Persist the stats. 138 void Save(); 139 140 void Dump(int fd, const std::string& prefix) const; 141 142 private: 143 Progress(int32_t initial_max, float growth_factor, 144 const std::string& path = ""); // Used by test cases. 145 Progress(int32_t initial_max, int32_t progress, float growth_factor); // Used by test cases. 146 void Load(); 147 int32_t initial_max_; 148 int32_t progress_; 149 int32_t max_; 150 float growth_factor_; 151 int32_t n_runs_; 152 int32_t average_max_; 153 std::string path_; 154 }; 155 156 /* 157 * List of supported zip format versions. 158 * 159 * See bugreport-format.md for more info. 160 */ 161 static std::string VERSION_CURRENT = "2.0"; 162 163 /* 164 * Temporary version that adds a anr-traces.txt entry. Once tools support it, the current version 165 * will be bumped to 3.0. 166 */ 167 static std::string VERSION_SPLIT_ANR = "3.0-dev-split-anr"; 168 169 /* 170 * "Alias" for the current version. 171 */ 172 static std::string VERSION_DEFAULT = "default"; 173 174 /* 175 * Directory used by Dumpstate binary to keep its local files. 176 */ 177 static const std::string DUMPSTATE_DIRECTORY = "/bugreports"; 178 179 /* 180 * Structure that contains the information of an open dump file. 181 */ 182 struct DumpData { 183 // Path of the file. 184 std::string name; 185 186 // Open file descriptor for the file. 187 android::base::unique_fd fd; 188 189 // Modification time of the file. 190 time_t mtime; 191 }; 192 193 /* 194 * Main class driving a bugreport generation. 195 * 196 * Currently, it only contains variables that are accessed externally, but gradually the functions 197 * that are spread accross utils.cpp and dumpstate.cpp will be moved to it. 198 */ 199 class Dumpstate { 200 friend class android::os::dumpstate::DumpstateTest; 201 friend class android::os::dumpstate::ZippedBugReportStreamTest; 202 203 public: 204 enum RunStatus { OK, HELP, INVALID_INPUT, ERROR, USER_CONSENT_DENIED, USER_CONSENT_TIMED_OUT }; 205 206 // The mode under which the bugreport should be run. Each mode encapsulates a few options. 207 enum BugreportMode { 208 BUGREPORT_FULL = android::os::IDumpstate::BUGREPORT_MODE_FULL, 209 BUGREPORT_INTERACTIVE = android::os::IDumpstate::BUGREPORT_MODE_INTERACTIVE, 210 BUGREPORT_REMOTE = android::os::IDumpstate::BUGREPORT_MODE_REMOTE, 211 BUGREPORT_WEAR = android::os::IDumpstate::BUGREPORT_MODE_WEAR, 212 BUGREPORT_TELEPHONY = android::os::IDumpstate::BUGREPORT_MODE_TELEPHONY, 213 BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI, 214 BUGREPORT_DEFAULT = android::os::IDumpstate::BUGREPORT_MODE_DEFAULT 215 }; 216 217 static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS; 218 219 static Dumpstate& GetInstance(); 220 221 /* Checkes whether dumpstate is generating a zipped bugreport. */ 222 bool IsZipping() const; 223 224 /* Initialize dumpstate fields before starting bugreport generation */ 225 void Initialize(); 226 227 /* 228 * Forks a command, waits for it to finish, and returns its status. 229 * 230 * |title| description of the command printed on `stdout` (or empty to skip 231 * description). 232 * |full_command| array containing the command (first entry) and its arguments. 233 * Must contain at least one element. 234 * |options| optional argument defining the command's behavior. 235 * |out_fd| A fd to support the DumpPool to output results to a temporary 236 * file. Using STDOUT_FILENO if it's not running in the parallel task. 237 */ 238 int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand, 239 const android::os::dumpstate::CommandOptions& options = 240 android::os::dumpstate::CommandOptions::DEFAULT, 241 bool verbose_duration = false, int out_fd = STDOUT_FILENO); 242 243 /* 244 * Runs `dumpsys` with the given arguments, automatically setting its timeout 245 * (`-T` argument) 246 * according to the command options. 247 * 248 * |title| description of the command printed on `stdout` (or empty to skip 249 * description). 250 * |dumpsys_args| `dumpsys` arguments (except `-t`). 251 * |options| optional argument defining the command's behavior. 252 * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -T` (otherwise it uses the 253 * timeout from `options`) 254 * |out_fd| A fd to support the DumpPool to output results to a temporary 255 * file. Using STDOUT_FILENO if it's not running in the parallel task. 256 */ 257 void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args, 258 const android::os::dumpstate::CommandOptions& options = DEFAULT_DUMPSYS, 259 long dumpsys_timeout_ms = 0, int out_fd = STDOUT_FILENO); 260 261 /* 262 * Prints the contents of a file. 263 * 264 * |title| description of the command printed on `stdout` (or empty to skip 265 * description). 266 * |path| location of the file to be dumped. 267 */ 268 int DumpFile(const std::string& title, const std::string& path); 269 270 /* 271 * Adds a new entry to the existing zip file. 272 * */ 273 bool AddZipEntry(const std::string& entry_name, const std::string& entry_path); 274 275 /* 276 * Adds a new entry to the existing zip file. 277 * 278 * |entry_name| destination path of the new entry. 279 * |fd| file descriptor to read from. 280 * |timeout| timeout to terminate the read if not completed. Set 281 * value of 0s (default) to disable timeout. 282 */ 283 android::status_t AddZipEntryFromFd(const std::string& entry_name, int fd, 284 std::chrono::milliseconds timeout); 285 286 /* 287 * Adds a text entry to the existing zip file. 288 */ 289 bool AddTextZipEntry(const std::string& entry_name, const std::string& content); 290 291 /* 292 * Adds all files from a directory to the zipped bugreport file. 293 */ 294 void AddDir(const std::string& dir, bool recursive); 295 296 /* 297 * Takes a screenshot and save it to the given `path`. 298 * 299 * If `path` is empty, uses a standard path based on the bugreport name. 300 */ 301 void TakeScreenshot(const std::string& path = ""); 302 303 ///////////////////////////////////////////////////////////////////// 304 // TODO: members below should be private once refactor is finished // 305 ///////////////////////////////////////////////////////////////////// 306 307 // TODO: temporary method until Dumpstate object is properly set 308 void SetProgress(std::unique_ptr<Progress> progress); 309 310 // Dumps Dalvik and native stack traces, sets the trace file location to path 311 // if it succeeded. 312 // Note that it returns early if user consent is denied with status USER_CONSENT_DENIED. 313 // Returns OK in all other cases. 314 RunStatus DumpTraces(const char** path); 315 316 /* 317 * |out_fd| A fd to support the DumpPool to output results to a temporary file. 318 * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO 319 * if it's not running in the parallel task. 320 */ 321 void DumpstateBoard(int out_fd = STDOUT_FILENO); 322 323 /* 324 * Updates the overall progress of the bugreport generation by the given weight increment. 325 */ 326 void UpdateProgress(int32_t delta); 327 328 /* Prints the dumpstate header on `stdout`. */ 329 void PrintHeader() const; 330 331 /* 332 * Adds the temporary report to the existing .zip file, closes the .zip file, and removes the 333 * temporary file. 334 */ 335 bool FinishZipFile(); 336 337 /* Constructs a full path inside directory with file name formatted using the given suffix. */ 338 std::string GetPath(const std::string& directory, const std::string& suffix) const; 339 340 /* Constructs a full path inside bugreport_internal_dir_ with file name formatted using the 341 * given suffix. */ 342 std::string GetPath(const std::string& suffix) const; 343 344 /* Returns true if the current version supports priority dump feature. */ 345 bool CurrentVersionSupportsPriorityDumps() const; 346 347 struct DumpOptions; 348 349 /* 350 * Main entry point for running a complete bugreport. 351 * 352 * Initialize() dumpstate before calling this method. 353 * 354 */ 355 RunStatus Run(int32_t calling_uid, const std::string& calling_package); 356 357 RunStatus ParseCommandlineAndRun(int argc, char* argv[]); 358 359 /* Deletes in-progress files */ 360 void Cancel(); 361 362 /* Sets runtime options. */ 363 void SetOptions(std::unique_ptr<DumpOptions> options); 364 365 /* 366 * Returns true if user consent is necessary and has been denied. 367 * Consent is only necessary if the caller has asked to copy over the bugreport to a file they 368 * provided. 369 */ 370 bool IsUserConsentDenied() const; 371 372 /* 373 * Returns true if dumpstate is called by bugreporting API 374 */ 375 bool CalledByApi() const; 376 377 /* 378 * Enqueues a task to the dumpstate's TaskQueue if the parallel run is enabled, 379 * otherwise invokes it immediately. The task adds file at path entry_path 380 * as a zip file entry with name entry_name. Unlinks entry_path when done. 381 * 382 * All enqueued tasks will be executed in the dumpstate's FinishZipFile method 383 * before the zip file is finished. Tasks will be cancelled in dumpstate's 384 * ShutdownDumpPool method if they have never been called. 385 */ 386 void EnqueueAddZipEntryAndCleanupIfNeeded(const std::string& entry_name, 387 const std::string& entry_path); 388 389 /* 390 * Structure to hold options that determine the behavior of dumpstate. 391 */ 392 struct DumpOptions { 393 bool do_vibrate = true; 394 // Writes bugreport zipped file to a socket. 395 bool stream_to_socket = false; 396 // Writes generation progress updates to a socket. 397 bool progress_updates_to_socket = false; 398 bool do_screenshot = false; 399 bool is_screenshot_copied = false; 400 bool is_remote_mode = false; 401 bool show_header_only = false; 402 bool telephony_only = false; 403 bool wifi_only = false; 404 // Trimmed-down version of dumpstate to only include whitelisted logs. 405 bool limited_only = false; 406 // Whether progress updates should be published. 407 bool do_progress_updates = false; 408 // The mode we'll use when calling IDumpstateDevice::dumpstateBoard. 409 // TODO(b/148168577) get rid of the AIDL values, replace them with the HAL values instead. 410 // The HAL is actually an API surface that can be validated, while the AIDL is not (@hide). 411 ::android::hardware::dumpstate::V1_1::DumpstateMode dumpstate_hal_mode = 412 ::android::hardware::dumpstate::V1_1::DumpstateMode::DEFAULT; 413 // File descriptor to output zip file. Takes precedence over out_dir. 414 android::base::unique_fd bugreport_fd; 415 // File descriptor to screenshot file. 416 android::base::unique_fd screenshot_fd; 417 // Custom output directory. 418 std::string out_dir; 419 // Bugreport mode of the bugreport. 420 std::string bugreport_mode; 421 // Command-line arguments as string 422 std::string args; 423 // Notification title and description 424 std::string notification_title; 425 std::string notification_description; 426 427 /* Initializes options from commandline arguments. */ 428 RunStatus Initialize(int argc, char* argv[]); 429 430 /* Initializes options from the requested mode. */ 431 void Initialize(BugreportMode bugreport_mode, const android::base::unique_fd& bugreport_fd, 432 const android::base::unique_fd& screenshot_fd, 433 bool is_screenshot_requested); 434 435 /* Returns true if the options set so far are consistent. */ 436 bool ValidateOptions() const; 437 438 /* Returns if options specified require writing to custom file location */ OutputToCustomFileDumpOptions439 bool OutputToCustomFile() { 440 // Custom location is only honored in limited mode. 441 return limited_only && !out_dir.empty() && bugreport_fd.get() == -1; 442 } 443 }; 444 445 // TODO: initialize fields on constructor 446 // dumpstate id - unique after each device reboot. 447 uint32_t id_; 448 449 // dumpstate pid 450 pid_t pid_; 451 452 // Runtime options. 453 std::unique_ptr<DumpOptions> options_; 454 455 // Last progress that was sent to the listener [0-100]. 456 int last_reported_percent_progress_ = 0; 457 458 // Whether it should take an screenshot earlier in the process. 459 bool do_early_screenshot_ = false; 460 461 // This is set to true when the trace snapshot request in the early call to 462 // MaybeSnapshotSystemTrace(). When this is true, the later stages of 463 // dumpstate will append the trace to the zip archive. 464 bool has_system_trace_ = false; 465 466 std::unique_ptr<Progress> progress_; 467 468 // When set, defines a socket file-descriptor use to report progress to bugreportz 469 // or to stream the zipped file to. 470 int control_socket_fd_ = -1; 471 472 // Bugreport format version; 473 std::string version_ = VERSION_CURRENT; 474 475 time_t now_; 476 477 // Base name (without suffix or extensions) of the bugreport files, typically 478 // `bugreport-BUILD_ID`. 479 std::string base_name_; 480 481 // Name is the suffix part of the bugreport files - it's typically the date, 482 // but it could be changed by the user.. 483 std::string name_; 484 485 std::string bugreport_internal_dir_ = DUMPSTATE_DIRECTORY; 486 487 // Full path of the temporary file containing the bugreport, inside bugreport_internal_dir_. 488 // At the very end this file is pulled into the zip file. 489 std::string tmp_path_; 490 491 // Full path of the file containing the dumpstate logs, inside bugreport_internal_dir_. 492 // This is useful for debugging. 493 std::string log_path_; 494 495 // Full path of the bugreport file, be it zip or text, inside bugreport_internal_dir_. 496 std::string path_; 497 498 // Full path of the file containing the screenshot (when requested). 499 std::string screenshot_path_; 500 501 // Pointer to the zipped file. 502 std::unique_ptr<FILE, int (*)(FILE*)> zip_file{nullptr, fclose}; 503 504 // Pointer to the zip structure. 505 std::unique_ptr<ZipWriter> zip_writer_; 506 507 // Binder object listening to progress. 508 android::sp<android::os::IDumpstateListener> listener_; 509 510 // List of open tombstone dump files. 511 std::vector<DumpData> tombstone_data_; 512 513 // List of open ANR dump files. 514 std::vector<DumpData> anr_data_; 515 516 // A thread pool to execute dump tasks simultaneously if the parallel run is enabled. 517 std::unique_ptr<android::os::dumpstate::DumpPool> dump_pool_; 518 519 // A task queue to collect adding zip entry tasks inside dump tasks if the 520 // parallel run is enabled. 521 std::unique_ptr<android::os::dumpstate::TaskQueue> zip_entry_tasks_; 522 523 // A callback to IncidentCompanion service, which checks user consent for sharing the 524 // bugreport with the calling app. If the user has not responded yet to the dialog it will 525 // be neither confirmed nor denied. 526 class ConsentCallback : public android::os::BnIncidentAuthListener { 527 public: 528 ConsentCallback(); 529 android::binder::Status onReportApproved() override; 530 android::binder::Status onReportDenied() override; 531 532 enum ConsentResult { APPROVED, DENIED, UNAVAILABLE }; 533 534 ConsentResult getResult(); 535 536 // Returns the time since creating this listener 537 uint64_t getElapsedTimeMs() const; 538 539 private: 540 ConsentResult result_; 541 uint64_t start_time_; 542 std::mutex lock_; 543 }; 544 545 private: 546 RunStatus RunInternal(int32_t calling_uid, const std::string& calling_package); 547 548 RunStatus DumpstateDefaultAfterCritical(); 549 550 void MaybeTakeEarlyScreenshot(); 551 void MaybeSnapshotSystemTrace(); 552 void MaybeSnapshotWinTrace(); 553 554 void onUiIntensiveBugreportDumpsFinished(int32_t calling_uid); 555 556 void MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package); 557 558 // Removes the in progress files output files (tmp file, zip/txt file, screenshot), 559 // but leaves the log file alone. 560 void CleanupTmpFiles(); 561 562 // Create the thread pool to enable the parallel run function. 563 void EnableParallelRunIfNeeded(); 564 void ShutdownDumpPool(); 565 566 RunStatus HandleUserConsentDenied(); 567 568 // Copies bugreport artifacts over to the caller's directories provided there is user consent or 569 // called by Shell. 570 RunStatus CopyBugreportIfUserConsented(int32_t calling_uid); 571 572 std::function<int(const char *)> open_socket_fn_; 573 574 // Used by GetInstance() only. 575 explicit Dumpstate(const std::string& version = VERSION_CURRENT); 576 577 android::sp<ConsentCallback> consent_callback_; 578 579 std::recursive_mutex mutex_; 580 581 DISALLOW_COPY_AND_ASSIGN(Dumpstate); 582 }; 583 584 // for_each_pid_func = void (*)(int, const char*); 585 // for_each_tid_func = void (*)(int, int, const char*); 586 587 typedef void(for_each_pid_func)(int, const char*); 588 typedef void(for_each_tid_func)(int, int, const char*); 589 590 /* saves the the contents of a file as a long */ 591 int read_file_as_long(const char *path, long int *output); 592 593 /* prints the contents of the fd 594 * fd must have been opened with the flag O_NONBLOCK. 595 */ 596 int dump_file_from_fd(const char *title, const char *path, int fd); 597 598 /* calls skip to gate calling dump_from_fd recursively 599 * in the specified directory. dump_from_fd defaults to 600 * dump_file_from_fd above when set to NULL. skip defaults 601 * to false when set to NULL. dump_from_fd will always be 602 * called with title NULL. 603 */ 604 int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path), 605 int (*dump_from_fd)(const char* title, const char* path, int fd)); 606 607 /* 608 * Redirects 'redirect' to a file indicated by 'path', truncating it. 609 * 610 * Returns true if redirect succeeds. 611 */ 612 bool redirect_to_file(FILE* redirect, char* path); 613 614 /* 615 * Redirects 'redirect' to an existing file indicated by 'path', appending it. 616 * 617 * Returns true if redirect succeeds. 618 */ 619 bool redirect_to_existing_file(FILE* redirect, char* path); 620 621 /* create leading directories, if necessary */ 622 void create_parent_dirs(const char *path); 623 624 /* for each process in the system, run the specified function */ 625 void for_each_pid(for_each_pid_func func, const char *header); 626 627 /* for each thread in the system, run the specified function */ 628 void for_each_tid(for_each_tid_func func, const char *header); 629 630 /* Displays a blocked processes in-kernel wait channel */ 631 void show_wchan(int pid, int tid, const char *name); 632 633 /* Displays a processes times */ 634 void show_showtime(int pid, const char *name); 635 636 /* Runs "showmap" for a process */ 637 void do_showmap(int pid, const char *name); 638 639 /* Gets the dmesg output for the kernel */ 640 void do_dmesg(); 641 642 /* Prints the contents of all the routing tables, both IPv4 and IPv6. */ 643 void dump_route_tables(); 644 645 /* Play a sound via Stagefright */ 646 void play_sound(const char *path); 647 648 /* Checks if a given path is a directory. */ 649 bool is_dir(const char* pathname); 650 651 /** Gets the last modification time of a file, or default time if file is not found. */ 652 time_t get_mtime(int fd, time_t default_mtime); 653 654 /** Gets command-line arguments. */ 655 void format_args(int argc, const char *argv[], std::string *args); 656 657 /** Main entry point for dumpstate. */ 658 int run_main(int argc, char* argv[]); 659 660 #ifdef __cplusplus 661 } 662 #endif 663 664 #endif /* FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_ */ 665