Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/stack_trace.h" | 5 #include "base/debug/stack_trace.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <dbghelp.h> | 8 #include <dbghelp.h> |
| 9 | 9 |
| 10 #include <iostream> | 10 #include <iostream> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/singleton.h" | 14 #include "base/memory/singleton.h" |
| 15 #include "base/path_service.h" | |
| 15 #include "base/process_util.h" | 16 #include "base/process_util.h" |
| 17 #include "base/string_util.h" | |
| 16 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
| 19 #include "base/win/windows_version.h" | |
| 17 | 20 |
| 18 namespace base { | 21 namespace base { |
| 19 namespace debug { | 22 namespace debug { |
| 20 | 23 |
| 21 namespace { | 24 namespace { |
| 22 | 25 |
| 23 // Previous unhandled filter. Will be called if not NULL when we intercept an | 26 // Previous unhandled filter. Will be called if not NULL when we intercept an |
| 24 // exception. Only used in unit tests. | 27 // exception. Only used in unit tests. |
| 25 LPTOP_LEVEL_EXCEPTION_FILTER g_previous_filter = NULL; | 28 LPTOP_LEVEL_EXCEPTION_FILTER g_previous_filter = NULL; |
| 26 | 29 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 private: | 125 private: |
| 123 friend struct DefaultSingletonTraits<SymbolContext>; | 126 friend struct DefaultSingletonTraits<SymbolContext>; |
| 124 | 127 |
| 125 SymbolContext() : init_error_(ERROR_SUCCESS) { | 128 SymbolContext() : init_error_(ERROR_SUCCESS) { |
| 126 // Initializes the symbols for the process. | 129 // Initializes the symbols for the process. |
| 127 // Defer symbol load until they're needed, use undecorated names, and | 130 // Defer symbol load until they're needed, use undecorated names, and |
| 128 // get line numbers. | 131 // get line numbers. |
| 129 SymSetOptions(SYMOPT_DEFERRED_LOADS | | 132 SymSetOptions(SYMOPT_DEFERRED_LOADS | |
| 130 SYMOPT_UNDNAME | | 133 SYMOPT_UNDNAME | |
| 131 SYMOPT_LOAD_LINES); | 134 SYMOPT_LOAD_LINES); |
| 132 if (SymInitialize(GetCurrentProcess(), NULL, TRUE)) { | 135 if (!SymInitialize(GetCurrentProcess(), NULL, TRUE)) { |
| 133 init_error_ = ERROR_SUCCESS; | |
| 134 } else { | |
| 135 init_error_ = GetLastError(); | 136 init_error_ = GetLastError(); |
| 136 // TODO(awong): Handle error: SymInitialize can fail with | 137 // TODO(awong): Handle error: SymInitialize can fail with |
| 137 // ERROR_INVALID_PARAMETER. | 138 // ERROR_INVALID_PARAMETER. |
| 138 // When it fails, we should not call debugbreak since it kills the current | 139 // When it fails, we should not call debugbreak since it kills the current |
| 139 // process (prevents future tests from running or kills the browser | 140 // process (prevents future tests from running or kills the browser |
| 140 // process). | 141 // process). |
| 141 DLOG(ERROR) << "SymInitialize failed: " << init_error_; | 142 DLOG(ERROR) << "SymInitialize failed: " << init_error_; |
| 143 return; | |
| 144 } | |
| 145 | |
| 146 init_error_ = ERROR_SUCCESS; | |
| 147 | |
| 148 // Work around a mysterious hang on Windows XP. | |
| 149 if (base::win::GetVersion() < base::win::VERSION_VISTA) | |
| 150 return; | |
| 151 | |
| 152 // When transferring the binaries e.g. between bots, path put | |
| 153 // into the executable will get off. To still retrieve symbols correctly, | |
| 154 // add the directory of the executable to symbol search path. | |
| 155 // All following errors are non-fatal. | |
| 156 wchar_t symbols_path[1024]; | |
| 157 | |
| 158 // Note: The below function takes buffer size as number of characters, | |
| 159 // not number of bytes! | |
| 160 if (!SymGetSearchPathW(GetCurrentProcess(), | |
| 161 symbols_path, | |
| 162 arraysize(symbols_path))) { | |
| 163 DLOG(WARNING) << "SymGetSearchPath failed: "; | |
| 164 return; | |
| 165 } | |
| 166 | |
| 167 FilePath module_path; | |
| 168 if (!PathService::Get(FILE_EXE, &module_path)) { | |
| 169 DLOG(WARNING) << "PathService::Get(FILE_EXE) failed."; | |
|
cpu_(ooo_6.6-7.5)
2013/04/10 23:19:26
I would seem to me that we should avoid calling dl
Paweł Hajdan Jr.
2013/04/10 23:50:19
There was a DLOG here already and I think it's use
| |
| 170 return; | |
| 171 } | |
| 172 | |
| 173 std::wstring new_path(std::wstring(symbols_path) + | |
| 174 L";" + module_path.DirName().value()); | |
| 175 if (!SymSetSearchPathW(GetCurrentProcess(), new_path.c_str())) { | |
| 176 DLOG(WARNING) << "SymSetSearchPath failed."; | |
| 177 return; | |
| 142 } | 178 } |
| 143 } | 179 } |
| 144 | 180 |
| 145 DWORD init_error_; | 181 DWORD init_error_; |
| 146 base::Lock lock_; | 182 base::Lock lock_; |
| 147 DISALLOW_COPY_AND_ASSIGN(SymbolContext); | 183 DISALLOW_COPY_AND_ASSIGN(SymbolContext); |
| 148 }; | 184 }; |
| 149 | 185 |
| 150 } // namespace | 186 } // namespace |
| 151 | 187 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 (*os) << "\t" << trace_[i] << "\n"; | 262 (*os) << "\t" << trace_[i] << "\n"; |
| 227 } | 263 } |
| 228 } else { | 264 } else { |
| 229 (*os) << "Backtrace:\n"; | 265 (*os) << "Backtrace:\n"; |
| 230 context->OutputTraceToStream(trace_, count_, os); | 266 context->OutputTraceToStream(trace_, count_, os); |
| 231 } | 267 } |
| 232 } | 268 } |
| 233 | 269 |
| 234 } // namespace debug | 270 } // namespace debug |
| 235 } // namespace base | 271 } // namespace base |
| OLD | NEW |