• 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 <android-base/macros.h>
29 #include <android/os/IDumpstateListener.h>
30 #include <utils/StrongPointer.h>
31 #include <ziparchive/zip_writer.h>
32 
33 #include "DumpstateUtil.h"
34 
35 // Workaround for const char *args[MAX_ARGS_ARRAY_SIZE] variables until they're converted to
36 // std::vector<std::string>
37 // TODO: remove once not used
38 #define MAX_ARGS_ARRAY_SIZE 1000
39 
40 // TODO: move everything under this namespace
41 // TODO: and then remove explicitly android::os::dumpstate:: prefixes
42 namespace android {
43 namespace os {
44 namespace dumpstate {
45 
46 class DumpstateTest;
47 class ProgressTest;
48 
49 }  // namespace dumpstate
50 }  // namespace os
51 }  // namespace android
52 
53 class ZipWriter;
54 
55 // TODO: remove once moved to HAL
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
60 /*
61  * Helper class used to report how long it takes for a section to finish.
62  *
63  * Typical usage:
64  *
65  *    DurationReporter duration_reporter(title);
66  *
67  */
68 class DurationReporter {
69   public:
70     DurationReporter(const std::string& title, bool log_only = false);
71 
72     ~DurationReporter();
73 
74   private:
75     std::string title_;
76     bool log_only_;
77     uint64_t started_;
78 
79     DISALLOW_COPY_AND_ASSIGN(DurationReporter);
80 };
81 
82 /*
83  * Keeps track of current progress and estimated max, saving stats on file to tune up future runs.
84  *
85  * Each `dumpstate` section contributes to the total weight by an individual weight, so the overall
86  * progress can be calculated by dividing the estimate max progress by the current progress.
87  *
88  * The estimated max progress is initially set to a value (`kDefaultMax) defined empirically, but
89  * it's adjusted after each dumpstate run by storing the average duration in a file.
90  *
91  */
92 class Progress {
93     friend class android::os::dumpstate::ProgressTest;
94     friend class android::os::dumpstate::DumpstateTest;
95 
96   public:
97     /*
98      * Default estimation of the max duration of a bugreport generation.
99      *
100      * It does not need to match the exact sum of all sections, but ideally it should to be slight
101      * more than such sum: a value too high will cause the bugreport to finish before the user
102      * expected (for example, jumping from 70% to 100%), while a value too low will cause the
103      * progress to get stuck at an almost-finished value (like 99%) for a while.
104      *
105      * This constant is only used when the average duration from previous runs cannot be used.
106      */
107     static const int kDefaultMax;
108 
109     Progress(const std::string& path = "");
110 
111     // Gets the current progress.
112     int32_t Get() const;
113 
114     // Gets the current estimated max progress.
115     int32_t GetMax() const;
116 
117     // Gets the initial estimated max progress.
118     int32_t GetInitialMax() const;
119 
120     // Increments progress (ignored if not positive).
121     // Returns `true` if the max progress increased as well.
122     bool Inc(int32_t delta);
123 
124     // Persist the stats.
125     void Save();
126 
127     void Dump(int fd, const std::string& prefix) const;
128 
129   private:
130     Progress(int32_t initial_max, float growth_factor,
131              const std::string& path = "");                                // Used by test cases.
132     Progress(int32_t initial_max, int32_t progress, float growth_factor);  // Used by test cases.
133     void Load();
134     int32_t initial_max_;
135     int32_t progress_;
136     int32_t max_;
137     float growth_factor_;
138     int32_t n_runs_;
139     int32_t average_max_;
140     const std::string& path_;
141 };
142 
143 /*
144  * List of supported zip format versions.
145  *
146  * See bugreport-format.md for more info.
147  */
148 static std::string VERSION_CURRENT = "1.0";
149 
150 /*
151  * Temporary version that adds a anr-traces.txt entry. Once tools support it, the current version
152  * will be bumped to 2.0-dev-1.
153  */
154 static std::string VERSION_SPLIT_ANR = "2.0-dev-1";
155 
156 /*
157  * "Alias" for the current version.
158  */
159 static std::string VERSION_DEFAULT = "default";
160 
161 /*
162  * Main class driving a bugreport generation.
163  *
164  * Currently, it only contains variables that are accessed externally, but gradually the functions
165  * that are spread accross utils.cpp and dumpstate.cpp will be moved to it.
166  */
167 class Dumpstate {
168     friend class DumpstateTest;
169 
170   public:
171     static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
172 
173     static Dumpstate& GetInstance();
174 
175     /* Checkes whether dumpstate is generating a zipped bugreport. */
176     bool IsZipping() const;
177 
178     /*
179      * Forks a command, waits for it to finish, and returns its status.
180      *
181      * |title| description of the command printed on `stdout` (or empty to skip
182      * description).
183      * |full_command| array containing the command (first entry) and its arguments.
184      * Must contain at least one element.
185      * |options| optional argument defining the command's behavior.
186      */
187     int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
188                    const android::os::dumpstate::CommandOptions& options =
189                        android::os::dumpstate::CommandOptions::DEFAULT);
190 
191     /*
192      * Runs `dumpsys` with the given arguments, automatically setting its timeout
193      * (`-t` argument)
194      * according to the command options.
195      *
196      * |title| description of the command printed on `stdout` (or empty to skip
197      * description).
198      * |dumpsys_args| `dumpsys` arguments (except `-t`).
199      * |options| optional argument defining the command's behavior.
200      * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -t` (otherwise it uses the
201      * timeout from `options`)
202      */
203     void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args,
204                     const android::os::dumpstate::CommandOptions& options = DEFAULT_DUMPSYS,
205                     long dumpsys_timeout = 0);
206 
207     /*
208      * Prints the contents of a file.
209      *
210      * |title| description of the command printed on `stdout` (or empty to skip
211      * description).
212      * |path| location of the file to be dumped.
213      */
214     int DumpFile(const std::string& title, const std::string& path);
215 
216     /*
217      * Adds a new entry to the existing zip file.
218      * */
219     bool AddZipEntry(const std::string& entry_name, const std::string& entry_path);
220 
221     /*
222      * Adds a new entry to the existing zip file.
223      */
224     bool AddZipEntryFromFd(const std::string& entry_name, int fd);
225 
226     /*
227      * Adds a text entry entry to the existing zip file.
228      */
229     bool AddTextZipEntry(const std::string& entry_name, const std::string& content);
230 
231     /*
232      * Adds all files from a directory to the zipped bugreport file.
233      */
234     void AddDir(const std::string& dir, bool recursive);
235 
236     /*
237      * Takes a screenshot and save it to the given `path`.
238      *
239      * If `path` is empty, uses a standard path based on the bugreport name.
240      */
241     void TakeScreenshot(const std::string& path = "");
242 
243     /////////////////////////////////////////////////////////////////////
244     // TODO: members below should be private once refactor is finished //
245     /////////////////////////////////////////////////////////////////////
246 
247     // TODO: temporary method until Dumpstate object is properly set
248     void SetProgress(std::unique_ptr<Progress> progress);
249 
250     void DumpstateBoard();
251 
252     /*
253      * Updates the overall progress of the bugreport generation by the given weight increment.
254      */
255     void UpdateProgress(int32_t delta);
256 
257     /* Prints the dumpstate header on `stdout`. */
258     void PrintHeader() const;
259 
260     /*
261      * Adds the temporary report to the existing .zip file, closes the .zip file, and removes the
262      * temporary file.
263      */
264     bool FinishZipFile();
265 
266     /* Gets the path of a bugreport file with the given suffix. */
267     std::string GetPath(const std::string& suffix) const;
268 
269     // TODO: initialize fields on constructor
270 
271     // dumpstate id - unique after each device reboot.
272     uint32_t id_;
273 
274     // dumpstate pid
275     pid_t pid_;
276 
277     // Whether progress updates should be published.
278     bool update_progress_ = false;
279 
280     // How frequently the progess should be updated;the listener will only be notificated when the
281     // delta from the previous update is more than the threshold.
282     int32_t update_progress_threshold_ = 100;
283 
284     // Last progress that triggered a listener updated
285     int32_t last_updated_progress_;
286 
287     // Whether it should take an screenshot earlier in the process.
288     bool do_early_screenshot_ = false;
289 
290     std::unique_ptr<Progress> progress_;
291 
292     // When set, defines a socket file-descriptor use to report progress to bugreportz.
293     int control_socket_fd_ = -1;
294 
295     // Bugreport format version;
296     std::string version_ = VERSION_CURRENT;
297 
298     // Command-line arguments as string
299     std::string args_;
300 
301     // Extra options passed as system property.
302     std::string extra_options_;
303 
304     // Full path of the directory where the bugreport files will be written.
305     std::string bugreport_dir_;
306 
307     // Full path of the temporary file containing the screenshot (when requested).
308     std::string screenshot_path_;
309 
310     time_t now_;
311 
312     // Base name (without suffix or extensions) of the bugreport files, typically
313     // `bugreport-BUILD_ID`.
314     std::string base_name_;
315 
316     // Name is the suffix part of the bugreport files - it's typically the date (when invoked with
317     // `-d`), but it could be changed by the user..
318     std::string name_;
319 
320     // Full path of the temporary file containing the bugreport.
321     std::string tmp_path_;
322 
323     // Full path of the file containing the dumpstate logs.
324     std::string log_path_;
325 
326     // Pointer to the actual path, be it zip or text.
327     std::string path_;
328 
329     // Pointer to the zipped file.
330     std::unique_ptr<FILE, int (*)(FILE*)> zip_file{nullptr, fclose};
331 
332     // Pointer to the zip structure.
333     std::unique_ptr<ZipWriter> zip_writer_;
334 
335     // Binder object listing to progress.
336     android::sp<android::os::IDumpstateListener> listener_;
337     std::string listener_name_;
338 
339     // Notification title and description
340     std::string notification_title;
341     std::string notification_description;
342 
343   private:
344     // Used by GetInstance() only.
345     Dumpstate(const std::string& version = VERSION_CURRENT);
346 
347     DISALLOW_COPY_AND_ASSIGN(Dumpstate);
348 };
349 
350 // for_each_pid_func = void (*)(int, const char*);
351 // for_each_tid_func = void (*)(int, int, const char*);
352 
353 typedef void(for_each_pid_func)(int, const char*);
354 typedef void(for_each_tid_func)(int, int, const char*);
355 
356 /* saves the the contents of a file as a long */
357 int read_file_as_long(const char *path, long int *output);
358 
359 /* prints the contents of the fd
360  * fd must have been opened with the flag O_NONBLOCK.
361  */
362 int dump_file_from_fd(const char *title, const char *path, int fd);
363 
364 /* calls skip to gate calling dump_from_fd recursively
365  * in the specified directory. dump_from_fd defaults to
366  * dump_file_from_fd above when set to NULL. skip defaults
367  * to false when set to NULL. dump_from_fd will always be
368  * called with title NULL.
369  */
370 int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
371                int (*dump_from_fd)(const char* title, const char* path, int fd));
372 
373 /** opens a socket and returns its file descriptor */
374 int open_socket(const char *service);
375 
376 /* redirect output to a service control socket */
377 void redirect_to_socket(FILE *redirect, const char *service);
378 
379 /* redirect output to a new file */
380 void redirect_to_file(FILE *redirect, char *path);
381 
382 /* redirect output to an existing file */
383 void redirect_to_existing_file(FILE *redirect, char *path);
384 
385 /* create leading directories, if necessary */
386 void create_parent_dirs(const char *path);
387 
388 /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
389 const char *dump_traces();
390 
391 /* for each process in the system, run the specified function */
392 void for_each_pid(for_each_pid_func func, const char *header);
393 
394 /* for each thread in the system, run the specified function */
395 void for_each_tid(for_each_tid_func func, const char *header);
396 
397 /* Displays a blocked processes in-kernel wait channel */
398 void show_wchan(int pid, int tid, const char *name);
399 
400 /* Displays a processes times */
401 void show_showtime(int pid, const char *name);
402 
403 /* Runs "showmap" for a process */
404 void do_showmap(int pid, const char *name);
405 
406 /* Gets the dmesg output for the kernel */
407 void do_dmesg();
408 
409 /* Prints the contents of all the routing tables, both IPv4 and IPv6. */
410 void dump_route_tables();
411 
412 /* Play a sound via Stagefright */
413 void play_sound(const char *path);
414 
415 /* Checks if a given path is a directory. */
416 bool is_dir(const char* pathname);
417 
418 /** Gets the last modification time of a file, or default time if file is not found. */
419 time_t get_mtime(int fd, time_t default_mtime);
420 
421 /* Dumps eMMC Extended CSD data. */
422 void dump_emmc_ecsd(const char *ext_csd_path);
423 
424 /** Gets command-line arguments. */
425 void format_args(int argc, const char *argv[], std::string *args);
426 
427 #ifdef __cplusplus
428 }
429 #endif
430 
431 #endif /* FRAMEWORK_NATIVE_CMD_DUMPSTATE_H_ */
432