|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef mozilla_ThreadStackHelper_h |
|
7 #define mozilla_ThreadStackHelper_h |
|
8 |
|
9 #include "mozilla/ThreadHangStats.h" |
|
10 |
|
11 #include "GeckoProfiler.h" |
|
12 |
|
13 #include <stddef.h> |
|
14 |
|
15 #if defined(XP_LINUX) |
|
16 #include <signal.h> |
|
17 #include <semaphore.h> |
|
18 #include <sys/types.h> |
|
19 #elif defined(XP_WIN) |
|
20 #include <windows.h> |
|
21 #elif defined(XP_MACOSX) |
|
22 #include <mach/mach.h> |
|
23 #endif |
|
24 |
|
25 namespace mozilla { |
|
26 |
|
27 /** |
|
28 * ThreadStackHelper is used to retrieve the profiler pseudo-stack of a |
|
29 * thread, as an alternative of using the profiler to take a profile. |
|
30 * The target thread first declares an ThreadStackHelper instance; |
|
31 * then another thread can call ThreadStackHelper::GetStack to retrieve |
|
32 * the pseudo-stack of the target thread at that instant. |
|
33 * |
|
34 * Only non-copying labels are included in the stack, which means labels |
|
35 * with custom text and markers are not included. |
|
36 */ |
|
37 class ThreadStackHelper |
|
38 { |
|
39 public: |
|
40 typedef Telemetry::HangHistogram::Stack Stack; |
|
41 |
|
42 private: |
|
43 #ifdef MOZ_ENABLE_PROFILER_SPS |
|
44 const PseudoStack* const mPseudoStack; |
|
45 #endif |
|
46 Stack mStackBuffer; |
|
47 size_t mMaxStackSize; |
|
48 |
|
49 bool PrepareStackBuffer(Stack& aStack); |
|
50 void FillStackBuffer(); |
|
51 |
|
52 public: |
|
53 /** |
|
54 * Initialize ThreadStackHelper. Must be called from main thread. |
|
55 */ |
|
56 static void Startup(); |
|
57 /** |
|
58 * Uninitialize ThreadStackHelper. Must be called from main thread. |
|
59 */ |
|
60 static void Shutdown(); |
|
61 |
|
62 /** |
|
63 * Create a ThreadStackHelper instance targeting the current thread. |
|
64 */ |
|
65 ThreadStackHelper(); |
|
66 |
|
67 ~ThreadStackHelper(); |
|
68 |
|
69 /** |
|
70 * Retrieve the current pseudostack of the thread associated |
|
71 * with this ThreadStackHelper. |
|
72 * |
|
73 * @param aStack Stack instance to be filled. |
|
74 */ |
|
75 void GetStack(Stack& aStack); |
|
76 |
|
77 #if defined(XP_LINUX) |
|
78 private: |
|
79 static int sInitialized; |
|
80 static sem_t sSem; |
|
81 static struct sigaction sOldSigAction; |
|
82 static ThreadStackHelper* sCurrent; |
|
83 |
|
84 static void SigAction(int aSignal, siginfo_t* aInfo, void* aContext); |
|
85 |
|
86 pid_t mThreadID; |
|
87 |
|
88 #elif defined(XP_WIN) |
|
89 private: |
|
90 bool mInitialized; |
|
91 HANDLE mThreadID; |
|
92 |
|
93 #elif defined(XP_MACOSX) |
|
94 private: |
|
95 thread_act_t mThreadID; |
|
96 |
|
97 #endif |
|
98 }; |
|
99 |
|
100 } // namespace mozilla |
|
101 |
|
102 #endif // mozilla_ThreadStackHelper_h |