blob: 3658e5114560a254a35c91a8a6b25bfd0c732e2b [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>
12#include <gtest/gtest_prod.h> // for FRIEND_TEST
13
Ken Mixter03403162010-08-18 15:23:16 -070014#include "crash-reporter/crash_collector.h"
Chris Sosae4a86032010-06-16 17:08:34 -070015
Ken Mixter03403162010-08-18 15:23:16 -070016class SystemLogging;
Chris Sosae4a86032010-06-16 17:08:34 -070017
18// User crash collector.
Ken Mixter03403162010-08-18 15:23:16 -070019class UserCollector : public CrashCollector {
Chris Sosae4a86032010-06-16 17:08:34 -070020 public:
Chris Sosae4a86032010-06-16 17:08:34 -070021 UserCollector();
22
23 // Initialize the user crash collector for detection of crashes,
24 // given a crash counting function, the path to this executable,
25 // metrics collection enabled oracle, and system logger facility.
Ken Mixter777484c2010-07-23 16:22:44 -070026 // Crash detection/reporting is not enabled until Enable is called.
27 // |generate_diagnostics| is used to indicate whether or not to try
28 // to generate a minidump from crashes.
Chris Sosae4a86032010-06-16 17:08:34 -070029 void Initialize(CountCrashFunction count_crash,
30 const std::string &our_path,
31 IsFeedbackAllowedFunction is_metrics_allowed,
Ken Mixter777484c2010-07-23 16:22:44 -070032 bool generate_diagnostics);
Chris Sosae4a86032010-06-16 17:08:34 -070033
34 virtual ~UserCollector();
35
36 // Enable collection.
37 bool Enable() { return SetUpInternal(true); }
38
39 // Disable collection.
40 bool Disable() { return SetUpInternal(false); }
41
Ken Mixter777484c2010-07-23 16:22:44 -070042 // Handle a specific user crash. Returns true on success.
Ken Mixter1b8fe012011-01-25 13:33:05 -080043 bool HandleCrash(const std::string &crash_attributes,
44 const char *force_exec);
Chris Sosae4a86032010-06-16 17:08:34 -070045
46 // Set (override the default) core file pattern.
47 void set_core_pattern_file(const std::string &pattern) {
48 core_pattern_file_ = pattern;
49 }
50
Ken Mixterc49dbd42010-12-14 17:44:11 -080051 // Set (override the default) core pipe limit file.
52 void set_core_pipe_limit_file(const std::string &path) {
53 core_pipe_limit_file_ = path;
54 }
55
Chris Sosae4a86032010-06-16 17:08:34 -070056 private:
57 friend class UserCollectorTest;
Ken Mixter777484c2010-07-23 16:22:44 -070058 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPath);
59 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPid);
60 FRIEND_TEST(UserCollectorTest, CopyOffProcFilesOK);
Ken Mixterd49d3622011-02-09 18:23:00 -080061 FRIEND_TEST(UserCollectorTest, GetExecutableBaseNameFromPid);
Ben Chanf13bb582012-01-06 08:22:07 -080062 FRIEND_TEST(UserCollectorTest, GetFirstLineWithPrefix);
Ken Mixter777484c2010-07-23 16:22:44 -070063 FRIEND_TEST(UserCollectorTest, GetIdFromStatus);
Ben Chanf13bb582012-01-06 08:22:07 -080064 FRIEND_TEST(UserCollectorTest, GetStateFromStatus);
Ken Mixter777484c2010-07-23 16:22:44 -070065 FRIEND_TEST(UserCollectorTest, GetProcessPath);
66 FRIEND_TEST(UserCollectorTest, GetSymlinkTarget);
67 FRIEND_TEST(UserCollectorTest, GetUserInfoFromName);
Ken Mixter1b8fe012011-01-25 13:33:05 -080068 FRIEND_TEST(UserCollectorTest, ParseCrashAttributes);
Ken Mixter5d3a1a22011-03-16 12:47:20 -070069 FRIEND_TEST(UserCollectorTest, ShouldDumpChromeOverridesDeveloperImage);
70 FRIEND_TEST(UserCollectorTest, ShouldDumpDeveloperImageOverridesConsent);
71 FRIEND_TEST(UserCollectorTest, ShouldDumpUseConsentProductionImage);
Ben Chanf13bb582012-01-06 08:22:07 -080072 FRIEND_TEST(UserCollectorTest, ValidateProcFiles);
Ben Chan6e709a12012-02-29 12:10:44 -080073 FRIEND_TEST(UserCollectorTest, ValidateCoreFile);
Ken Mixter777484c2010-07-23 16:22:44 -070074
75 // Enumeration to pass to GetIdFromStatus. Must match the order
76 // that the kernel lists IDs in the status file.
77 enum IdKind {
78 kIdReal = 0, // uid and gid
79 kIdEffective = 1, // euid and egid
80 kIdSet = 2, // suid and sgid
81 kIdFileSystem = 3, // fsuid and fsgid
82 kIdMax
83 };
Chris Sosae4a86032010-06-16 17:08:34 -070084
Ben Chan6e709a12012-02-29 12:10:44 -080085 enum ErrorType {
86 kErrorNone,
87 kErrorSystemIssue,
88 kErrorReadCoreData,
89 kErrorUnusableProcFiles,
90 kErrorInvalidCoreFile,
91 kErrorUnsupported32BitCoreFile,
92 kErrorCore2MinidumpConversion,
93 };
94
Ken Mixter2953c3a2010-10-18 14:42:20 -070095 static const int kForkProblem = 255;
96
Ben Chan6e709a12012-02-29 12:10:44 -080097 // Returns an error type signature for a given |error_type| value,
98 // which is reported to the crash server along with the
99 // crash_reporter-user-collection signature.
100 std::string GetErrorTypeSignature(ErrorType error_type) const;
101
Chris Sosae4a86032010-06-16 17:08:34 -0700102 std::string GetPattern(bool enabled) const;
103 bool SetUpInternal(bool enabled);
104
Ben Chanf13bb582012-01-06 08:22:07 -0800105 // Returns, via |line|, the first line in |lines| that starts with |prefix|.
106 // Returns true if a line is found, or false otherwise.
107 bool GetFirstLineWithPrefix(const std::vector<std::string> &lines,
108 const char *prefix, std::string *line);
109
110 // Returns the identifier of |kind|, via |id|, found in |status_lines| on
111 // the line starting with |prefix|. |status_lines| contains the lines in
112 // the status file. Returns true if the identifier can be determined.
Ken Mixter777484c2010-07-23 16:22:44 -0700113 bool GetIdFromStatus(const char *prefix,
114 IdKind kind,
Ben Chanf13bb582012-01-06 08:22:07 -0800115 const std::vector<std::string> &status_lines,
Ken Mixter777484c2010-07-23 16:22:44 -0700116 int *id);
Ken Mixter207694d2010-10-28 15:42:37 -0700117
Ben Chanf13bb582012-01-06 08:22:07 -0800118 // Returns the process state, via |state|, found in |status_lines|, which
119 // contains the lines in the status file. Returns true if the process state
120 // can be determined.
121 bool GetStateFromStatus(const std::vector<std::string> &status_lines,
122 std::string *state);
123
Ken Mixter207694d2010-10-28 15:42:37 -0700124 void LogCollectionError(const std::string &error_message);
Ben Chan6e709a12012-02-29 12:10:44 -0800125 void EnqueueCollectionErrorLog(pid_t pid, ErrorType error_type,
126 const std::string &exec_name);
Ken Mixter207694d2010-10-28 15:42:37 -0700127
Simon Que9f90aca2013-02-19 17:19:52 -0800128 bool CopyOffProcFiles(pid_t pid, const base::FilePath &container_dir);
Ben Chanf13bb582012-01-06 08:22:07 -0800129
130 // Validates the proc files at |container_dir| and returns true if they
131 // are usable for the core-to-minidump conversion later. For instance, if
132 // a process is reaped by the kernel before the copying of its proc files
133 // takes place, some proc files like /proc/<pid>/maps may contain nothing
134 // and thus become unusable.
Simon Que9f90aca2013-02-19 17:19:52 -0800135 bool ValidateProcFiles(const base::FilePath &container_dir) const;
Ben Chan6e709a12012-02-29 12:10:44 -0800136
137 // Validates the core file at |core_path| and returns kErrorNone if
138 // the file contains the ELF magic bytes and an ELF class that matches the
139 // platform (i.e. 32-bit ELF on a 32-bit platform or 64-bit ELF on a 64-bit
140 // platform), which is due to the limitation in core2md. It returns an error
141 // type otherwise.
Simon Que9f90aca2013-02-19 17:19:52 -0800142 ErrorType ValidateCoreFile(const base::FilePath &core_path) const;
Ben Chanf13bb582012-01-06 08:22:07 -0800143
Ken Mixter777484c2010-07-23 16:22:44 -0700144 // Determines the crash directory for given pid based on pid's owner,
145 // and creates the directory if necessary with appropriate permissions.
146 // Returns true whether or not directory needed to be created, false on
147 // any failure.
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700148 bool GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid,
Simon Que9f90aca2013-02-19 17:19:52 -0800149 base::FilePath *crash_file_path,
Ken Mixter207694d2010-10-28 15:42:37 -0700150 bool *out_of_capacity);
Simon Que9f90aca2013-02-19 17:19:52 -0800151 bool CopyStdinToCoreFile(const base::FilePath &core_path);
152 bool RunCoreToMinidump(const base::FilePath &core_path,
153 const base::FilePath &procfs_directory,
154 const base::FilePath &minidump_path,
155 const base::FilePath &temp_directory);
Ben Chan6e709a12012-02-29 12:10:44 -0800156 ErrorType ConvertCoreToMinidump(pid_t pid,
Simon Que9f90aca2013-02-19 17:19:52 -0800157 const base::FilePath &container_dir,
158 const base::FilePath &core_path,
159 const base::FilePath &minidump_path);
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700160 ErrorType ConvertAndEnqueueCrash(pid_t pid, const std::string &exec_name,
161 uid_t supplied_ruid, bool *out_of_capacity);
Ken Mixter1b8fe012011-01-25 13:33:05 -0800162 bool ParseCrashAttributes(const std::string &crash_attributes,
Michael Krebs1c57e9e2012-09-25 18:03:13 -0700163 pid_t *pid, int *signal, uid_t *uid,
Ken Mixter1b8fe012011-01-25 13:33:05 -0800164 std::string *kernel_supplied_name);
Michael Krebs538ecbf2011-07-27 14:13:22 -0700165
Ken Mixter5d3a1a22011-03-16 12:47:20 -0700166 bool ShouldDump(bool has_owner_consent,
167 bool is_developer,
Michael Krebs4fe30db2011-08-05 13:54:52 -0700168 bool handle_chrome_crashes,
Ken Mixter5d3a1a22011-03-16 12:47:20 -0700169 const std::string &exec,
170 std::string *reason);
Ken Mixter777484c2010-07-23 16:22:44 -0700171
172 bool generate_diagnostics_;
Chris Sosae4a86032010-06-16 17:08:34 -0700173 std::string core_pattern_file_;
Ken Mixterc49dbd42010-12-14 17:44:11 -0800174 std::string core_pipe_limit_file_;
Chris Sosae4a86032010-06-16 17:08:34 -0700175 std::string our_path_;
176 bool initialized_;
Ken Mixter777484c2010-07-23 16:22:44 -0700177
178 static const char *kUserId;
179 static const char *kGroupId;
Chris Sosae4a86032010-06-16 17:08:34 -0700180};
181
Ben Chan7e776902014-06-18 13:19:51 -0700182#endif // CRASH_REPORTER_USER_COLLECTOR_H_