| // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // UserCollector handles program crashes in userspace. When the kernel detects |
| // a crashing program, it invokes this collector via |
| // /proc/sys/kernel/core_pattern. |
| // This handler ignores chrome crashes (letting chrome_collector handle them |
| // when it is directly invoked). |
| |
| #ifndef CRASH_REPORTER_USER_COLLECTOR_H_ |
| #define CRASH_REPORTER_USER_COLLECTOR_H_ |
| |
| #include <functional> |
| #include <string> |
| |
| #include <base/files/file_path.h> |
| #include <base/macros.h> |
| #include <gtest/gtest_prod.h> // for FRIEND_TEST |
| |
| #include "crash-reporter/user_collector_base.h" |
| |
| // User crash collector. |
| class UserCollector : public UserCollectorBase { |
| public: |
| UserCollector(); |
| |
| // Initialize the user crash collector for detection of crashes, |
| // given the path to this executable, metrics collection enabled |
| // oracle, and system logger facility. Crash detection/reporting |
| // is not enabled until Enable is called. |
| void Initialize(const std::string& our_path, |
| IsFeedbackAllowedFunction is_metrics_allowed, |
| bool core2md_failure, |
| bool directory_failure, |
| bool early); |
| |
| ~UserCollector() override; |
| |
| // Enable collection. |
| bool Enable(bool early) { return SetUpInternal(true /* enabled */, early); } |
| |
| // Disable collection. |
| bool Disable() { |
| return SetUpInternal(false /* enabled */, false /* early */); |
| } |
| |
| // Set (override the default) core file pattern. |
| void set_core_pattern_file(const std::string& pattern) { |
| core_pattern_file_ = pattern; |
| } |
| |
| // Set (override the default) core pipe limit file. |
| void set_core_pipe_limit_file(const std::string& path) { |
| core_pipe_limit_file_ = path; |
| } |
| |
| void set_filter_path(const std::string& filter_path) { |
| filter_path_ = filter_path; |
| } |
| |
| protected: |
| void FinishCrash(const base::FilePath& meta_path, |
| const std::string& exec_name, |
| const std::string& payload_name) override; |
| |
| private: |
| friend class UserCollectorTest; |
| FRIEND_TEST(UserCollectorTest, ClobberContainerDirectory); |
| FRIEND_TEST(UserCollectorTest, CopyOffProcFilesBadPid); |
| FRIEND_TEST(UserCollectorTest, CopyOffProcFilesOK); |
| FRIEND_TEST(UserCollectorTest, GetExecutableBaseNameFromPid); |
| FRIEND_TEST(UserCollectorTest, GetFirstLineWithPrefix); |
| FRIEND_TEST(UserCollectorTest, GetIdFromStatus); |
| FRIEND_TEST(UserCollectorTest, GetStateFromStatus); |
| FRIEND_TEST(UserCollectorTest, GetProcessPath); |
| FRIEND_TEST(UserCollectorTest, ParseCrashAttributes); |
| FRIEND_TEST(UserCollectorTest, ShouldDumpFiltering); |
| FRIEND_TEST(UserCollectorTest, ShouldDumpChromeOverridesDeveloperImage); |
| FRIEND_TEST(UserCollectorTest, ShouldDumpDeveloperImageOverridesConsent); |
| FRIEND_TEST(UserCollectorTest, ShouldDumpUserConsentProductionImage); |
| FRIEND_TEST(UserCollectorTest, ValidateProcFiles); |
| FRIEND_TEST(UserCollectorTest, ValidateCoreFile); |
| |
| std::string GetPattern(bool enabled, bool early) const; |
| bool SetUpInternal(bool enabled, bool early); |
| |
| bool CopyOffProcFiles(pid_t pid, const base::FilePath& container_dir); |
| |
| // Validates the proc files at |container_dir| and returns true if they |
| // are usable for the core-to-minidump conversion later. For instance, if |
| // a process is reaped by the kernel before the copying of its proc files |
| // takes place, some proc files like /proc/<pid>/maps may contain nothing |
| // and thus become unusable. |
| bool ValidateProcFiles(const base::FilePath& container_dir) const; |
| |
| // Validates the core file at |core_path| and returns kErrorNone if |
| // the file contains the ELF magic bytes and an ELF class that matches the |
| // platform (i.e. 32-bit ELF on a 32-bit platform or 64-bit ELF on a 64-bit |
| // platform), which is due to the limitation in core2md. It returns an error |
| // type otherwise. |
| ErrorType ValidateCoreFile(const base::FilePath& core_path) const; |
| bool CopyStdinToCoreFile(const base::FilePath& core_path); |
| bool RunCoreToMinidump(const base::FilePath& core_path, |
| const base::FilePath& procfs_directory, |
| const base::FilePath& minidump_path, |
| const base::FilePath& temp_directory); |
| |
| bool RunFilter(pid_t pid); |
| |
| bool ShouldDump(pid_t pid, |
| bool has_owner_consent, |
| bool is_developer, |
| bool handle_chrome_crashes, |
| const std::string& exec, |
| std::string* reason); |
| |
| // UserCollectorBase overrides. |
| bool ShouldDump(pid_t pid, |
| uid_t uid, |
| const std::string& exec, |
| std::string* reason) override; |
| ErrorType ConvertCoreToMinidump(pid_t pid, |
| const base::FilePath& container_dir, |
| const base::FilePath& core_path, |
| const base::FilePath& minidump_path) override; |
| |
| std::string core_pattern_file_; |
| std::string core_pipe_limit_file_; |
| std::string our_path_; |
| std::string filter_path_; |
| |
| // Force a core2md failure for testing. |
| bool core2md_failure_; |
| |
| DISALLOW_COPY_AND_ASSIGN(UserCollector); |
| }; |
| |
| #endif // CRASH_REPORTER_USER_COLLECTOR_H_ |