hang_watcher.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. // Copyright 2020 The Chromium 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. #ifndef BASE_THREADING_HANG_WATCHER_H_
  5. #define BASE_THREADING_HANG_WATCHER_H_
  6. #include <atomic>
  7. #include <cstdint>
  8. #include <memory>
  9. #include <type_traits>
  10. #include <vector>
  11. #include "base/atomicops.h"
  12. #include "base/base_export.h"
  13. #include "base/bits.h"
  14. #include "base/callback.h"
  15. #include "base/callback_forward.h"
  16. #include "base/callback_helpers.h"
  17. #include "base/compiler_specific.h"
  18. #include "base/dcheck_is_on.h"
  19. #include "base/debug/crash_logging.h"
  20. #include "base/gtest_prod_util.h"
  21. #include "base/memory/memory_pressure_listener.h"
  22. #include "base/memory/raw_ptr.h"
  23. #include "base/synchronization/lock.h"
  24. #include "base/synchronization/waitable_event.h"
  25. #include "base/template_util.h"
  26. #include "base/thread_annotations.h"
  27. #include "base/threading/platform_thread.h"
  28. #include "base/threading/simple_thread.h"
  29. #include "base/threading/thread_checker.h"
  30. #include "base/threading/thread_local.h"
  31. #include "base/time/tick_clock.h"
  32. #include "base/time/time.h"
  33. #include "build/build_config.h"
  34. namespace base {
  35. class WatchHangsInScope;
  36. namespace internal {
  37. class HangWatchState;
  38. } // namespace internal
  39. } // namespace base
  40. namespace base {
  41. // Instantiate a WatchHangsInScope in a code scope to register to be
  42. // watched for hangs of more than |timeout| by the HangWatcher.
  43. //
  44. // Example usage:
  45. //
  46. // void FooBar(){
  47. // WatchHangsInScope scope(base::Seconds(5));
  48. // DoWork();
  49. // }
  50. //
  51. // If DoWork() takes more than 5s to run and the HangWatcher
  52. // inspects the thread state before Foobar returns a hang will be
  53. // reported.
  54. //
  55. // WatchHangsInScopes are typically meant to live on the stack. In some
  56. // cases it's necessary to keep a WatchHangsInScope instance as a class
  57. // member but special care is required when doing so as a WatchHangsInScope
  58. // that stays alive longer than intended will generate non-actionable hang
  59. // reports.
  60. class BASE_EXPORT WatchHangsInScope {
  61. public:
  62. // A good default value needs to be large enough to represent a significant
  63. // hang and avoid noise while being small enough to not exclude too many
  64. // hangs. The nature of the work that gets executed on the thread is also
  65. // important. We can be much stricter when monitoring a UI thread compared to
  66. // a ThreadPool thread for example.
  67. static constexpr base::TimeDelta kDefaultHangWatchTime = base::Seconds(10);
  68. // Constructing/destructing thread must be the same thread.
  69. explicit WatchHangsInScope(TimeDelta timeout = kDefaultHangWatchTime);
  70. ~WatchHangsInScope();
  71. WatchHangsInScope(const WatchHangsInScope&) = delete;
  72. WatchHangsInScope& operator=(const WatchHangsInScope&) = delete;
  73. private:
  74. // Will be true if the object actually set a deadline and false if not.
  75. bool took_effect_ = true;
  76. // This object should always be constructed and destructed on the same thread.
  77. THREAD_CHECKER(thread_checker_);
  78. // The deadline set by the previous WatchHangsInScope created on this
  79. // thread. Stored so it can be restored when this WatchHangsInScope is
  80. // destroyed.
  81. TimeTicks previous_deadline_;
  82. // Indicates whether the kIgnoreCurrentWatchHangsInScope flag must be set upon
  83. // exiting this WatchHangsInScope if a call to InvalidateActiveExpectations()
  84. // previously suspended hang watching.
  85. bool set_hangs_ignored_on_exit_ = false;
  86. #if DCHECK_IS_ON()
  87. // The previous WatchHangsInScope created on this thread.
  88. WatchHangsInScope* previous_watch_hangs_in_scope_;
  89. #endif
  90. };
  91. // Monitors registered threads for hangs by inspecting their associated
  92. // HangWatchStates for deadline overruns. This happens at a regular interval on
  93. // a separate thread. Only one instance of HangWatcher can exist at a time
  94. // within a single process. This instance must outlive all monitored threads.
  95. class BASE_EXPORT HangWatcher : public DelegateSimpleThread::Delegate {
  96. public:
  97. // Describes the type of a process for logging purposes.
  98. enum class ProcessType {
  99. kUnknownProcess = 0,
  100. kBrowserProcess = 1,
  101. kGPUProcess = 2,
  102. kRendererProcess = 3,
  103. kUtilityProcess = 4,
  104. kMax = kUtilityProcess
  105. };
  106. // Describes the type of a thread for logging purposes.
  107. enum class ThreadType {
  108. kIOThread = 0,
  109. kMainThread = 1,
  110. kThreadPoolThread = 2,
  111. kMax = kThreadPoolThread
  112. };
  113. // Notes on lifetime:
  114. // 1) The first invocation of the constructor will set the global instance
  115. // accessible through GetInstance().
  116. // 2) In production HangWatcher is always purposefuly leaked.
  117. // 3) If not leaked HangWatcher is always constructed and destructed from
  118. // the same thread.
  119. // 4) There can never be more than one instance of HangWatcher at a time.
  120. // The class is not base::Singleton derived because it needs to destroyed
  121. // in tests.
  122. HangWatcher();
  123. // Clears the global instance for the class.
  124. ~HangWatcher() override;
  125. HangWatcher(const HangWatcher&) = delete;
  126. HangWatcher& operator=(const HangWatcher&) = delete;
  127. static void CreateHangWatcherInstance();
  128. // Returns a non-owning pointer to the global HangWatcher instance.
  129. static HangWatcher* GetInstance();
  130. // Initializes HangWatcher. Must be called once on the main thread during
  131. // startup while single-threaded.
  132. static void InitializeOnMainThread(ProcessType process_type);
  133. // Returns the values that were set through InitializeOnMainThread() to their
  134. // default value. Used for testing since in prod initialization should happen
  135. // only once.
  136. static void UnitializeOnMainThreadForTesting();
  137. // Thread safe functions to verify if hang watching is activated. If called
  138. // before InitializeOnMainThread returns the default value which is false.
  139. static bool IsEnabled();
  140. static bool IsThreadPoolHangWatchingEnabled();
  141. static bool IsIOThreadHangWatchingEnabled();
  142. // Returns true if crash dump reporting is configured for any thread type.
  143. static bool IsCrashReportingEnabled();
  144. // Use to avoid capturing hangs for operations known to take unbounded time
  145. // like waiting for user input. WatchHangsInScope objects created after this
  146. // call will take effect. To resume watching for hangs create a new
  147. // WatchHangsInScope after the unbounded operation finishes.
  148. //
  149. // Example usage:
  150. // {
  151. // WatchHangsInScope scope_1;
  152. // {
  153. // WatchHangsInScope scope_2;
  154. // InvalidateActiveExpectations();
  155. // WaitForUserInput();
  156. // }
  157. //
  158. // WatchHangsInScope scope_4;
  159. // }
  160. //
  161. // WatchHangsInScope scope_5;
  162. //
  163. // In this example hang watching is disabled for WatchHangsInScopes 1 and 2
  164. // since they were both active at the time of the invalidation.
  165. // WatchHangsInScopes 4 and 5 are unaffected since they were created after the
  166. // end of the WatchHangsInScope that was current at the time of invalidation.
  167. //
  168. static void InvalidateActiveExpectations();
  169. // Sets up the calling thread to be monitored for threads. Returns a
  170. // ScopedClosureRunner that unregisters the thread. This closure has to be
  171. // called from the registered thread before it's joined. Returns a null
  172. // closure in the case where there is no HangWatcher instance to register the
  173. // thread with.
  174. [[nodiscard]] static ScopedClosureRunner RegisterThread(
  175. ThreadType thread_type);
  176. // Choose a closure to be run at the end of each call to Monitor(). Use only
  177. // for testing. Reentering the HangWatcher in the closure must be done with
  178. // care. It should only be done through certain testing functions because
  179. // deadlocks are possible.
  180. void SetAfterMonitorClosureForTesting(base::RepeatingClosure closure);
  181. // Choose a closure to be run instead of recording the hang. Used to test
  182. // that certain conditions hold true at the time of recording. Use only
  183. // for testing. Reentering the HangWatcher in the closure must be done with
  184. // care. It should only be done through certain testing functions because
  185. // deadlocks are possible.
  186. void SetOnHangClosureForTesting(base::RepeatingClosure closure);
  187. // Set a monitoring period other than the default. Use only for
  188. // testing.
  189. void SetMonitoringPeriodForTesting(base::TimeDelta period);
  190. // Choose a callback to invoke right after waiting to monitor in Wait(). Use
  191. // only for testing.
  192. void SetAfterWaitCallbackForTesting(
  193. RepeatingCallback<void(TimeTicks)> callback);
  194. // Force the monitoring loop to resume and evaluate whether to continue.
  195. // This can trigger a call to Monitor() or not depending on why the
  196. // HangWatcher thread is sleeping. Use only for testing.
  197. void SignalMonitorEventForTesting();
  198. // Call to make sure no more monitoring takes place. The
  199. // function is thread-safe and can be called at anytime but won't stop
  200. // monitoring that is currently taking place. Use only for testing.
  201. static void StopMonitoringForTesting();
  202. // Replace the clock used when calculating time spent
  203. // sleeping. Use only for testing.
  204. void SetTickClockForTesting(const base::TickClock* tick_clock);
  205. // Use to block until the hang is recorded. Allows the caller to halt
  206. // execution so it does not overshoot the hang watch target and result in a
  207. // non-actionable stack trace in the crash recorded.
  208. void BlockIfCaptureInProgress();
  209. // Begin executing the monitoring loop on the HangWatcher thread.
  210. void Start();
  211. // Returns the value of the crash key with the time since last system power
  212. // resume.
  213. std::string GetTimeSinceLastSystemPowerResumeCrashKeyValue() const;
  214. private:
  215. // See comment of ::RegisterThread() for details.
  216. [[nodiscard]] ScopedClosureRunner RegisterThreadInternal(
  217. ThreadType thread_type) LOCKS_EXCLUDED(watch_state_lock_);
  218. // Use to assert that functions are called on the monitoring thread.
  219. THREAD_CHECKER(hang_watcher_thread_checker_);
  220. // Use to assert that functions are called on the constructing thread.
  221. THREAD_CHECKER(constructing_thread_checker_);
  222. // Invoked on memory pressure signal.
  223. void OnMemoryPressure(
  224. base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
  225. #if !BUILDFLAG(IS_NACL)
  226. // Returns a ScopedCrashKeyString that sets the crash key with the time since
  227. // last critical memory pressure signal.
  228. [[nodiscard]] debug::ScopedCrashKeyString
  229. GetTimeSinceLastCriticalMemoryPressureCrashKey();
  230. #endif
  231. // Invoke base::debug::DumpWithoutCrashing() insuring that the stack frame
  232. // right under it in the trace belongs to HangWatcher for easier attribution.
  233. NOINLINE static void RecordHang();
  234. using HangWatchStates =
  235. std::vector<std::unique_ptr<internal::HangWatchState>>;
  236. // Used to save a snapshots of the state of hang watching during capture.
  237. // Only the state of hung threads is retained.
  238. class BASE_EXPORT WatchStateSnapShot {
  239. public:
  240. struct WatchStateCopy {
  241. base::TimeTicks deadline;
  242. base::PlatformThreadId thread_id;
  243. };
  244. WatchStateSnapShot();
  245. WatchStateSnapShot(const WatchStateSnapShot& other);
  246. ~WatchStateSnapShot();
  247. // Initialize the snapshot from provided data. |snapshot_time| can be
  248. // different than now() to be coherent with other operations recently done
  249. // on |watch_states|. |hung_watch_state_copies_| can be empty after
  250. // initialization for a number of reasons:
  251. // 1. If any deadline in |watch_states| is before
  252. // |deadline_ignore_threshold|.
  253. // 2. If some of the hung threads could not be marked as blocking on
  254. // capture.
  255. // 3. If none of the hung threads are of a type configured to trigger a
  256. // crash dump.
  257. //
  258. // This function cannot be called more than once without an associated call
  259. // to Clear().
  260. void Init(const HangWatchStates& watch_states,
  261. base::TimeTicks deadline_ignore_threshold);
  262. // Reset the snapshot object to be reused. Can only be called after Init().
  263. void Clear();
  264. // Returns a string that contains the ids of the hung threads separated by a
  265. // '|'. The size of the string is capped at debug::CrashKeySize::Size256. If
  266. // no threads are hung returns an empty string. Can only be invoked if
  267. // IsActionable(). Can only be called after Init().
  268. std::string PrepareHungThreadListCrashKey() const;
  269. // Return the highest deadline included in this snapshot. Can only be called
  270. // if IsActionable(). Can only be called after Init().
  271. base::TimeTicks GetHighestDeadline() const;
  272. // Returns true if the snapshot can be used to record an actionable hang
  273. // report and false if not. Can only be called after Init().
  274. bool IsActionable() const;
  275. private:
  276. bool initialized_ = false;
  277. std::vector<WatchStateCopy> hung_watch_state_copies_;
  278. };
  279. // Return a watch state snapshot taken Now() to be inspected in tests.
  280. // NO_THREAD_SAFETY_ANALYSIS is needed because the analyzer can't figure out
  281. // that calls to this function done from |on_hang_closure_| are properly
  282. // locked.
  283. WatchStateSnapShot GrabWatchStateSnapshotForTesting() const
  284. NO_THREAD_SAFETY_ANALYSIS;
  285. // Inspects the state of all registered threads to check if they are hung and
  286. // invokes the appropriate closure if so.
  287. void Monitor() LOCKS_EXCLUDED(watch_state_lock_);
  288. // Record the hang crash dump and perform the necessary housekeeping before
  289. // and after.
  290. void DoDumpWithoutCrashing(const WatchStateSnapShot& watch_state_snapshot)
  291. EXCLUSIVE_LOCKS_REQUIRED(watch_state_lock_) LOCKS_EXCLUDED(capture_lock_);
  292. // Stop all monitoring and join the HangWatcher thread.
  293. void Stop();
  294. // Wait until it's time to monitor.
  295. void Wait();
  296. // Run the loop that periodically monitors the registered thread at a
  297. // set time interval.
  298. void Run() override;
  299. base::TimeDelta monitor_period_;
  300. // Use to make the HangWatcher thread wake or sleep to schedule the
  301. // appropriate monitoring frequency.
  302. WaitableEvent should_monitor_;
  303. bool IsWatchListEmpty() LOCKS_EXCLUDED(watch_state_lock_);
  304. // Stops hang watching on the calling thread by removing the entry from the
  305. // watch list.
  306. void UnregisterThread() LOCKS_EXCLUDED(watch_state_lock_);
  307. Lock watch_state_lock_;
  308. std::vector<std::unique_ptr<internal::HangWatchState>> watch_states_
  309. GUARDED_BY(watch_state_lock_);
  310. // Snapshot to be reused across hang captures. The point of keeping it
  311. // around is reducing allocations during capture.
  312. WatchStateSnapShot watch_state_snapshot_
  313. GUARDED_BY_CONTEXT(hang_watcher_thread_checker_);
  314. base::DelegateSimpleThread thread_;
  315. RepeatingClosure after_monitor_closure_for_testing_;
  316. RepeatingClosure on_hang_closure_for_testing_;
  317. RepeatingCallback<void(TimeTicks)> after_wait_callback_;
  318. base::Lock capture_lock_ ACQUIRED_AFTER(watch_state_lock_);
  319. std::atomic<bool> capture_in_progress_{false};
  320. raw_ptr<const base::TickClock> tick_clock_;
  321. // Registration to receive memory pressure signals.
  322. base::MemoryPressureListener memory_pressure_listener_;
  323. // The last time at which a critical memory pressure signal was received, or
  324. // null if no signal was ever received. Atomic because it's set and read from
  325. // different threads.
  326. std::atomic<base::TimeTicks> last_critical_memory_pressure_{
  327. base::TimeTicks()};
  328. // The time after which all deadlines in |watch_states_| need to be for a hang
  329. // to be reported.
  330. base::TimeTicks deadline_ignore_threshold_;
  331. FRIEND_TEST_ALL_PREFIXES(HangWatcherTest, NestedScopes);
  332. FRIEND_TEST_ALL_PREFIXES(HangWatcherSnapshotTest, HungThreadIDs);
  333. FRIEND_TEST_ALL_PREFIXES(HangWatcherSnapshotTest, NonActionableReport);
  334. };
  335. // Classes here are exposed in the header only for testing. They are not
  336. // intended to be used outside of base.
  337. namespace internal {
  338. // Threadsafe class that manages a deadline of type TimeTicks alongside hang
  339. // watching specific flags. The flags are stored in the higher bits of the
  340. // underlying TimeTicks deadline. This enables setting the flags on thread T1 in
  341. // a way that's resilient to concurrent deadline or flag changes from thread T2.
  342. // Flags can be queried separately from the deadline and users of this class
  343. // should not have to care about them when doing so.
  344. class BASE_EXPORT HangWatchDeadline {
  345. public:
  346. // Masks to set flags by flipping a single bit in the TimeTicks value. There
  347. // are two types of flags. Persistent flags remain set through a deadline
  348. // change and non-persistent flags are cleared when the deadline changes.
  349. enum class Flag : uint64_t {
  350. // Minimum value for validation purposes. Not currently used.
  351. kMinValue = bits::LeftmostBit<uint64_t>() >> 7,
  352. // Persistent because if hang detection is disabled on a thread it should
  353. // be re-enabled manually.
  354. kIgnoreCurrentWatchHangsInScope = bits::LeftmostBit<uint64_t>() >> 1,
  355. // Non-persistent because a new value means a new WatchHangsInScope started
  356. // after the beginning of capture. It can't be implicated in the hang so we
  357. // don't want it to block.
  358. kShouldBlockOnHang = bits::LeftmostBit<uint64_t>() >> 0,
  359. kMaxValue = kShouldBlockOnHang
  360. };
  361. HangWatchDeadline();
  362. ~HangWatchDeadline();
  363. // HangWatchDeadline should never be copied. To keep a copy of the deadline or
  364. // flags use the appropriate accessors.
  365. HangWatchDeadline(const HangWatchDeadline&) = delete;
  366. HangWatchDeadline& operator=(const HangWatchDeadline&) = delete;
  367. // Returns the underlying TimeTicks deadline. WARNING: The deadline and flags
  368. // can change concurrently. To inspect both, use GetFlagsAndDeadline() to get
  369. // a coherent race-free view of the state.
  370. TimeTicks GetDeadline() const;
  371. // Returns a mask containing the flags and the deadline as a pair. Use to
  372. // inspect the flags and deadline and then optionally call
  373. // SetShouldBlockOnHang() .
  374. std::pair<uint64_t, TimeTicks> GetFlagsAndDeadline() const;
  375. // Returns true if the flag is set and false if not. WARNING: The deadline and
  376. // flags can change concurrently. To inspect both, use GetFlagsAndDeadline()
  377. // to get a coherent race-free view of the state.
  378. bool IsFlagSet(Flag flag) const;
  379. // Returns true if a flag is set in |flags| and false if not. Use to inspect
  380. // the flags mask returned by GetFlagsAndDeadline(). WARNING: The deadline and
  381. // flags can change concurrently. If you need to inspect both you need to use
  382. // GetFlagsAndDeadline() to get a coherent race-free view of the state.
  383. static bool IsFlagSet(Flag flag, uint64_t flags);
  384. // Replace the deadline value. |new_value| needs to be within [0,
  385. // Max()]. This function can never fail.
  386. void SetDeadline(TimeTicks new_value);
  387. // Sets the kShouldBlockOnHang flag and returns true if current flags and
  388. // deadline are still equal to |old_flags| and |old_deadline|. Otherwise does
  389. // not set the flag and returns false.
  390. bool SetShouldBlockOnHang(uint64_t old_flags, TimeTicks old_deadline);
  391. // Sets the kIgnoreCurrentWatchHangsInScope flag.
  392. void SetIgnoreCurrentWatchHangsInScope();
  393. // Clears the kIgnoreCurrentWatchHangsInScope flag.
  394. void UnsetIgnoreCurrentWatchHangsInScope();
  395. // Use to simulate the value of |bits_| changing between the calling a
  396. // Set* function and the moment of atomically switching the values. The
  397. // callback should return a value containing the desired flags and deadline
  398. // bits. The flags that are already set will be preserved upon applying. Use
  399. // only for testing.
  400. void SetSwitchBitsClosureForTesting(
  401. RepeatingCallback<uint64_t(void)> closure);
  402. // Remove the deadline modification callback for when testing is done. Use
  403. // only for testing.
  404. void ResetSwitchBitsClosureForTesting();
  405. private:
  406. using TimeTicksInternalRepresentation =
  407. std::invoke_result<decltype(&TimeTicks::ToInternalValue),
  408. TimeTicks>::type;
  409. static_assert(std::is_same<TimeTicksInternalRepresentation, int64_t>::value,
  410. "Bit manipulations made by HangWatchDeadline need to be"
  411. "adapted if internal representation of TimeTicks changes.");
  412. // Replace the bits with the ones provided through the callback. Preserves the
  413. // flags that were already set. Returns the switched in bits. Only call if
  414. // |switch_bits_callback_for_testing_| is installed.
  415. uint64_t SwitchBitsForTesting();
  416. // Atomically sets persitent flag |flag|. Cannot fail.
  417. void SetPersistentFlag(Flag flag);
  418. // Atomically clears persitent flag |flag|. Cannot fail.
  419. void ClearPersistentFlag(Flag flag);
  420. // Converts bits to TimeTicks with some sanity checks. Use to return the
  421. // deadline outside of this class.
  422. static TimeTicks DeadlineFromBits(uint64_t bits);
  423. // Returns the largest representable deadline.
  424. static TimeTicks Max();
  425. // Extract the flag bits from |bits|.
  426. static uint64_t ExtractFlags(uint64_t bits);
  427. // Extract the deadline bits from |bits|.
  428. static uint64_t ExtractDeadline(uint64_t bits);
  429. // BitsType is uint64_t. This type is chosen for having
  430. // std::atomic<BitsType>{}.is_lock_free() true on many platforms and having no
  431. // undefined behaviors with regards to bit shift operations. Throughout this
  432. // class this is the only type that is used to store, retrieve and manipulate
  433. // the bits. When returning a TimeTicks value outside this class it's
  434. // necessary to run the proper checks to insure correctness of the conversion
  435. // that has to go through int_64t. (See DeadlineFromBits()).
  436. using BitsType = uint64_t;
  437. static_assert(std::is_same<std::underlying_type<Flag>::type, BitsType>::value,
  438. "Flag should have the same underlying type as bits_ to "
  439. "simplify thinking about bit operations");
  440. // Holds the bits of both the flags and the TimeTicks deadline.
  441. // TimeTicks values represent a count of microseconds since boot which may or
  442. // may not include suspend time depending on the platform. Using the seven
  443. // highest order bits and the sign bit to store flags still enables the
  444. // storing of TimeTicks values that can represent up to ~1142 years of uptime
  445. // in the remaining bits. Should never be directly accessed from outside the
  446. // class. Starts out at Max() to provide a base-line deadline that will not be
  447. // reached during normal execution.
  448. //
  449. // Binary format: 0xFFDDDDDDDDDDDDDDDD
  450. // F = Flags
  451. // D = Deadline
  452. std::atomic<BitsType> bits_{static_cast<uint64_t>(Max().ToInternalValue())};
  453. RepeatingCallback<uint64_t(void)> switch_bits_callback_for_testing_;
  454. THREAD_CHECKER(thread_checker_);
  455. FRIEND_TEST_ALL_PREFIXES(HangWatchDeadlineTest, BitsPreservedThroughExtract);
  456. };
  457. // Contains the information necessary for hang watching a specific
  458. // thread. Instances of this class are accessed concurrently by the associated
  459. // thread and the HangWatcher. The HangWatcher owns instances of this
  460. // class and outside of it they are accessed through
  461. // GetHangWatchStateForCurrentThread().
  462. class BASE_EXPORT HangWatchState {
  463. public:
  464. // |thread_type| is the type of thread the watch state will
  465. // be associated with. It's the responsibility of the creating
  466. // code to choose the correct type.
  467. explicit HangWatchState(HangWatcher::ThreadType thread_type);
  468. ~HangWatchState();
  469. HangWatchState(const HangWatchState&) = delete;
  470. HangWatchState& operator=(const HangWatchState&) = delete;
  471. // Allocates a new state object bound to the calling thread and returns an
  472. // owning pointer to it.
  473. static std::unique_ptr<HangWatchState> CreateHangWatchStateForCurrentThread(
  474. HangWatcher::ThreadType thread_type);
  475. // Retrieves the hang watch state associated with the calling thread.
  476. // Returns nullptr if no HangWatchState exists for the current thread (see
  477. // CreateHangWatchStateForCurrentThread()).
  478. static ThreadLocalPointer<HangWatchState>*
  479. GetHangWatchStateForCurrentThread();
  480. // Returns the current deadline. Use this function if you need to
  481. // store the value. To test if the deadline has expired use IsOverDeadline().
  482. // WARNING: The deadline and flags can change concurrently. If you need to
  483. // inspect both you need to use GetFlagsAndDeadline() to get a coherent
  484. // race-free view of the state.
  485. TimeTicks GetDeadline() const;
  486. // Returns a mask containing the hang watching flags and the value as a pair.
  487. // Use to inspect the flags and deadline and optionally call
  488. // SetShouldBlockOnHang(flags, deadline).
  489. std::pair<uint64_t, TimeTicks> GetFlagsAndDeadline() const;
  490. // Sets the deadline to a new value.
  491. void SetDeadline(TimeTicks deadline);
  492. // Mark this thread as ignored for hang watching. This means existing
  493. // WatchHangsInScope will not trigger hangs.
  494. void SetIgnoreCurrentWatchHangsInScope();
  495. // Reactivate hang watching on this thread. Should be called when all
  496. // WatchHangsInScope instances that were ignored have completed.
  497. void UnsetIgnoreCurrentWatchHangsInScope();
  498. // Mark the current state as having to block in its destruction until hang
  499. // capture completes.
  500. bool SetShouldBlockOnHang(uint64_t old_flags, TimeTicks old_deadline);
  501. // Returns true if |flag| is set and false if not. WARNING: The deadline and
  502. // flags can change concurrently. If you need to inspect both you need to use
  503. // GetFlagsAndDeadline() to get a coherent race-free view of the state.
  504. bool IsFlagSet(HangWatchDeadline::Flag flag);
  505. // Tests whether the associated thread's execution has gone over the deadline.
  506. bool IsOverDeadline() const;
  507. #if DCHECK_IS_ON()
  508. // Saves the supplied WatchHangsInScope as the currently active
  509. // WatchHangsInScope.
  510. void SetCurrentWatchHangsInScope(WatchHangsInScope* scope);
  511. // Retrieve the currently active scope.
  512. WatchHangsInScope* GetCurrentWatchHangsInScope();
  513. #endif
  514. PlatformThreadId GetThreadID() const;
  515. // Retrieve the current hang watch deadline directly. For testing only.
  516. HangWatchDeadline* GetHangWatchDeadlineForTesting();
  517. // Returns the current nesting level.
  518. int nesting_level() { return nesting_level_; }
  519. // Increase the nesting level by 1;
  520. void IncrementNestingLevel();
  521. // Reduce the nesting level by 1;
  522. void DecrementNestingLevel();
  523. // Returns the type of the thread under watch.
  524. HangWatcher::ThreadType thread_type() const { return thread_type_; }
  525. private:
  526. // The thread that creates the instance should be the class that updates
  527. // the deadline.
  528. THREAD_CHECKER(thread_checker_);
  529. // If the deadline fails to be updated before TimeTicks::Now() ever
  530. // reaches the value contained in it this constistutes a hang.
  531. HangWatchDeadline deadline_;
  532. // A unique ID of the thread under watch. Used for logging in crash reports
  533. // only.
  534. PlatformThreadId thread_id_;
  535. // Number of active HangWatchScopeEnables on this thread.
  536. int nesting_level_ = 0;
  537. // The type of the thread under watch.
  538. const HangWatcher::ThreadType thread_type_;
  539. #if DCHECK_IS_ON()
  540. // Used to keep track of the current WatchHangsInScope and detect improper
  541. // usage. Scopes should always be destructed in reverse order from the one
  542. // they were constructed in. Example of improper use:
  543. //
  544. // {
  545. // std::unique_ptr<Scope> scope = std::make_unique<Scope>(...);
  546. // Scope other_scope;
  547. // |scope| gets deallocated first, violating reverse destruction order.
  548. // scope.reset();
  549. // }
  550. raw_ptr<WatchHangsInScope> current_watch_hangs_in_scope_{nullptr};
  551. #endif
  552. };
  553. } // namespace internal
  554. } // namespace base
  555. #endif // BASE_THREADING_HANG_WATCHER_H_