1 : // Copyright 2011 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 : // Implementation class to gather per-process, per-module working set
16 : // statistics.
17 :
18 : #ifndef SYZYGY_WSDUMP_PROCESS_WORKING_SET_H_
19 : #define SYZYGY_WSDUMP_PROCESS_WORKING_SET_H_
20 :
21 : #include <windows.h>
22 : #include <memory>
23 : #include <string>
24 : #include <vector>
25 :
26 : namespace core {
27 : template <typename AddressType, typename SizeType, typename ItemType>
28 : class AddressSpace;
29 : };
30 : struct _PSAPI_WORKING_SET_INFORMATION;
31 : typedef struct _PSAPI_WORKING_SET_INFORMATION PSAPI_WORKING_SET_INFORMATION;
32 :
33 : namespace wsdump {
34 :
35 : // Captures working set for a given process at a point in time,
36 : // summarizes per-module as well as overall statistics.
37 : class ProcessWorkingSet {
38 : public:
39 : // Non-module stats.
40 : struct Stats {
41 E : Stats() { memset(this, 0, sizeof(*this)); }
42 :
43 : size_t pages;
44 : size_t shareable_pages;
45 : size_t shared_pages;
46 : size_t read_only_pages;
47 : size_t writable_pages;
48 : size_t executable_pages;
49 : };
50 :
51 : // Per-module stats.
52 : struct ModuleStats : public Stats {
53 : std::wstring module_name;
54 : };
55 : typedef std::vector<ModuleStats> ModuleStatsVector;
56 :
57 : // Initialize working set statistics for the given process_id.
58 : // @returns true on success, false on failure.
59 : // @note total_stats(), non_module_stats() and module_stats() are valid only
60 : // after a successful call call to Initialize.
61 : bool Initialize(DWORD process_id);
62 :
63 : // @returns overall tally for the whole process.
64 E : const Stats& total_stats() const { return total_stats_; }
65 :
66 : // @returns tally for working set pages that don't belong to modules,
67 : // e.g. pages that belong to heaps, stacks, mapped files, etc.
68 E : const Stats& non_module_stats() const { return non_module_stats_; }
69 :
70 : // @returns per module tallies.
71 E : const ModuleStatsVector& module_stats() const { return module_stats_; }
72 :
73 : protected:
74 : // These are protected members to allow unittesting them.
75 : typedef std::unique_ptr<PSAPI_WORKING_SET_INFORMATION> ScopedWsPtr;
76 : static bool CaptureWorkingSet(HANDLE process, ScopedWsPtr* working_set);
77 :
78 : typedef core::AddressSpace<size_t, size_t, std::wstring> ModuleAddressSpace;
79 : static bool CaptureModules(DWORD process_id, ModuleAddressSpace* modules);
80 :
81 : // Storage for stats.
82 : Stats total_stats_;
83 : Stats non_module_stats_;
84 : ModuleStatsVector module_stats_;
85 : };
86 :
87 : } // namespace wsdump
88 :
89 : #endif // SYZYGY_WSDUMP_PROCESS_WORKING_SET_H_
|