Home | History | Annotate | Download | only in crash_reporter
      1 /*
      2  * Copyright (C) 2012 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 CRASH_REPORTER_CRASH_COLLECTOR_H_
     18 #define CRASH_REPORTER_CRASH_COLLECTOR_H_
     19 
     20 #include <sys/stat.h>
     21 
     22 #include <map>
     23 #include <string>
     24 
     25 #include <base/files/file_path.h>
     26 #include <base/macros.h>
     27 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     28 
     29 // User crash collector.
     30 class CrashCollector {
     31  public:
     32   typedef void (*CountCrashFunction)();
     33   typedef bool (*IsFeedbackAllowedFunction)();
     34 
     35   CrashCollector();
     36 
     37   virtual ~CrashCollector();
     38 
     39   // Initialize the crash collector for detection of crashes, given a
     40   // crash counting function, and metrics collection enabled oracle.
     41   void Initialize(CountCrashFunction count_crash,
     42                   IsFeedbackAllowedFunction is_metrics_allowed);
     43 
     44  protected:
     45   friend class CrashCollectorTest;
     46   FRIEND_TEST(ChromeCollectorTest, HandleCrash);
     47   FRIEND_TEST(CrashCollectorTest, CheckHasCapacityCorrectBasename);
     48   FRIEND_TEST(CrashCollectorTest, CheckHasCapacityStrangeNames);
     49   FRIEND_TEST(CrashCollectorTest, CheckHasCapacityUsual);
     50   FRIEND_TEST(CrashCollectorTest, GetCrashDirectoryInfo);
     51   FRIEND_TEST(CrashCollectorTest, GetCrashPath);
     52   FRIEND_TEST(CrashCollectorTest, GetLogContents);
     53   FRIEND_TEST(CrashCollectorTest, ForkExecAndPipe);
     54   FRIEND_TEST(CrashCollectorTest, FormatDumpBasename);
     55   FRIEND_TEST(CrashCollectorTest, Initialize);
     56   FRIEND_TEST(CrashCollectorTest, MetaData);
     57   FRIEND_TEST(CrashCollectorTest, Sanitize);
     58   FRIEND_TEST(CrashCollectorTest, WriteNewFile);
     59   FRIEND_TEST(ForkExecAndPipeTest, Basic);
     60   FRIEND_TEST(ForkExecAndPipeTest, NonZeroReturnValue);
     61   FRIEND_TEST(ForkExecAndPipeTest, BadOutputFile);
     62   FRIEND_TEST(ForkExecAndPipeTest, ExistingOutputFile);
     63   FRIEND_TEST(ForkExecAndPipeTest, BadExecutable);
     64   FRIEND_TEST(ForkExecAndPipeTest, StderrCaptured);
     65   FRIEND_TEST(ForkExecAndPipeTest, NULLParam);
     66   FRIEND_TEST(ForkExecAndPipeTest, NoParams);
     67   FRIEND_TEST(ForkExecAndPipeTest, SegFaultHandling);
     68 
     69   // Set maximum enqueued crashes in a crash directory.
     70   static const int kMaxCrashDirectorySize;
     71 
     72   // Writes |data| of |size| to |filename|, which must be a new file.
     73   // If the file already exists or writing fails, return a negative value.
     74   // Otherwise returns the number of bytes written.
     75   int WriteNewFile(const base::FilePath &filename, const char *data, int size);
     76 
     77   // Return a filename that has only [a-z0-1_] characters by mapping
     78   // all others into '_'.
     79   std::string Sanitize(const std::string &name);
     80 
     81   // For testing, set the directory always returned by
     82   // GetCreatedCrashDirectoryByEuid.
     83   void ForceCrashDirectory(const base::FilePath &forced_directory) {
     84     forced_crash_directory_ = forced_directory;
     85   }
     86 
     87   base::FilePath GetCrashDirectoryInfo(mode_t *mode,
     88                                        uid_t *directory_owner,
     89                                        gid_t *directory_group);
     90   bool GetUserInfoFromName(const std::string &name,
     91                            uid_t *uid,
     92                            gid_t *gid);
     93 
     94   // Determines the crash directory for given euid, and creates the
     95   // directory if necessary with appropriate permissions.  If
     96   // |out_of_capacity| is not nullptr, it is set to indicate if the call
     97   // failed due to not having capacity in the crash directory. Returns
     98   // true whether or not directory needed to be created, false on any
     99   // failure.  If the crash directory is at capacity, returns false.
    100   bool GetCreatedCrashDirectoryByEuid(uid_t euid,
    101                                       base::FilePath *crash_file_path,
    102                                       bool *out_of_capacity);
    103 
    104   // Format crash name based on components.
    105   std::string FormatDumpBasename(const std::string &exec_name,
    106                                  time_t timestamp,
    107                                  pid_t pid);
    108 
    109   // Create a file path to a file in |crash_directory| with the given
    110   // |basename| and |extension|.
    111   base::FilePath GetCrashPath(const base::FilePath &crash_directory,
    112                               const std::string &basename,
    113                               const std::string &extension);
    114 
    115   base::FilePath GetProcessPath(pid_t pid);
    116   bool GetSymlinkTarget(const base::FilePath &symlink,
    117                         base::FilePath *target);
    118   bool GetExecutableBaseNameFromPid(pid_t pid,
    119                                     std::string *base_name);
    120 
    121   // Check given crash directory still has remaining capacity for another
    122   // crash.
    123   bool CheckHasCapacity(const base::FilePath &crash_directory);
    124 
    125   // Write a log applicable to |exec_name| to |output_file| based on the
    126   // log configuration file at |config_path|.
    127   bool GetLogContents(const base::FilePath &config_path,
    128                       const std::string &exec_name,
    129                       const base::FilePath &output_file);
    130 
    131   // Add non-standard meta data to the crash metadata file.  Call
    132   // before calling WriteCrashMetaData.  Key must not contain "=" or
    133   // "\n" characters.  Value must not contain "\n" characters.
    134   void AddCrashMetaData(const std::string &key, const std::string &value);
    135 
    136   // Add a file to be uploaded to the crash reporter server. The file must
    137   // persist until the crash report is sent; ideally it should live in the same
    138   // place as the .meta file, so it can be cleaned up automatically.
    139   void AddCrashMetaUploadFile(const std::string &key, const std::string &path);
    140 
    141   // Add non-standard meta data to the crash metadata file.
    142   // Data added though this call will be uploaded to the crash reporter server,
    143   // appearing as a form field.
    144   void AddCrashMetaUploadData(const std::string &key, const std::string &value);
    145 
    146   // Write a file of metadata about crash.
    147   void WriteCrashMetaData(const base::FilePath &meta_path,
    148                           const std::string &exec_name,
    149                           const std::string &payload_path);
    150 
    151   // Returns true if the a crash test is currently running.
    152   bool IsCrashTestInProgress();
    153   // Returns true if we should consider ourselves to be running on a
    154   // developer image.
    155   bool IsDeveloperImage();
    156 
    157   CountCrashFunction count_crash_function_;
    158   IsFeedbackAllowedFunction is_feedback_allowed_function_;
    159   std::string extra_metadata_;
    160   base::FilePath forced_crash_directory_;
    161   base::FilePath log_config_path_;
    162 
    163  private:
    164   DISALLOW_COPY_AND_ASSIGN(CrashCollector);
    165 };
    166 
    167 #endif  // CRASH_REPORTER_CRASH_COLLECTOR_H_
    168