| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef UI_GFX_WIN_CRASH_ID_HELPER_H_ |
| #define UI_GFX_WIN_CRASH_ID_HELPER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/no_destructor.h" |
| #include "base/threading/platform_thread.h" |
| #include "components/crash/core/common/crash_key.h" |
| #include "ui/gfx/gfx_export.h" |
| |
| namespace gfx { |
| |
| // CrashIdHelper is used to log (in crash dumps) the id(s) of the window/widget |
| // currently dispatching an event. Often times crashes occur purely in ui |
| // code, while the bug lies in client code. Logging an id helps better identify |
| // the client code that created the window/widget. |
| // |
| // This class only logs ids on the thread identified by RegisterMainThread(). |
| // |
| // Example usage: |
| // { |
| // auto logger = CrashIdHelper::Get()->OnWillProcessMessages(crash_id); |
| // <do message processing> |
| // } |
| class GFX_EXPORT CrashIdHelper { |
| public: |
| static CrashIdHelper* Get(); |
| |
| CrashIdHelper(const CrashIdHelper&) = delete; |
| CrashIdHelper& operator=(const CrashIdHelper&) = delete; |
| |
| // Registers the thread used for logging. |
| static void RegisterMainThread(base::PlatformThreadId thread_id); |
| |
| // RAII style class that unregisters in the destructor. |
| class GFX_EXPORT ScopedLogger { |
| public: |
| ScopedLogger(const ScopedLogger&) = delete; |
| ScopedLogger& operator=(const ScopedLogger&) = delete; |
| |
| ~ScopedLogger(); |
| |
| private: |
| friend class CrashIdHelper; |
| ScopedLogger(); |
| }; |
| |
| // Adds |id| to the list of active debugging ids. When the returned object |
| // is destroyed, |id| is removed from the list of active debugging ids. |
| // Returns null if logging is not enabled on the current thread. |
| std::unique_ptr<ScopedLogger> OnWillProcessMessages(const std::string& id); |
| |
| private: |
| friend base::NoDestructor<CrashIdHelper>; |
| friend class CrashIdHelperTest; |
| |
| CrashIdHelper(); |
| ~CrashIdHelper(); |
| |
| // Called from ~ScopedLogger. Removes the most recently added id. |
| void OnDidProcessMessages(); |
| |
| // Returns the identifier to put in the crash key. |
| std::string CurrentCrashId() const; |
| |
| // Ordered list of debugging identifiers added. |
| std::vector<std::string> ids_; |
| |
| // Set to true once |ids_| has more than one object, and false once |ids_| is |
| // empty. That is, this is true once processing the windows message resulted |
| // in processing another windows message (nested message loops). See comment |
| // in implementation of CurrentCrashId() as to why this is tracked. |
| bool was_nested_ = false; |
| |
| // This uses the name 'widget' as this code is most commonly triggered from |
| // views, which uses the term Widget. |
| crash_reporter::CrashKeyString<128> debugging_crash_key_{"widget-id"}; |
| |
| static base::PlatformThreadId main_thread_id_; |
| }; |
| |
| } // namespace gfx |
| |
| #endif // UI_GFX_WIN_CRASH_ID_HELPER_H_ |