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