blob: aac94cb84068a5747eabb954978cf3f16b6f5a7e [file] [log] [blame]
Chris Sosae4a86032010-06-16 17:08:34 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Chan7e776902014-06-18 13:19:51 -07005#ifndef CRASH_REPORTER_USER_COLLECTOR_H_
6#define CRASH_REPORTER_USER_COLLECTOR_H_
Chris Sosae4a86032010-06-16 17:08:34 -07007
8#include <string>
Ken Mixter2953c3a2010-10-18 14:42:20 -07009#include <vector>
Chris Sosae4a86032010-06-16 17:08:34 -070010
Ben Chan7e776902014-06-18 13:19:51 -070011#include <base/files/file_path.h>
Ben Chan895fa5d2014-09-02 20:58:20 -070012#include <base/macros.h>
Ben Chan7e776902014-06-18 13:19:51 -070013#include <gtest/gtest_prod.h> // for FRIEND_TEST
14
Ken Mixter03403162010-08-18 15:23:16 -070015#include "crash-reporter/crash_collector.h"
Chris Sosae4a86032010-06-16 17:08:34 -070016
Ken Mixter03403162010-08-18 15:23:16 -070017class SystemLogging;
Chris Sosae4a86032010-06-16 17:08:34 -070018
19// User crash collector.
Ken Mixter03403162010-08-18 15:23:16 -070020class UserCollector : public CrashCollector {
Chris Sosae4a86032010-06-16 17:08:34 -070021 public:
Chris Sosae4a86032010-06-16 17:08:34 -070022 UserCollector();
23
24 // Initialize the user crash collector for detection of crashes,
25 // given a crash counting function, the path to this executable,
26 // metrics collection enabled oracle, and system logger facility.
Ken Mixter777484c2010-07-23 16:22:44 -070027 // Crash detection/reporting is not enabled until Enable is called.
28 // |generate_diagnostics| is used to indicate whether or not to try
29 // to generate a minidump from crashes.
Chris Sosae4a86032010-06-16 17:08:34 -070030 void Initialize(CountCrashFunction count_crash,
31 const std::string &our_path,
32 IsFeedbackAllowedFunction is_metrics_allowed,
Steve Fungd6169a22014-08-11 15:52:23 -070033 bool generate_diagnostics,
34 bool core2md_failure,
35 bool directory_failure,
36 const std::string &filter_in);
Chris Sosae4a86032010-06-16 17:08:34 -070037
Ben Chanefec0b32014-08-12 08:52:11 -070038 ~UserCollector() override;
Chris Sosae4a86032010-06-16 17:08:34 -070039
40 // Enable collection.
41 bool Enable() { return SetUpInternal(true); }
42
43 // Disable collection.
44 bool Disable() { return SetUpInternal(false); }
45
Ken Mixter777484c2010-07-23 16:22:44 -070046 // Handle a specific user crash. Returns true on success.
Ken Mixter1b8fe012011-01-25 13:33:05 -080047 bool HandleCrash(const std::string &crash_attributes,
48 const char *force_exec);
Chris Sosae4a86032010-06-16 17:08:34 -070049
50 // Set (override the default) core file pattern.
51 void set_core_pattern_file(const std::string &pattern) {
52 core_pattern_file_ = pattern;
53 }
54
Ken Mixterc49dbd42010-12-14 17:44:11 -080055 // Set (override the default) core pipe limit file.
56 void set_core_pipe_limit_file(const std::string &path) {
57 core_pipe_limit_file_ = path;
58 }
59
Chris Sosae4a86032010-06-16 17:08:34 -070060 private:
61 friend class UserCollectorTest;
Ken Mixter777484c2010-07-23 16:22:44 -070062 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPath);
63 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPid);
64 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesOK);
Ken Mixterd49d3622011-02-09 18:23:00 -080065 FRIEND_TEST(UserCollectorTest, GetExecutableBaseNameFromPid);
Ben Chanf13bb582012-01-06 08:22:07 -080066 FRIEND_TEST(UserCollectorTest, GetFirstLineWithPrefix);
Ken Mixter777484c2010-07-23 16:22:44 -070067 FRIEND_TEST(UserCollectorTest, GetIdFromStatus);
Ben Chanf13bb582012-01-06 08:22:07 -080068 FRIEND_TEST(UserCollectorTest, GetStateFromStatus);
Ken Mixter777484c2010-07-23 16:22:44 -070069 FRIEND_TEST(UserCollectorTest, GetProcessPath);
70 FRIEND_TEST(UserCollectorTest, GetSymlinkTarget);
71 FRIEND_TEST(UserCollectorTest, GetUserInfoFromName);
Ken Mixter1b8fe012011-01-25 13:33:05 -080072 FRIEND_TEST(UserCollectorTest, ParseCrashAttributes);
Ken Mixter5d3a1a22011-03-16 12:47:20 -070073 FRIEND_TEST(UserCollectorTest, ShouldDumpChromeOverridesDeveloperImage);
74 FRIEND_TEST(UserCollectorTest, ShouldDumpDeveloperImageOverridesConsent);
75 FRIEND_TEST(UserCollectorTest, ShouldDumpUseConsentProductionImage);
Ben Chanf13bb582012-01-06 08:22:07 -080076 FRIEND_TEST(UserCollectorTest, ValidateProcFiles);
Ben Chan6e709a12012-02-29 12:10:44 -080077 FRIEND_TEST(UserCollectorTest, ValidateCoreFile);
Ken Mixter777484c2010-07-23 16:22:44 -070078
79 // Enumeration to pass to GetIdFromStatus. Must match the order
80 // that the kernel lists IDs in the status file.
81 enum IdKind {
82 kIdReal = 0, // uid and gid
83 kIdEffective = 1, // euid and egid
84 kIdSet = 2, // suid and sgid
85 kIdFileSystem = 3, // fsuid and fsgid
86 kIdMax
87 };
Chris Sosae4a86032010-06-16 17:08:34 -070088
Ben Chan6e709a12012-02-29 12:10:44 -080089 enum ErrorType {
90 kErrorNone,
91 kErrorSystemIssue,
92 kErrorReadCoreData,
93 kErrorUnusableProcFiles,
94 kErrorInvalidCoreFile,
95 kErrorUnsupported32BitCoreFile,
96 kErrorCore2MinidumpConversion,
97 };
98
Ken Mixter2953c3a2010-10-18 14:42:20 -070099 static const int kForkProblem = 255;
100
Ben Chan6e709a12012-02-29 12:10:44 -0800101 // Returns an error type signature for a given |error_type| value,
102 // which is reported to the crash server along with the
103 // crash_reporter-user-collection signature.
104 std::string GetErrorTypeSignature(ErrorType error_type) const;
105
Chris Sosae4a86032010-06-16 17:08:34 -0700106 std::string GetPattern(bool enabled) const;
107 bool SetUpInternal(bool enabled);
108
Ben Chanf13bb582012-01-06 08:22:07 -0800109 // Returns, via |line|, the first line in |lines| that starts with |prefix|.
110 // Returns true if a line is found, or false otherwise.
111 bool GetFirstLineWithPrefix(const std::vector<std::string> &lines,
112 const char *prefix, std::string *line);
113
114 // Returns the identifier of |kind|, via |id|, found in |status_lines| on
115 // the line starting with |prefix|. |status_lines| contains the lines in
116 // the status file. Returns true if the identifier can be determined.
Ken Mixter777484c2010-07-23 16:22:44 -0700117 bool GetIdFromStatus(const char *prefix,
118 IdKind kind,
Ben Chanf13bb582012-01-06 08:22:07 -0800119 const std::vector<std::string> &status_lines,
Ken Mixter777484c2010-07-23 16:22:44 -0700120 int *id);
Ken Mixter207694d2010-10-28 15:42:37 -0700121
Ben Chanf13bb582012-01-06 08:22:07 -0800122 // Returns the process state, via |state|, found in |status_lines|, which
123 // contains the lines in the status file. Returns true if the process state
124 // can be determined.
125 bool GetStateFromStatus(const std::vector<std::string> &status_lines,
126 std::string *state);
127
Ken Mixter207694d2010-10-28 15:42:37 -0700128 void LogCollectionError(const std::string &error_message);
Ben Chan6e709a12012-02-29 12:10:44 -0800129 void EnqueueCollectionErrorLog(pid_t pid, ErrorType error_type,
130 const std::string &exec_name);
Ken Mixter207694d2010-10-28 15:42:37 -0700131
Simon Que9f90aca2013-02-19 17:19:52 -0800132 bool CopyOffProcFiles(pid_t pid, const base::FilePath &container_dir);
Ben Chanf13bb582012-01-06 08:22:07 -0800133
134 // Validates the proc files at |container_dir| and returns true if they
135 // are usable for the core-to-minidump conversion later. For instance, if
136 // a process is reaped by the kernel before the copying of its proc files
137 // takes place, some proc files like /proc/<pid>/maps may contain nothing
138 // and thus become unusable.
Simon Que9f90aca2013-02-19 17:19:52 -0800139 bool ValidateProcFiles(const base::FilePath &container_dir) const;
Ben Chan6e709a12012-02-29 12:10:44 -0800140
141 // Validates the core file at |core_path| and returns kErrorNone if
142 // the file contains the ELF magic bytes and an ELF class that matches the
143 // platform (i.e. 32-bit ELF on a 32-bit platform or 64-bit ELF on a 64-bit
144 // platform), which is due to the limitation in core2md. It returns an error
145 // type otherwise.
Simon Que9f90aca2013-02-19 17:19:52 -0800146 ErrorType ValidateCoreFile(const base::FilePath &core_path) const;
Ben Chanf13bb582012-01-06 08:22:07 -0800147
Ken Mixter777484c2010-07-23 16:22:44 -0700148 // Determines the crash directory for given pid based on pid's owner,
149 // and creates the directory if necessary with appropriate permissions.
150 // Returns true whether or not directory needed to be created, false on
151 // any failure.
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700152 bool GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid,
Simon Que9f90aca2013-02-19 17:19:52 -0800153 base::FilePath *crash_file_path,
Ken Mixter207694d2010-10-28 15:42:37 -0700154 bool *out_of_capacity);
Simon Que9f90aca2013-02-19 17:19:52 -0800155 bool CopyStdinToCoreFile(const base::FilePath &core_path);
156 bool RunCoreToMinidump(const base::FilePath &core_path,
157 const base::FilePath &procfs_directory,
158 const base::FilePath &minidump_path,
159 const base::FilePath &temp_directory);
Ben Chan6e709a12012-02-29 12:10:44 -0800160 ErrorType ConvertCoreToMinidump(pid_t pid,
Simon Que9f90aca2013-02-19 17:19:52 -0800161 const base::FilePath &container_dir,
162 const base::FilePath &core_path,
163 const base::FilePath &minidump_path);
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700164 ErrorType ConvertAndEnqueueCrash(pid_t pid, const std::string &exec_name,
165 uid_t supplied_ruid, bool *out_of_capacity);
Ken Mixter1b8fe012011-01-25 13:33:05 -0800166 bool ParseCrashAttributes(const std::string &crash_attributes,
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700167 pid_t *pid, int *signal, uid_t *uid,
Ken Mixter1b8fe012011-01-25 13:33:05 -0800168 std::string *kernel_supplied_name);
Michael Krebs538ecbf2011-07-27 14:13:22 -0700169
Ken Mixter5d3a1a22011-03-16 12:47:20 -0700170 bool ShouldDump(bool has_owner_consent,
171 bool is_developer,
Michael Krebs4fe30db2011-08-05 13:54:52 -0700172 bool handle_chrome_crashes,
Ken Mixter5d3a1a22011-03-16 12:47:20 -0700173 const std::string &exec,
174 std::string *reason);
Ken Mixter777484c2010-07-23 16:22:44 -0700175
176 bool generate_diagnostics_;
Chris Sosae4a86032010-06-16 17:08:34 -0700177 std::string core_pattern_file_;
Ken Mixterc49dbd42010-12-14 17:44:11 -0800178 std::string core_pipe_limit_file_;
Chris Sosae4a86032010-06-16 17:08:34 -0700179 std::string our_path_;
180 bool initialized_;
Ken Mixter777484c2010-07-23 16:22:44 -0700181
Steve Fungd6169a22014-08-11 15:52:23 -0700182 bool core2md_failure_;
183 bool directory_failure_;
184 std::string filter_in_;
185
Ken Mixter777484c2010-07-23 16:22:44 -0700186 static const char *kUserId;
187 static const char *kGroupId;
Ben Chan895fa5d2014-09-02 20:58:20 -0700188
189 DISALLOW_COPY_AND_ASSIGN(UserCollector);
Chris Sosae4a86032010-06-16 17:08:34 -0700190};
191
Ben Chan7e776902014-06-18 13:19:51 -0700192#endif // CRASH_REPORTER_USER_COLLECTOR_H_