blob: 7261ed413be514a3afe3423901d67b48148b5c76 [file] [log] [blame]
Steve Fung6c34c252015-08-20 00:27:30 -07001/*
2 * Copyright (C) 2010 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 */
Chris Sosae4a86032010-06-16 17:08:34 -070016
Ben Chan7e776902014-06-18 13:19:51 -070017#ifndef CRASH_REPORTER_USER_COLLECTOR_H_
18#define CRASH_REPORTER_USER_COLLECTOR_H_
Chris Sosae4a86032010-06-16 17:08:34 -070019
20#include <string>
Ken Mixter2953c3a2010-10-18 14:42:20 -070021#include <vector>
Chris Sosae4a86032010-06-16 17:08:34 -070022
Ben Chan7e776902014-06-18 13:19:51 -070023#include <base/files/file_path.h>
Ben Chan895fa5d2014-09-02 20:58:20 -070024#include <base/macros.h>
Ben Chan7e776902014-06-18 13:19:51 -070025#include <gtest/gtest_prod.h> // for FRIEND_TEST
26
Steve Fung129bea52015-07-23 13:11:15 -070027#include "crash_collector.h"
Chris Sosae4a86032010-06-16 17:08:34 -070028
Ken Mixter03403162010-08-18 15:23:16 -070029class SystemLogging;
Chris Sosae4a86032010-06-16 17:08:34 -070030
31// User crash collector.
Ken Mixter03403162010-08-18 15:23:16 -070032class UserCollector : public CrashCollector {
Chris Sosae4a86032010-06-16 17:08:34 -070033 public:
Chris Sosae4a86032010-06-16 17:08:34 -070034 UserCollector();
35
36 // Initialize the user crash collector for detection of crashes,
37 // given a crash counting function, the path to this executable,
38 // metrics collection enabled oracle, and system logger facility.
Ken Mixter777484c2010-07-23 16:22:44 -070039 // Crash detection/reporting is not enabled until Enable is called.
40 // |generate_diagnostics| is used to indicate whether or not to try
41 // to generate a minidump from crashes.
Chris Sosae4a86032010-06-16 17:08:34 -070042 void Initialize(CountCrashFunction count_crash,
43 const std::string &our_path,
44 IsFeedbackAllowedFunction is_metrics_allowed,
Steve Fungd6169a22014-08-11 15:52:23 -070045 bool generate_diagnostics,
46 bool core2md_failure,
47 bool directory_failure,
48 const std::string &filter_in);
Chris Sosae4a86032010-06-16 17:08:34 -070049
Ben Chanefec0b32014-08-12 08:52:11 -070050 ~UserCollector() override;
Chris Sosae4a86032010-06-16 17:08:34 -070051
52 // Enable collection.
53 bool Enable() { return SetUpInternal(true); }
54
55 // Disable collection.
56 bool Disable() { return SetUpInternal(false); }
57
Ken Mixter777484c2010-07-23 16:22:44 -070058 // Handle a specific user crash. Returns true on success.
Ken Mixter1b8fe012011-01-25 13:33:05 -080059 bool HandleCrash(const std::string &crash_attributes,
60 const char *force_exec);
Chris Sosae4a86032010-06-16 17:08:34 -070061
Chris Sosae4a86032010-06-16 17:08:34 -070062 private:
63 friend class UserCollectorTest;
Ken Mixter777484c2010-07-23 16:22:44 -070064 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPath);
65 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPid);
66 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesOK);
Ken Mixterd49d3622011-02-09 18:23:00 -080067 FRIEND_TEST(UserCollectorTest, GetExecutableBaseNameFromPid);
Ben Chanf13bb582012-01-06 08:22:07 -080068 FRIEND_TEST(UserCollectorTest, GetFirstLineWithPrefix);
Ken Mixter777484c2010-07-23 16:22:44 -070069 FRIEND_TEST(UserCollectorTest, GetIdFromStatus);
Ben Chanf13bb582012-01-06 08:22:07 -080070 FRIEND_TEST(UserCollectorTest, GetStateFromStatus);
Ken Mixter777484c2010-07-23 16:22:44 -070071 FRIEND_TEST(UserCollectorTest, GetProcessPath);
72 FRIEND_TEST(UserCollectorTest, GetSymlinkTarget);
73 FRIEND_TEST(UserCollectorTest, GetUserInfoFromName);
Ken Mixter1b8fe012011-01-25 13:33:05 -080074 FRIEND_TEST(UserCollectorTest, ParseCrashAttributes);
Ken Mixter5d3a1a22011-03-16 12:47:20 -070075 FRIEND_TEST(UserCollectorTest, ShouldDumpChromeOverridesDeveloperImage);
76 FRIEND_TEST(UserCollectorTest, ShouldDumpDeveloperImageOverridesConsent);
77 FRIEND_TEST(UserCollectorTest, ShouldDumpUseConsentProductionImage);
Ben Chanf13bb582012-01-06 08:22:07 -080078 FRIEND_TEST(UserCollectorTest, ValidateProcFiles);
Ben Chan6e709a12012-02-29 12:10:44 -080079 FRIEND_TEST(UserCollectorTest, ValidateCoreFile);
Ken Mixter777484c2010-07-23 16:22:44 -070080
81 // Enumeration to pass to GetIdFromStatus. Must match the order
82 // that the kernel lists IDs in the status file.
83 enum IdKind {
84 kIdReal = 0, // uid and gid
85 kIdEffective = 1, // euid and egid
86 kIdSet = 2, // suid and sgid
87 kIdFileSystem = 3, // fsuid and fsgid
88 kIdMax
89 };
Chris Sosae4a86032010-06-16 17:08:34 -070090
Ben Chan6e709a12012-02-29 12:10:44 -080091 enum ErrorType {
92 kErrorNone,
93 kErrorSystemIssue,
94 kErrorReadCoreData,
95 kErrorUnusableProcFiles,
96 kErrorInvalidCoreFile,
97 kErrorUnsupported32BitCoreFile,
98 kErrorCore2MinidumpConversion,
99 };
100
Ken Mixter2953c3a2010-10-18 14:42:20 -0700101 static const int kForkProblem = 255;
102
Ben Chan6e709a12012-02-29 12:10:44 -0800103 // Returns an error type signature for a given |error_type| value,
104 // which is reported to the crash server along with the
105 // crash_reporter-user-collection signature.
106 std::string GetErrorTypeSignature(ErrorType error_type) const;
107
Chris Sosae4a86032010-06-16 17:08:34 -0700108 bool SetUpInternal(bool enabled);
109
Ben Chanf13bb582012-01-06 08:22:07 -0800110 // Returns, via |line|, the first line in |lines| that starts with |prefix|.
111 // Returns true if a line is found, or false otherwise.
112 bool GetFirstLineWithPrefix(const std::vector<std::string> &lines,
113 const char *prefix, std::string *line);
114
115 // Returns the identifier of |kind|, via |id|, found in |status_lines| on
116 // the line starting with |prefix|. |status_lines| contains the lines in
117 // the status file. Returns true if the identifier can be determined.
Ken Mixter777484c2010-07-23 16:22:44 -0700118 bool GetIdFromStatus(const char *prefix,
119 IdKind kind,
Ben Chanf13bb582012-01-06 08:22:07 -0800120 const std::vector<std::string> &status_lines,
Ken Mixter777484c2010-07-23 16:22:44 -0700121 int *id);
Ken Mixter207694d2010-10-28 15:42:37 -0700122
Ben Chanf13bb582012-01-06 08:22:07 -0800123 // Returns the process state, via |state|, found in |status_lines|, which
124 // contains the lines in the status file. Returns true if the process state
125 // can be determined.
126 bool GetStateFromStatus(const std::vector<std::string> &status_lines,
127 std::string *state);
128
Ken Mixter207694d2010-10-28 15:42:37 -0700129 void LogCollectionError(const std::string &error_message);
Ben Chan6e709a12012-02-29 12:10:44 -0800130 void EnqueueCollectionErrorLog(pid_t pid, ErrorType error_type,
131 const std::string &exec_name);
Ken Mixter207694d2010-10-28 15:42:37 -0700132
Simon Que9f90aca2013-02-19 17:19:52 -0800133 bool CopyOffProcFiles(pid_t pid, const base::FilePath &container_dir);
Ben Chanf13bb582012-01-06 08:22:07 -0800134
135 // Validates the proc files at |container_dir| and returns true if they
136 // are usable for the core-to-minidump conversion later. For instance, if
137 // a process is reaped by the kernel before the copying of its proc files
138 // takes place, some proc files like /proc/<pid>/maps may contain nothing
139 // and thus become unusable.
Simon Que9f90aca2013-02-19 17:19:52 -0800140 bool ValidateProcFiles(const base::FilePath &container_dir) const;
Ben Chan6e709a12012-02-29 12:10:44 -0800141
142 // Validates the core file at |core_path| and returns kErrorNone if
143 // the file contains the ELF magic bytes and an ELF class that matches the
144 // platform (i.e. 32-bit ELF on a 32-bit platform or 64-bit ELF on a 64-bit
145 // platform), which is due to the limitation in core2md. It returns an error
146 // type otherwise.
Simon Que9f90aca2013-02-19 17:19:52 -0800147 ErrorType ValidateCoreFile(const base::FilePath &core_path) const;
Ben Chanf13bb582012-01-06 08:22:07 -0800148
Ken Mixter777484c2010-07-23 16:22:44 -0700149 // Determines the crash directory for given pid based on pid's owner,
150 // and creates the directory if necessary with appropriate permissions.
151 // Returns true whether or not directory needed to be created, false on
152 // any failure.
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700153 bool GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid,
Simon Que9f90aca2013-02-19 17:19:52 -0800154 base::FilePath *crash_file_path,
Ken Mixter207694d2010-10-28 15:42:37 -0700155 bool *out_of_capacity);
Simon Que9f90aca2013-02-19 17:19:52 -0800156 bool CopyStdinToCoreFile(const base::FilePath &core_path);
157 bool RunCoreToMinidump(const base::FilePath &core_path,
158 const base::FilePath &procfs_directory,
159 const base::FilePath &minidump_path,
160 const base::FilePath &temp_directory);
Ben Chan6e709a12012-02-29 12:10:44 -0800161 ErrorType ConvertCoreToMinidump(pid_t pid,
Simon Que9f90aca2013-02-19 17:19:52 -0800162 const base::FilePath &container_dir,
163 const base::FilePath &core_path,
164 const base::FilePath &minidump_path);
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700165 ErrorType ConvertAndEnqueueCrash(pid_t pid, const std::string &exec_name,
166 uid_t supplied_ruid, bool *out_of_capacity);
Ken Mixter1b8fe012011-01-25 13:33:05 -0800167 bool ParseCrashAttributes(const std::string &crash_attributes,
Steve Fung773fd3c2015-10-09 17:01:35 -0700168 pid_t *pid, int *signal, uid_t *uid, gid_t *gid,
Ken Mixter1b8fe012011-01-25 13:33:05 -0800169 std::string *kernel_supplied_name);
Michael Krebs538ecbf2011-07-27 14:13:22 -0700170
Ken Mixter5d3a1a22011-03-16 12:47:20 -0700171 bool ShouldDump(bool has_owner_consent,
172 bool is_developer,
Ken Mixter5d3a1a22011-03-16 12:47:20 -0700173 std::string *reason);
Ken Mixter777484c2010-07-23 16:22:44 -0700174
175 bool generate_diagnostics_;
Chris Sosae4a86032010-06-16 17:08:34 -0700176 std::string our_path_;
177 bool initialized_;
Ken Mixter777484c2010-07-23 16:22:44 -0700178
Steve Fungd6169a22014-08-11 15:52:23 -0700179 bool core2md_failure_;
180 bool directory_failure_;
181 std::string filter_in_;
182
Ken Mixter777484c2010-07-23 16:22:44 -0700183 static const char *kUserId;
184 static const char *kGroupId;
Ben Chan895fa5d2014-09-02 20:58:20 -0700185
186 DISALLOW_COPY_AND_ASSIGN(UserCollector);
Chris Sosae4a86032010-06-16 17:08:34 -0700187};
188
Ben Chan7e776902014-06-18 13:19:51 -0700189#endif // CRASH_REPORTER_USER_COLLECTOR_H_