|  | // Copyright 2020 The Fuchsia 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 SRC_SYS_APPMGR_CRASH_INTROSPECTOR_H_ | 
|  | #define SRC_SYS_APPMGR_CRASH_INTROSPECTOR_H_ | 
|  |  | 
|  | #include <fuchsia/sys/internal/cpp/fidl.h> | 
|  | #include <lib/fidl/cpp/binding_set.h> | 
|  | #include <zircon/types.h> | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "lib/async/cpp/task.h" | 
|  | #include "lib/async/cpp/wait.h" | 
|  | #include "lib/fitx/internal/result.h" | 
|  | #include "lib/zx/channel.h" | 
|  | #include "lib/zx/thread.h" | 
|  | #include "src/lib/fxl/macros.h" | 
|  | #include "src/lib/fxl/memory/weak_ptr.h" | 
|  |  | 
|  | namespace component { | 
|  |  | 
|  | // Implements |CrashIntrospect| fidl service and keeps a cache of all crashed threads in monitored | 
|  | // jobs. The cached results are automatically deleted after some time or when retrieved using | 
|  | // |FindComponentByThreadKoid| call. | 
|  | class CrashIntrospector : public fuchsia::sys::internal::CrashIntrospect { | 
|  | public: | 
|  | CrashIntrospector(); | 
|  | virtual ~CrashIntrospector() override; | 
|  |  | 
|  | // Register the job to be monitored for thread crashes and associate it with |component_info|. | 
|  | void RegisterJob(const zx::job& job, fuchsia::sys::internal::SourceIdentity component_info); | 
|  |  | 
|  | // Removes and returns the component associated with crashed thread which is cached in this | 
|  | // class. | 
|  | void FindComponentByThreadKoid(zx_koid_t thread_koid, | 
|  | FindComponentByThreadKoidCallback callback) override; | 
|  |  | 
|  | void AddBinding(fidl::InterfaceRequest<fuchsia::sys::internal::CrashIntrospect> request); | 
|  |  | 
|  | private: | 
|  | // Class to monitor an individual job. | 
|  | class CrashMonitor { | 
|  | public: | 
|  | CrashMonitor(fxl::WeakPtr<CrashIntrospector> introspector, zx::channel exception_channel, | 
|  | fuchsia::sys::internal::SourceIdentity component_info); | 
|  | ~CrashMonitor(); | 
|  |  | 
|  | private: | 
|  | void CrashHandler(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status, | 
|  | const zx_packet_signal* signal); | 
|  | fxl::WeakPtr<CrashIntrospector> introspector_; | 
|  | fuchsia::sys::internal::SourceIdentity component_info_; | 
|  | zx::channel exception_channel_; | 
|  | async::WaitMethod<CrashMonitor, &CrashMonitor::CrashHandler> wait_; | 
|  |  | 
|  | FXL_DISALLOW_COPY_AND_ASSIGN(CrashMonitor); | 
|  | }; | 
|  |  | 
|  | // Adds thread and associated |component_info| to the cache. | 
|  | void AddThreadToCache(const zx::thread& thread, | 
|  | const fuchsia::sys::internal::SourceIdentity& component_info); | 
|  |  | 
|  | // Removes thread from the cache and returns |component_info| if available. | 
|  | // Returns false if thread is not in the cache. | 
|  | fitx::result<bool, fuchsia::sys::internal::SourceIdentity> RemoveThreadFromCache( | 
|  | zx_koid_t thread_koid); | 
|  |  | 
|  | std::unique_ptr<CrashMonitor> ExtractMonitor(const CrashMonitor* monitor); | 
|  |  | 
|  | fxl::WeakPtrFactory<CrashIntrospector> weak_ptr_factory_; | 
|  | // Keep monitors for safe keeping till they are running. | 
|  | std::map<const CrashMonitor*, std::unique_ptr<CrashMonitor>> monitors_; | 
|  |  | 
|  | // Stores associated |component_info| and a task which will auto delete it from the cache in a | 
|  | // fixed time (as defined in implementation file). | 
|  | std::map<zx_koid_t, | 
|  | std::pair<std::unique_ptr<async::TaskClosure>, fuchsia::sys::internal::SourceIdentity>> | 
|  | thread_cache_; | 
|  |  | 
|  | fidl::BindingSet<fuchsia::sys::internal::CrashIntrospect> bindings_; | 
|  |  | 
|  | FXL_DISALLOW_COPY_AND_ASSIGN(CrashIntrospector); | 
|  | }; | 
|  |  | 
|  | }  // namespace component | 
|  |  | 
|  | #endif  // SRC_SYS_APPMGR_CRASH_INTROSPECTOR_H_ |