• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
29 #include <android-base/macros.h>
30 #include <android-base/unique_fd.h>
31 #include <android/hardware/dumpstate/1.1/types.h>
32 #include <android/os/BnIncidentAuthListener.h>
33 #include <android/os/IDumpstate.h>
34 #include <android/os/IDumpstateListener.h>
35 #include <utils/StrongPointer.h>
36 #include <ziparchive/zip_writer.h>
37 
38 #include "DumpstateUtil.h"
39 #include "DumpPool.h"
40 #include "TaskQueue.h"
41 
42 // TODO: move everything under this namespace
43 // TODO: and then remove explicitly android::os::dumpstate:: prefixes
44 namespace android {
45 namespace os {
46 
47 struct DumpstateOptions;
48 
49 namespace dumpstate {
50 
51 class DumpstateTest;
52 class ProgressTest;
53 class ZippedBugReportStreamTest;
54 
55 }  // namespace dumpstate
56 }  // namespace os
57 }  // namespace android
58 
59 class ZipWriter;
60 
61 // TODO: remove once moved to HAL
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65 
66 /*
67  * Helper class used to report how long it takes for a section to finish.
68  *
69  * Typical usage:
70  *
71  *    DurationReporter duration_reporter(title);
72  *
73  */
74 class DurationReporter {
75   public:
76     explicit DurationReporter(const std::string& title, bool logcat_only = false,
77                               bool verbose = false, int duration_fd = STDOUT_FILENO);
78 
79     ~DurationReporter();
80 
81   private:
82     std::string title_;
83     bool logcat_only_;
84     bool verbose_;
85     uint64_t started_;
86     int duration_fd_;
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  * "Alias" for the current version.
161  */
162 static std::string VERSION_DEFAULT = "default";
163 
164 /*
165  * Directory used by Dumpstate binary to keep its local files.
166  */
167 static const std::string DUMPSTATE_DIRECTORY = "/bugreports";
168 
169 /*
170  * Structure that contains the information of an open dump file.
171  */
172 struct DumpData {
173     // Path of the file.
174     std::string name;
175 
176     // Open file descriptor for the file.
177     android::base::unique_fd fd;
178 
179     // Modification time of the file.
180     time_t mtime;
181 };
182 
183 /*
184  * Main class driving a bugreport generation.
185  *
186  * Currently, it only contains variables that are accessed externally, but gradually the functions
187  * that are spread accross utils.cpp and dumpstate.cpp will be moved to it.
188  */
189 class Dumpstate {
190     friend class android::os::dumpstate::DumpstateTest;
191     friend class android::os::dumpstate::ZippedBugReportStreamTest;
192 
193   public:
194     enum RunStatus { OK, HELP, INVALID_INPUT, ERROR, USER_CONSENT_DENIED, USER_CONSENT_TIMED_OUT };
195 
196     // The mode under which the bugreport should be run. Each mode encapsulates a few options.
197     enum BugreportMode {
198         BUGREPORT_FULL = android::os::IDumpstate::BUGREPORT_MODE_FULL,
199         BUGREPORT_INTERACTIVE = android::os::IDumpstate::BUGREPORT_MODE_INTERACTIVE,
200         BUGREPORT_REMOTE = android::os::IDumpstate::BUGREPORT_MODE_REMOTE,
201         BUGREPORT_WEAR = android::os::IDumpstate::BUGREPORT_MODE_WEAR,
202         BUGREPORT_TELEPHONY = android::os::IDumpstate::BUGREPORT_MODE_TELEPHONY,
203         BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI,
204         BUGREPORT_ONBOARDING = android::os::IDumpstate::BUGREPORT_MODE_ONBOARDING,
205         BUGREPORT_DEFAULT = android::os::IDumpstate::BUGREPORT_MODE_DEFAULT
206     };
207 
208     // The flags used to customize bugreport requests.
209     enum BugreportFlag {
210         BUGREPORT_USE_PREDUMPED_UI_DATA =
211           android::os::IDumpstate::BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA,
212         BUGREPORT_FLAG_DEFER_CONSENT =
213           android::os::IDumpstate::BUGREPORT_FLAG_DEFER_CONSENT,
214           BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL =
215                     android::os::IDumpstate::BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL
216     };
217 
218     static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
219 
220     static Dumpstate& GetInstance();
221 
222     /* Initialize dumpstate fields before starting bugreport generation */
223     void Initialize();
224 
225     /*
226      * Forks a command, waits for it to finish, and returns its status.
227      *
228      * |title| description of the command printed on `stdout` (or empty to skip
229      * description).
230      * |full_command| array containing the command (first entry) and its arguments.
231      * Must contain at least one element.
232      * |options| optional argument defining the command's behavior.
233      * |out_fd| A fd to support the DumpPool to output results to a temporary
234      * file. Using STDOUT_FILENO if it's not running in the parallel task.
235      */
236     int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
237                    const android::os::dumpstate::CommandOptions& options =
238                        android::os::dumpstate::CommandOptions::DEFAULT,
239                    bool verbose_duration = false, int out_fd = STDOUT_FILENO);
240 
241     /*
242      * Runs `dumpsys` with the given arguments, automatically setting its timeout
243      * (`-T` argument)
244      * according to the command options.
245      *
246      * |title| description of the command printed on `stdout` (or empty to skip
247      * description).
248      * |dumpsys_args| `dumpsys` arguments (except `-t`).
249      * |options| optional argument defining the command's behavior.
250      * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -T` (otherwise it uses the
251      * timeout from `options`)
252      * |out_fd| A fd to support the DumpPool to output results to a temporary
253      * file. Using STDOUT_FILENO if it's not running in the parallel task.
254      */
255     void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args,
256                     const android::os::dumpstate::CommandOptions& options = DEFAULT_DUMPSYS,
257                     long dumpsys_timeout_ms = 0, int out_fd = STDOUT_FILENO);
258 
259     /*
260      * Prints the contents of a file.
261      *
262      * |title| description of the command printed on `stdout` (or empty to skip
263      * description).
264      * |path| location of the file to be dumped.
265      */
266     int DumpFile(const std::string& title, const std::string& path);
267 
268     /*
269      * Adds a new entry to the existing zip file.
270      * */
271     bool AddZipEntry(const std::string& entry_name, const std::string& entry_path);
272 
273     /*
274      * Adds a new entry to the existing zip file.
275      *
276      * |entry_name| destination path of the new entry.
277      * |fd| file descriptor to read from.
278      * |timeout| timeout to terminate the read if not completed. Set
279      * value of 0s (default) to disable timeout.
280      */
281     android::status_t AddZipEntryFromFd(const std::string& entry_name, int fd,
282                                         std::chrono::milliseconds timeout);
283 
284     /*
285      * Adds a text entry to the existing zip file.
286      */
287     bool AddTextZipEntry(const std::string& entry_name, const std::string& content);
288 
289     /*
290      * Adds all files from a directory to the zipped bugreport file.
291      */
292     void AddDir(const std::string& dir, bool recursive);
293 
294     /*
295      * Takes a screenshot and save it to the given `path`.
296      *
297      * If `path` is empty, uses a standard path based on the bugreport name.
298      */
299     void TakeScreenshot(const std::string& path = "");
300 
301     /////////////////////////////////////////////////////////////////////
302     // TODO: members below should be private once refactor is finished //
303     /////////////////////////////////////////////////////////////////////
304 
305     // TODO: temporary method until Dumpstate object is properly set
306     void SetProgress(std::unique_ptr<Progress> progress);
307 
308     // Dumps Dalvik and native stack traces, sets the trace file location to path
309     // if it succeeded.
310     // Note that it returns early if user consent is denied with status USER_CONSENT_DENIED.
311     // Returns OK in all other cases.
312     RunStatus DumpTraces(const char** path);
313 
314     /*
315      * |out_fd| A fd to support the DumpPool to output results to a temporary file.
316      * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO
317      * if it's not running in the parallel task.
318      */
319     void DumpstateBoard(int out_fd = STDOUT_FILENO);
320 
321     /*
322      * Updates the overall progress of the bugreport generation by the given weight increment.
323      */
324     void UpdateProgress(int32_t delta);
325 
326     /* Prints the dumpstate header on `stdout`. */
327     void PrintHeader() const;
328 
329     /*
330      * Adds the temporary report to the existing .zip file, closes the .zip file, and removes the
331      * temporary file.
332      */
333     bool FinishZipFile();
334 
335     /* Constructs a full path inside directory with file name formatted using the given suffix. */
336     std::string GetPath(const std::string& directory, const std::string& suffix) const;
337 
338     /* Constructs a full path inside bugreport_internal_dir_ with file name formatted using the
339      * given suffix. */
340     std::string GetPath(const std::string& suffix) const;
341 
342     /* Returns true if the current version supports priority dump feature. */
343     bool CurrentVersionSupportsPriorityDumps() const;
344 
345     struct DumpOptions;
346 
347     /**
348      * Pre-dump critical UI data, e.g. data stored in short ring buffers that might get lost
349      * by the time the actual bugreport is requested.
350      */
351     void PreDumpUiData();
352 
353     /*
354      * Main entry point for running a complete bugreport.
355      *
356      * Initialize() dumpstate before calling this method.
357      *
358      */
359     RunStatus Run(int32_t calling_uid, const std::string& calling_package);
360 
361     /*
362      * Entry point for retrieving a previous-generated bugreport.
363      *
364      * Initialize() dumpstate before calling this method.
365      */
366     RunStatus Retrieve(int32_t calling_uid, const std::string& calling_package,
367                         const bool keep_bugreport_on_retrieval, const bool skip_user_consent);
368 
369 
370 
371     RunStatus ParseCommandlineAndRun(int argc, char* argv[]);
372 
373     /* Deletes in-progress files */
374     void Cancel();
375 
376     /* Sets runtime options. */
377     void SetOptions(std::unique_ptr<DumpOptions> options);
378 
379     /*
380      * Returns true if user consent is necessary and has been denied.
381      * Consent is only necessary if the caller has asked to copy over the bugreport to a file they
382      * provided.
383      */
384     bool IsUserConsentDenied() const;
385 
386     /*
387      * Returns true if dumpstate is called by bugreporting API
388      */
389     bool CalledByApi() const;
390 
391     /*
392      * Enqueues a task to the dumpstate's TaskQueue if the parallel run is enabled,
393      * otherwise invokes it immediately. The task adds file at path entry_path
394      * as a zip file entry with name entry_name. Unlinks entry_path when done.
395      *
396      * All enqueued tasks will be executed in the dumpstate's FinishZipFile method
397      * before the zip file is finished. Tasks will be cancelled in dumpstate's
398      * ShutdownDumpPool method if they have never been called.
399      */
400     void EnqueueAddZipEntryAndCleanupIfNeeded(const std::string& entry_name,
401             const std::string& entry_path);
402 
403     /*
404      * Structure to hold options that determine the behavior of dumpstate.
405      */
406     struct DumpOptions {
407         bool do_vibrate = true;
408         // Writes bugreport zipped file to a socket.
409         bool stream_to_socket = false;
410         // Writes generation progress updates to a socket.
411         bool progress_updates_to_socket = false;
412         bool do_screenshot = false;
413         bool is_screenshot_copied = false;
414         bool is_consent_deferred = false;
415         bool skip_user_consent = false;
416         bool is_remote_mode = false;
417         bool show_header_only = false;
418         bool telephony_only = false;
419         bool wifi_only = false;
420         bool onboarding_only = false;
421         // Trimmed-down version of dumpstate to only include whitelisted logs.
422         bool limited_only = false;
423         // Whether progress updates should be published.
424         bool do_progress_updates = false;
425         // this is used to derive dumpstate HAL bug report mode
426         // TODO(b/148168577) get rid of the AIDL values, replace them with the HAL values instead.
427         // The HAL is actually an API surface that can be validated, while the AIDL is not (@hide).
428         BugreportMode bugreport_mode = Dumpstate::BugreportMode::BUGREPORT_DEFAULT;
429         // Will use data collected through a previous call to PreDumpUiData().
430         bool use_predumped_ui_data;
431         // File descriptor to output zip file. Takes precedence over out_dir.
432         android::base::unique_fd bugreport_fd;
433         // File descriptor to screenshot file.
434         android::base::unique_fd screenshot_fd;
435         // Custom output directory.
436         std::string out_dir;
437         // Bugreport mode of the bugreport as a string
438         std::string bugreport_mode_string;
439         // Command-line arguments as string
440         std::string args;
441         // Notification title and description
442         std::string notification_title;
443         std::string notification_description;
444 
445         /* Initializes options from commandline arguments. */
446         RunStatus Initialize(int argc, char* argv[]);
447 
448         /* Initializes options from the requested mode. */
449         void Initialize(BugreportMode bugreport_mode, int bugreport_flags,
450                         const android::base::unique_fd& bugreport_fd,
451                         const android::base::unique_fd& screenshot_fd,
452                         bool is_screenshot_requested,
453                         bool skip_user_consent);
454 
455         /* Returns true if the options set so far are consistent. */
456         bool ValidateOptions() const;
457 
458         /* Returns if options specified require writing to custom file location */
OutputToCustomFileDumpOptions459         bool OutputToCustomFile() {
460             // Custom location is only honored in limited mode.
461             return limited_only && !out_dir.empty() && bugreport_fd.get() == -1;
462         }
463     };
464 
465     // TODO: initialize fields on constructor
466     // dumpstate id - unique after each device reboot.
467     uint32_t id_;
468 
469     // dumpstate pid
470     pid_t pid_;
471 
472     // Runtime options.
473     std::unique_ptr<DumpOptions> options_;
474 
475     // Last progress that was sent to the listener [0-100].
476     int last_reported_percent_progress_ = 0;
477 
478     // Whether it should take an screenshot earlier in the process.
479     bool do_early_screenshot_ = false;
480 
481     std::unique_ptr<Progress> progress_;
482 
483     // When set, defines a socket file-descriptor use to report progress to bugreportz
484     // or to stream the zipped file to.
485     int control_socket_fd_ = -1;
486 
487     // Bugreport format version;
488     std::string version_ = VERSION_CURRENT;
489 
490     time_t now_;
491 
492     // Base name (without suffix or extensions) of the bugreport files, typically
493     // `bugreport-BUILD_ID`.
494     std::string base_name_;
495 
496     // Name is the suffix part of the bugreport files - it's typically the date,
497     // but it could be changed by the user..
498     std::string name_;
499 
500     std::string bugreport_internal_dir_ = DUMPSTATE_DIRECTORY;
501 
502     // Full path of the temporary file containing the bugreport, inside bugreport_internal_dir_.
503     // At the very end this file is pulled into the zip file.
504     std::string tmp_path_;
505 
506     // Full path of the file containing the dumpstate logs, inside bugreport_internal_dir_.
507     // This is useful for debugging.
508     std::string log_path_;
509 
510     // Full path of the bugreport zip file inside bugreport_internal_dir_.
511     std::string path_;
512 
513     // Full path of the file containing the screenshot (when requested).
514     std::string screenshot_path_;
515 
516     // Pointer to the zipped file.
517     std::unique_ptr<FILE, int (*)(FILE*)> zip_file{nullptr, fclose};
518 
519     // Pointer to the zip structure.
520     std::unique_ptr<ZipWriter> zip_writer_;
521 
522     // Binder object listening to progress.
523     android::sp<android::os::IDumpstateListener> listener_;
524 
525     // List of open tombstone dump files.
526     std::vector<DumpData> tombstone_data_;
527 
528     // List of open ANR dump files.
529     std::vector<DumpData> anr_data_;
530 
531     // List of open Java traces files in the anr directory.
532     std::vector<DumpData> anr_trace_data_;
533 
534     // List of open shutdown checkpoint files.
535     std::vector<DumpData> shutdown_checkpoints_;
536 
537     // A thread pool to execute dump tasks simultaneously if the parallel run is enabled.
538     std::unique_ptr<android::os::dumpstate::DumpPool> dump_pool_;
539 
540     // A task queue to collect adding zip entry tasks inside dump tasks if the
541     // parallel run is enabled.
542     std::unique_ptr<android::os::dumpstate::TaskQueue> zip_entry_tasks_;
543 
544     // A callback to IncidentCompanion service, which checks user consent for sharing the
545     // bugreport with the calling app. If the user has not responded yet to the dialog it will
546     // be neither confirmed nor denied.
547     class ConsentCallback : public android::os::BnIncidentAuthListener {
548       public:
549         ConsentCallback();
550         android::binder::Status onReportApproved() override;
551         android::binder::Status onReportDenied() override;
552 
553         enum ConsentResult { APPROVED, DENIED, UNAVAILABLE };
554 
555         ConsentResult getResult();
556 
557         // Returns the time since creating this listener
558         uint64_t getElapsedTimeMs() const;
559 
560       private:
561         ConsentResult result_;
562         uint64_t start_time_;
563         std::mutex lock_;
564     };
565 
566   private:
567     RunStatus RunInternal(int32_t calling_uid, const std::string& calling_package);
568     RunStatus RetrieveInternal(int32_t calling_uid, const std::string& calling_package,
569                                 const bool keep_bugreport_on_retrieval,
570                                 const bool skip_user_consent);
571 
572     RunStatus DumpstateDefaultAfterCritical();
573     RunStatus dumpstate();
574 
575     void MaybeTakeEarlyScreenshot();
576     std::future<std::string> MaybeSnapshotSystemTraceAsync();
577     void MaybeWaitForSnapshotSystemTrace(std::future<std::string> task);
578     void MaybeSnapshotUiTraces();
579     void MaybeAddUiTracesToZip();
580 
581     void onUiIntensiveBugreportDumpsFinished(int32_t calling_uid);
582 
583     void MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package);
584 
585     // Removes the in progress files output files (tmp file, zip/txt file, screenshot),
586     // but leaves the log file alone.
587     void CleanupTmpFiles();
588 
589     // Create the thread pool to enable the parallel run function.
590     void EnableParallelRunIfNeeded();
591     void ShutdownDumpPool();
592 
593     RunStatus HandleUserConsentDenied();
594 
595     void HandleRunStatus(RunStatus status);
596 
597     // Copies bugreport artifacts over to the caller's directories provided there is user consent or
598     // called by Shell.
599     RunStatus CopyBugreportIfUserConsented(int32_t calling_uid);
600 
601     std::function<int(const char *)> open_socket_fn_;
602 
603     // Used by GetInstance() only.
604     explicit Dumpstate(const std::string& version = VERSION_CURRENT);
605 
606     android::sp<ConsentCallback> consent_callback_;
607 
608     std::recursive_mutex mutex_;
609 
610     DISALLOW_COPY_AND_ASSIGN(Dumpstate);
611 };
612 
613 // for_each_pid_func = void (*)(int, const char*);
614 // for_each_tid_func = void (*)(int, int, const char*);
615 
616 typedef void(for_each_pid_func)(int, const char*);
617 typedef void(for_each_tid_func)(int, int, const char*);
618 
619 /* saves the the contents of a file as a long */
620 int read_file_as_long(const char *path, long int *output);
621 
622 /* prints the contents of the fd
623  * fd must have been opened with the flag O_NONBLOCK.
624  */
625 int dump_file_from_fd(const char *title, const char *path, int fd);
626 
627 /* calls skip to gate calling dump_from_fd recursively
628  * in the specified directory. dump_from_fd defaults to
629  * dump_file_from_fd above when set to NULL. skip defaults
630  * to false when set to NULL. dump_from_fd will always be
631  * called with title NULL.
632  */
633 int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
634                int (*dump_from_fd)(const char* title, const char* path, int fd));
635 
636 /*
637  * Redirects 'redirect' to a file indicated by 'path', truncating it.
638  *
639  * Returns true if redirect succeeds.
640  */
641 bool redirect_to_file(FILE* redirect, char* path);
642 
643 /*
644  * Redirects 'redirect' to an existing file indicated by 'path', appending it.
645  *
646  * Returns true if redirect succeeds.
647  */
648 bool redirect_to_existing_file(FILE* redirect, char* path);
649 
650 /* create leading directories, if necessary */
651 void create_parent_dirs(const char *path);
652 
653 /* for each process in the system, run the specified function */
654 void for_each_pid(for_each_pid_func func, const char *header);
655 
656 /* for each thread in the system, run the specified function */
657 void for_each_tid(for_each_tid_func func, const char *header);
658 
659 /* Displays a blocked processes in-kernel wait channel */
660 void show_wchan(int pid, int tid, const char *name);
661 
662 /* Displays a processes times */
663 void show_showtime(int pid, const char *name);
664 
665 /* Gets the dmesg output for the kernel */
666 void do_dmesg();
667 
668 /* Prints the contents of all the routing tables, both IPv4 and IPv6. */
669 void dump_route_tables();
670 
671 /* Dump subdirectories of cgroupfs if the corresponding process is frozen */
672 void dump_frozen_cgroupfs();
673 
674 /* Play a sound via Stagefright */
675 void play_sound(const char *path);
676 
677 /* Checks if a given path is a directory. */
678 bool is_dir(const char* pathname);
679 
680 /** Gets the last modification time of a file, or default time if file is not found. */
681 time_t get_mtime(int fd, time_t default_mtime);
682 
683 /** Gets command-line arguments. */
684 void format_args(int argc, const char *argv[], std::string *args);
685 
686 /** Main entry point for dumpstate. */
687 int run_main(int argc, char* argv[]);
688 
689 #ifdef __cplusplus
690 }
691 #endif
692 
693 #endif /* FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_ */
694