1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Declares the memory profiler class, which is responsible for gathering
16 : // memory statistics by hooking the Heap API. This class isn't much more than
17 : // a thin wrapper for the FunctionCallLogger right now, but will likely grow
18 : // to maintain and log other state.
19 :
20 : #ifndef SYZYGY_AGENT_MEMPROF_MEMORY_PROFILER_H_
21 : #define SYZYGY_AGENT_MEMPROF_MEMORY_PROFILER_H_
22 :
23 : #include "base/threading/thread_local.h"
24 : #include "syzygy/agent/common/agent.h"
25 : #include "syzygy/agent/common/dll_notifications.h"
26 : #include "syzygy/agent/common/thread_state.h"
27 : #include "syzygy/agent/memprof/function_call_logger.h"
28 : #include "syzygy/agent/memprof/parameters.h"
29 : #include "syzygy/common/logging.h"
30 : #include "syzygy/trace/client/rpc_session.h"
31 :
32 m : namespace agent {
33 m : namespace memprof {
34 :
35 m : class MemoryProfiler {
36 m : public:
37 m : MemoryProfiler();
38 :
39 : // Initializes this memory profiler.
40 : // @returns true for success, false otherwise.
41 m : bool Init();
42 :
43 : // @returns the active function call logger.
44 m : FunctionCallLogger& function_call_logger() {
45 m : return function_call_logger_;
46 m : }
47 :
48 : // Forward declaration.
49 m : class ThreadState;
50 :
51 : // @returns the thread state for the current thread, with an initialized
52 : // call trace segment. Allocates thread state if this is not already
53 : // done.
54 m : ThreadState* GetOrAllocateThreadState();
55 :
56 : // @returns the thread state, returning nullptr if none has yet been
57 : // allocated.
58 m : ThreadState* GetThreadState();
59 :
60 : // @returns the current parameters.
61 m : const Parameters& parameters() const { return parameters_; }
62 :
63 m : protected:
64 m : friend class ThreadState;
65 :
66 : // Propagates configured parameters to sub-components.
67 m : void PropagateParameters();
68 :
69 : // Returns the thread state for the current thread, but doesn't initialize
70 : // a call trace segment.
71 m : ThreadState* GetOrAllocateThreadStateImpl();
72 :
73 : // Logs all modules in the process, then flushes the current trace segment.
74 : // Logs using the current thread's segment.
75 m : void LogAllModules();
76 :
77 : // Logs @p module, using the current thread's segment.
78 m : void LogModule(HMODULE module);
79 :
80 : // Sink for DLL load/unload event notifications.
81 m : void OnDllEvent(agent::common::DllNotificationWatcher::EventType type,
82 m : HMODULE module,
83 m : size_t module_size,
84 m : const base::StringPiece16& dll_path,
85 m : const base::StringPiece16& dll_base_name);
86 :
87 : // Helper class for managing ThreadState lifetimes.
88 m : agent::common::ThreadStateManager thread_state_manager_;
89 :
90 : // Synchronizes access to various global state.
91 m : base::Lock lock_;
92 :
93 : // The RPC session we're logging to/through.
94 m : trace::client::RpcSession session_;
95 :
96 : // The function call logger that we use for detailed function call
97 : // events.
98 m : FunctionCallLogger function_call_logger_;
99 :
100 : // The parameters that we use. These are parsed from the environment.
101 m : Parameters parameters_;
102 :
103 : // To keep track of modules added after initialization.
104 m : agent::common::DllNotificationWatcher dll_watcher_;
105 :
106 : // Contains the set of modules we've seen and logged.
107 m : typedef base::hash_set<HMODULE> ModuleSet;
108 m : ModuleSet logged_modules_; // Under lock_.
109 :
110 : // This points to our per-thread state.
111 m : mutable base::ThreadLocalPointer<ThreadState> tls_;
112 :
113 m : private:
114 m : DISALLOW_COPY_AND_ASSIGN(MemoryProfiler);
115 m : };
116 :
117 : // Maintains thread specific memory profiler state, and provides convenient
118 : // logging methods.
119 m : class MemoryProfiler::ThreadState : public agent::common::ThreadStateBase {
120 m : public:
121 : // Initializes this thread state.
122 : // @param parent The memory profiler owning this thread state.
123 m : explicit ThreadState(MemoryProfiler* parent);
124 :
125 : // Flushes the active segment and gets a new one.
126 : // @returns true if all went well, false otherwise.
127 m : bool FlushSegment();
128 :
129 : // @returns the active trace file segment.
130 m : trace::client::TraceFileSegment* segment() {
131 m : return &segment_;
132 m : }
133 :
134 m : protected:
135 m : friend class MemoryProfiler;
136 :
137 : // Our parent memory profiler.
138 m : MemoryProfiler* parent_;
139 :
140 : // The active trace file segment where events are written.
141 m : trace::client::TraceFileSegment segment_;
142 :
143 m : private:
144 m : DISALLOW_COPY_AND_ASSIGN(ThreadState);
145 m : };
146 :
147 m : } // namespace memprof
148 m : } // namespace agent
149 :
150 : #endif // SYZYGY_AGENT_MEMPROF_MEMORY_PROFILER_H_
|