| // Copyright 2015 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. |
| |
| #ifndef CRASH_REPORTER_ARC_COLLECTOR_H_ |
| #define CRASH_REPORTER_ARC_COLLECTOR_H_ |
| |
| #include <memory> |
| #include <sstream> |
| #include <string> |
| #include <unordered_map> |
| |
| #include <base/macros.h> |
| #include <gtest/gtest_prod.h> // for FRIEND_TEST |
| |
| #include "crash-reporter/user_collector_base.h" |
| |
| // Collector for system crashes in the ARC container. |
| class ArcCollector : public UserCollectorBase { |
| public: |
| struct Context { |
| virtual ~Context() = default; |
| |
| virtual bool GetArcPid(pid_t *pid) const = 0; |
| virtual bool GetPidNamespace(pid_t pid, std::string *ns) const = 0; |
| virtual bool GetExeBaseName(pid_t pid, std::string *exe) const = 0; |
| virtual bool GetCommand(pid_t pid, std::string *command) const = 0; |
| }; |
| |
| using ContextPtr = std::unique_ptr<Context>; |
| |
| ArcCollector(); |
| explicit ArcCollector(ContextPtr context); |
| ~ArcCollector() override = default; |
| |
| const Context &context() const { return *context_; } |
| |
| // Returns false if the query failed, which may happen during teardown of the |
| // ARC container. Since the behavior of user collectors is determined by |
| // IsArcProcess, there is a (rare) race condition for crashes that occur |
| // during teardown. |
| bool IsArcProcess(pid_t pid) const; |
| |
| // Reads a Java crash log of the given |type| from standard input, or closes |
| // the stream if reporting is disabled. |
| bool HandleJavaCrash(const std::string &type); |
| |
| static bool IsArcRunning(); |
| |
| private: |
| FRIEND_TEST(ArcCollectorTest, GetExeBaseNameForUserCrash); |
| FRIEND_TEST(ArcCollectorTest, GetExeBaseNameForArcCrash); |
| FRIEND_TEST(ArcCollectorTest, ShouldDump); |
| FRIEND_TEST(ArcCollectorTest, ParseCrashLog); |
| |
| // Upper bound for system UIDs in ARC. |
| static const uid_t kSystemUserEnd = 10000; |
| |
| class ArcContext : public Context { |
| public: |
| explicit ArcContext(ArcCollector *collector) |
| : collector_(collector) {} |
| |
| bool GetArcPid(pid_t *pid) const override; |
| bool GetPidNamespace(pid_t pid, std::string *ns) const override; |
| bool GetExeBaseName(pid_t pid, std::string *exe) const override; |
| bool GetCommand(pid_t pid, std::string *command) const override; |
| |
| private: |
| ArcCollector *const collector_; |
| }; |
| |
| // CrashCollector overrides. |
| bool GetExecutableBaseNameFromPid(pid_t pid, std::string *base_name) override; |
| |
| // 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; |
| |
| // Adds the crash |type| and Chrome version as metadata. The |add_arc_version| |
| // option requires privilege to access the ARC root. |
| void AddArcMetaData(const std::string &type, bool add_arc_version); |
| |
| using CrashLogHeaderMap = std::unordered_map<std::string, std::string>; |
| static std::string GetCrashLogHeader(const CrashLogHeaderMap &map, |
| const char *key); |
| |
| static bool ParseCrashLog(const std::string &type, |
| std::stringstream *stream, |
| CrashLogHeaderMap *map, |
| std::string *exception_info); |
| |
| bool CreateReportForJavaCrash(const std::string &type, |
| const CrashLogHeaderMap &map, |
| const std::string &exception_info, |
| const std::string &log, |
| bool *out_of_capacity); |
| |
| const ContextPtr context_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ArcCollector); |
| }; |
| |
| #endif // CRASH_REPORTER_ARC_COLLECTOR_H_ |