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

Side by Side Diff: base/profiler/win32_stack_frame_unwinder.cc

Issue 1465273002: Stack sampling profiler: remove RUNTIME_FUNCTION sanity check (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: make variations add to 100 Created 5 years 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 | « no previous file | base/profiler/win32_stack_frame_unwinder_unittest.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 Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/profiler/win32_stack_frame_unwinder.h" 5 #include "base/profiler/win32_stack_frame_unwinder.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/containers/hash_tables.h" 9 #include "base/containers/hash_tables.h"
10 #include "base/memory/singleton.h" 10 #include "base/memory/singleton.h"
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 blacklisted_modules_.insert(module); 152 blacklisted_modules_.insert(module);
153 } 153 }
154 154
155 LeafUnwindBlacklist::LeafUnwindBlacklist() {} 155 LeafUnwindBlacklist::LeafUnwindBlacklist() {}
156 LeafUnwindBlacklist::~LeafUnwindBlacklist() {} 156 LeafUnwindBlacklist::~LeafUnwindBlacklist() {}
157 157
158 } // namespace 158 } // namespace
159 159
160 // Win32StackFrameUnwinder ---------------------------------------------------- 160 // Win32StackFrameUnwinder ----------------------------------------------------
161 161
162 // hipis0e011b8.dll from McAfee Host Intrusion Prevention has been observed to
163 // provide a pointer to a bogus RUNTIME_FUNCTION structure. This function checks
164 // that the values in the structure look plausible.
165 bool SanityCheckRuntimeFunction(PRUNTIME_FUNCTION runtime_function,
166 ULONG64 image_base,
167 DWORD64 program_counter) {
168 const DWORD64 program_counter_offset = program_counter - image_base;
169 return (runtime_function->BeginAddress <= runtime_function->EndAddress &&
170 program_counter_offset >= runtime_function->BeginAddress &&
171 program_counter_offset <= runtime_function->EndAddress);
172 }
173
174 Win32StackFrameUnwinder::UnwindFunctions::~UnwindFunctions() {} 162 Win32StackFrameUnwinder::UnwindFunctions::~UnwindFunctions() {}
175 Win32StackFrameUnwinder::UnwindFunctions::UnwindFunctions() {} 163 Win32StackFrameUnwinder::UnwindFunctions::UnwindFunctions() {}
176 164
177 Win32StackFrameUnwinder::Win32StackFrameUnwinder() 165 Win32StackFrameUnwinder::Win32StackFrameUnwinder()
178 : Win32StackFrameUnwinder(make_scoped_ptr(new Win32UnwindFunctions)) { 166 : Win32StackFrameUnwinder(make_scoped_ptr(new Win32UnwindFunctions)) {
179 } 167 }
180 168
181 Win32StackFrameUnwinder::~Win32StackFrameUnwinder() {} 169 Win32StackFrameUnwinder::~Win32StackFrameUnwinder() {}
182 170
183 bool Win32StackFrameUnwinder::TryUnwind(CONTEXT* context, 171 bool Win32StackFrameUnwinder::TryUnwind(CONTEXT* context,
184 ScopedModuleHandle* module) { 172 ScopedModuleHandle* module) {
185 #ifdef _WIN64 173 #ifdef _WIN64
186 CHECK(!at_top_frame_ || unwind_info_present_for_all_frames_); 174 CHECK(!at_top_frame_ || unwind_info_present_for_all_frames_);
187 175
188 ScopedModuleHandle frame_module = 176 ScopedModuleHandle frame_module =
189 unwind_functions_->GetModuleForProgramCounter(context->Rip); 177 unwind_functions_->GetModuleForProgramCounter(context->Rip);
190 // The module may have been unloaded since we recorded the stack. Note that if 178 if (!frame_module.IsValid()) {
191 // this check detects module as valid, it still could be a different module at 179 // There's no loaded module containing the instruction pointer. This can be
192 // the same instruction pointer address (i.e. if the module was unloaded and a 180 // due to executing code that is not in a module. In particular,
193 // different module loaded in overlapping memory). This should occur extremely 181 // runtime-generated code associated with third-party injected DLLs
194 // rarely. 182 // typically is not in a module. It can also be due to the the module having
195 if (!frame_module.IsValid()) 183 // been unloaded since we recorded the stack. In the latter case the
184 // function unwind information was part of the unloaded module, so it's not
185 // possible to unwind further.
186 //
187 // If a module was found, it's still theoretically possible for the detected
188 // module module to be different than the one that was loaded when the stack
189 // was copied (i.e. if the module was unloaded and a different module loaded
190 // in overlapping memory). This likely would cause a crash, but has not been
191 // observed in practice.
196 return false; 192 return false;
193 }
197 194
198 ULONG64 image_base; 195 ULONG64 image_base;
199 // Try to look up unwind metadata for the current function. 196 // Try to look up unwind metadata for the current function.
200 PRUNTIME_FUNCTION runtime_function = 197 PRUNTIME_FUNCTION runtime_function =
201 unwind_functions_->LookupFunctionEntry(context->Rip, &image_base); 198 unwind_functions_->LookupFunctionEntry(context->Rip, &image_base);
202 199
203 if (runtime_function) { 200 if (runtime_function) {
204 if (!SanityCheckRuntimeFunction(runtime_function, image_base, context->Rip))
205 return false;
206
207 unwind_functions_->VirtualUnwind(image_base, context->Rip, runtime_function, 201 unwind_functions_->VirtualUnwind(image_base, context->Rip, runtime_function,
208 context); 202 context);
209 at_top_frame_ = false; 203 at_top_frame_ = false;
210 } else { 204 } else {
211 // RtlLookupFunctionEntry didn't find unwind information. This could mean 205 // RtlLookupFunctionEntry didn't find unwind information. This could mean
212 // the code at the instruction pointer is in: 206 // the code at the instruction pointer is in:
213 // 207 //
214 // 1. a true leaf function (i.e. a function that neither calls a function, 208 // 1. a true leaf function (i.e. a function that neither calls a function,
215 // nor allocates any stack space itself) in which case the return 209 // nor allocates any stack space itself) in which case the return
216 // address is at RSP, or 210 // address is at RSP, or
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 } 283 }
290 284
291 Win32StackFrameUnwinder::Win32StackFrameUnwinder( 285 Win32StackFrameUnwinder::Win32StackFrameUnwinder(
292 scoped_ptr<UnwindFunctions> unwind_functions) 286 scoped_ptr<UnwindFunctions> unwind_functions)
293 : at_top_frame_(true), 287 : at_top_frame_(true),
294 unwind_info_present_for_all_frames_(true), 288 unwind_info_present_for_all_frames_(true),
295 unwind_functions_(unwind_functions.Pass()) { 289 unwind_functions_(unwind_functions.Pass()) {
296 } 290 }
297 291
298 } // namespace base 292 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/profiler/win32_stack_frame_unwinder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698