Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: util/win/process_info_test.cc

Issue 1369833002: win: Gather memory information (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@save-peb-stuff
Patch Set: . Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/win/process_info.cc ('k') | util/win/process_info_test_child.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Crashpad Authors. All rights reserved. 1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "util/win/process_info.h" 15 #include "util/win/process_info.h"
16 16
17 #include <imagehlp.h> 17 #include <imagehlp.h>
18 #include <intrin.h>
18 #include <wchar.h> 19 #include <wchar.h>
19 20
20 #include "base/files/file_path.h" 21 #include "base/files/file_path.h"
21 #include "build/build_config.h" 22 #include "build/build_config.h"
22 #include "gtest/gtest.h" 23 #include "gtest/gtest.h"
23 #include "test/paths.h" 24 #include "test/paths.h"
24 #include "test/win/child_launcher.h" 25 #include "test/win/child_launcher.h"
25 #include "util/file/file_io.h" 26 #include "util/file/file_io.h"
26 #include "util/misc/uuid.h" 27 #include "util/misc/uuid.h"
27 #include "util/win/scoped_handle.h" 28 #include "util/win/scoped_handle.h"
(...skipping 20 matching lines...) Expand all
48 if (!is_wow64_process) 49 if (!is_wow64_process)
49 return false; 50 return false;
50 BOOL is_wow64; 51 BOOL is_wow64;
51 if (!is_wow64_process(process_handle, &is_wow64)) { 52 if (!is_wow64_process(process_handle, &is_wow64)) {
52 PLOG(ERROR) << "IsWow64Process"; 53 PLOG(ERROR) << "IsWow64Process";
53 return false; 54 return false;
54 } 55 }
55 return is_wow64; 56 return is_wow64;
56 } 57 }
57 58
59 void VerifyAddressInInCodePage(const ProcessInfo& process_info,
60 WinVMAddress code_address) {
61 // Make sure the child code address is an code page address with the right
62 // information.
63 const std::vector<ProcessInfo::MemoryInfo>& memory_info =
64 process_info.MemoryInformation();
65 bool found_region = false;
66 for (const auto& mi : memory_info) {
67 if (mi.base_address <= code_address &&
68 mi.base_address + mi.region_size > code_address) {
69 EXPECT_EQ(MEM_COMMIT, mi.state);
70 EXPECT_EQ(PAGE_EXECUTE_READ, mi.protect);
71 EXPECT_EQ(MEM_IMAGE, mi.type);
72 EXPECT_FALSE(found_region);
73 found_region = true;
74 }
75 }
76 EXPECT_TRUE(found_region);
77 }
78
58 TEST(ProcessInfo, Self) { 79 TEST(ProcessInfo, Self) {
59 ProcessInfo process_info; 80 ProcessInfo process_info;
60 ASSERT_TRUE(process_info.Initialize(GetCurrentProcess())); 81 ASSERT_TRUE(process_info.Initialize(GetCurrentProcess()));
61 EXPECT_EQ(GetCurrentProcessId(), process_info.ProcessID()); 82 EXPECT_EQ(GetCurrentProcessId(), process_info.ProcessID());
62 EXPECT_GT(process_info.ParentProcessID(), 0u); 83 EXPECT_GT(process_info.ParentProcessID(), 0u);
63 84
64 #if defined(ARCH_CPU_64_BITS) 85 #if defined(ARCH_CPU_64_BITS)
65 EXPECT_TRUE(process_info.Is64Bit()); 86 EXPECT_TRUE(process_info.Is64Bit());
66 EXPECT_FALSE(process_info.IsWow64()); 87 EXPECT_FALSE(process_info.IsWow64());
67 #else 88 #else
(...skipping 26 matching lines...) Expand all
94 reinterpret_cast<uintptr_t>(GetModuleHandle(L"ntdll.dll"))); 115 reinterpret_cast<uintptr_t>(GetModuleHandle(L"ntdll.dll")));
95 116
96 EXPECT_GT(modules[0].size, 0); 117 EXPECT_GT(modules[0].size, 0);
97 EXPECT_GT(modules[1].size, 0); 118 EXPECT_GT(modules[1].size, 0);
98 119
99 EXPECT_EQ(modules[0].timestamp, 120 EXPECT_EQ(modules[0].timestamp,
100 GetTimestampForModule(GetModuleHandle(nullptr))); 121 GetTimestampForModule(GetModuleHandle(nullptr)));
101 // System modules are forced to particular stamps and the file header values 122 // System modules are forced to particular stamps and the file header values
102 // don't match the on-disk times. Just make sure we got some data here. 123 // don't match the on-disk times. Just make sure we got some data here.
103 EXPECT_GT(modules[1].timestamp, 0); 124 EXPECT_GT(modules[1].timestamp, 0);
125
126 // Find something we know is a code address and confirm expected memory
127 // information settings.
128 VerifyAddressInInCodePage(process_info,
129 reinterpret_cast<WinVMAddress>(_ReturnAddress()));
104 } 130 }
105 131
106 void TestOtherProcess(const base::string16& directory_modification) { 132 void TestOtherProcess(const base::string16& directory_modification) {
107 ProcessInfo process_info; 133 ProcessInfo process_info;
108 134
109 UUID started_uuid(UUID::InitializeWithNewTag{});
110 UUID done_uuid(UUID::InitializeWithNewTag{}); 135 UUID done_uuid(UUID::InitializeWithNewTag{});
111 136
112 ScopedKernelHANDLE started(
113 CreateEvent(nullptr, true, false, started_uuid.ToString16().c_str()));
114 ASSERT_TRUE(started.get());
115 ScopedKernelHANDLE done( 137 ScopedKernelHANDLE done(
116 CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str())); 138 CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str()));
117 ASSERT_TRUE(done.get()); 139 ASSERT_TRUE(done.get());
118 140
119 base::FilePath test_executable = Paths::Executable(); 141 base::FilePath test_executable = Paths::Executable();
120 142
121 std::wstring child_test_executable = 143 std::wstring child_test_executable =
122 test_executable.DirName() 144 test_executable.DirName()
123 .Append(directory_modification) 145 .Append(directory_modification)
124 .Append(test_executable.BaseName().RemoveFinalExtension().value() + 146 .Append(test_executable.BaseName().RemoveFinalExtension().value() +
125 L"_process_info_test_child.exe") 147 L"_process_info_test_child.exe")
126 .value(); 148 .value();
127 149
128 std::wstring args; 150 std::wstring args;
129 AppendCommandLineArgument(started_uuid.ToString16(), &args);
130 args += L" ";
131 AppendCommandLineArgument(done_uuid.ToString16(), &args); 151 AppendCommandLineArgument(done_uuid.ToString16(), &args);
132 152
133 ChildLauncher child(child_test_executable, args); 153 ChildLauncher child(child_test_executable, args);
134 child.Start(); 154 child.Start();
135 155
136 // Wait until the test has completed initialization. 156 // The child sends us a code address we can look up in the memory map.
137 ASSERT_EQ(WaitForSingleObject(started.get(), INFINITE), WAIT_OBJECT_0); 157 WinVMAddress code_address;
158 CheckedReadFile(
159 child.stdout_read_handle(), &code_address, sizeof(code_address));
138 160
139 ASSERT_TRUE(process_info.Initialize(child.process_handle())); 161 ASSERT_TRUE(process_info.Initialize(child.process_handle()));
140 162
141 // Tell the test it's OK to shut down now that we've read our data. 163 // Tell the test it's OK to shut down now that we've read our data.
142 SetEvent(done.get()); 164 EXPECT_TRUE(SetEvent(done.get()));
143 165
144 std::vector<ProcessInfo::Module> modules; 166 std::vector<ProcessInfo::Module> modules;
145 EXPECT_TRUE(process_info.Modules(&modules)); 167 EXPECT_TRUE(process_info.Modules(&modules));
146 ASSERT_GE(modules.size(), 3u); 168 ASSERT_GE(modules.size(), 3u);
147 std::wstring child_name = L"\\crashpad_util_test_process_info_test_child.exe"; 169 std::wstring child_name = L"\\crashpad_util_test_process_info_test_child.exe";
148 ASSERT_GE(modules[0].name.size(), child_name.size()); 170 ASSERT_GE(modules[0].name.size(), child_name.size());
149 EXPECT_EQ(child_name, 171 EXPECT_EQ(child_name,
150 modules[0].name.substr(modules[0].name.size() - child_name.size())); 172 modules[0].name.substr(modules[0].name.size() - child_name.size()));
151 ASSERT_GE(modules[1].name.size(), wcslen(kNtdllName)); 173 ASSERT_GE(modules[1].name.size(), wcslen(kNtdllName));
152 EXPECT_EQ( 174 EXPECT_EQ(
153 kNtdllName, 175 kNtdllName,
154 modules[1].name.substr(modules[1].name.size() - wcslen(kNtdllName))); 176 modules[1].name.substr(modules[1].name.size() - wcslen(kNtdllName)));
155 // lz32.dll is an uncommonly-used-but-always-available module that the test 177 // lz32.dll is an uncommonly-used-but-always-available module that the test
156 // binary manually loads. 178 // binary manually loads.
157 const wchar_t kLz32dllName[] = L"\\lz32.dll"; 179 const wchar_t kLz32dllName[] = L"\\lz32.dll";
158 ASSERT_GE(modules.back().name.size(), wcslen(kLz32dllName)); 180 ASSERT_GE(modules.back().name.size(), wcslen(kLz32dllName));
159 EXPECT_EQ(kLz32dllName, 181 EXPECT_EQ(kLz32dllName,
160 modules.back().name.substr(modules.back().name.size() - 182 modules.back().name.substr(modules.back().name.size() -
161 wcslen(kLz32dllName))); 183 wcslen(kLz32dllName)));
184
185 VerifyAddressInInCodePage(process_info, code_address);
162 } 186 }
163 187
164 TEST(ProcessInfo, OtherProcess) { 188 TEST(ProcessInfo, OtherProcess) {
165 TestOtherProcess(FILE_PATH_LITERAL(".")); 189 TestOtherProcess(FILE_PATH_LITERAL("."));
166 } 190 }
167 191
168 #if defined(ARCH_CPU_64_BITS) 192 #if defined(ARCH_CPU_64_BITS)
169 TEST(ProcessInfo, OtherProcessWOW64) { 193 TEST(ProcessInfo, OtherProcessWOW64) {
170 #ifndef NDEBUG 194 #ifndef NDEBUG
171 TestOtherProcess(FILE_PATH_LITERAL("..\\..\\out\\Debug")); 195 TestOtherProcess(FILE_PATH_LITERAL("..\\..\\out\\Debug"));
172 #else 196 #else
173 TestOtherProcess(FILE_PATH_LITERAL("..\\..\\out\\Release")); 197 TestOtherProcess(FILE_PATH_LITERAL("..\\..\\out\\Release"));
174 #endif 198 #endif
175 } 199 }
176 #endif // ARCH_CPU_64_BITS 200 #endif // ARCH_CPU_64_BITS
177 201
178 } // namespace 202 } // namespace
179 } // namespace test 203 } // namespace test
180 } // namespace crashpad 204 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/win/process_info.cc ('k') | util/win/process_info_test_child.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698