| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "chrome_frame/crash_reporting/nt_loader.h" | 4 #include "chrome_frame/crash_reporting/nt_loader.h" |
| 5 | 5 |
| 6 #include <tlhelp32.h> | 6 #include <tlhelp32.h> |
| 7 #include <winnt.h> | 7 #include <winnt.h> |
| 8 #include <base/at_exit.h> | 8 #include <base/at_exit.h> |
| 9 #include <base/environment.h> |
| 9 #include <base/message_loop.h> | 10 #include <base/message_loop.h> |
| 10 #include <base/scoped_handle.h> | 11 #include <base/scoped_handle.h> |
| 12 #include <base/scoped_ptr.h> |
| 11 #include <base/string_util.h> | 13 #include <base/string_util.h> |
| 12 #include <base/sys_info.h> | 14 #include <base/sys_info.h> |
| 13 #include <base/thread.h> | 15 #include <base/thread.h> |
| 16 #include <base/utf_string_conversions.h> |
| 14 #include "chrome_frame/crash_reporting/crash_dll.h" | 17 #include "chrome_frame/crash_reporting/crash_dll.h" |
| 15 #include "gtest/gtest.h" | 18 #include "gtest/gtest.h" |
| 16 | 19 |
| 17 namespace { | 20 namespace { |
| 18 void AssertIsCriticalSection(CRITICAL_SECTION* critsec) { | 21 void AssertIsCriticalSection(CRITICAL_SECTION* critsec) { |
| 19 // Assert on some of the internals of the debug info if it has one. | 22 // Assert on some of the internals of the debug info if it has one. |
| 20 RTL_CRITICAL_SECTION_DEBUG* debug = critsec->DebugInfo; | 23 RTL_CRITICAL_SECTION_DEBUG* debug = critsec->DebugInfo; |
| 21 if (debug) { | 24 if (debug) { |
| 22 ASSERT_EQ(RTL_CRITSECT_TYPE, debug->Type); | 25 ASSERT_EQ(RTL_CRITSECT_TYPE, debug->Type); |
| 23 ASSERT_EQ(critsec, debug->CriticalSection); | 26 ASSERT_EQ(critsec, debug->CriticalSection); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 ~NtLoaderTest() { | 187 ~NtLoaderTest() { |
| 185 EXPECT_TRUE(this == current_); | 188 EXPECT_TRUE(this == current_); |
| 186 current_ = NULL; | 189 current_ = NULL; |
| 187 } | 190 } |
| 188 | 191 |
| 189 void SetUp() { | 192 void SetUp() { |
| 190 veh_id_ = ::AddVectoredExceptionHandler(FALSE, &ExceptionHandler); | 193 veh_id_ = ::AddVectoredExceptionHandler(FALSE, &ExceptionHandler); |
| 191 EXPECT_TRUE(veh_id_ != NULL); | 194 EXPECT_TRUE(veh_id_ != NULL); |
| 192 | 195 |
| 193 // Clear the crash DLL environment. | 196 // Clear the crash DLL environment. |
| 194 ::SetEnvironmentVariable(kCrashOnLoadMode, NULL); | 197 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 195 ::SetEnvironmentVariable(kCrashOnUnloadMode, NULL); | 198 env->UnSetVar(WideToASCII(kCrashOnLoadMode).c_str()); |
| 199 env->UnSetVar(WideToASCII(kCrashOnUnloadMode).c_str()); |
| 196 } | 200 } |
| 197 | 201 |
| 198 void TearDown() { | 202 void TearDown() { |
| 199 if (veh_id_ != NULL) | 203 if (veh_id_ != NULL) |
| 200 EXPECT_NE(0, ::RemoveVectoredExceptionHandler(veh_id_)); | 204 EXPECT_NE(0, ::RemoveVectoredExceptionHandler(veh_id_)); |
| 201 | 205 |
| 202 // Clear the crash DLL environment. | 206 // Clear the crash DLL environment. |
| 203 ::SetEnvironmentVariable(kCrashOnLoadMode, NULL); | 207 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 204 ::SetEnvironmentVariable(kCrashOnUnloadMode, NULL); | 208 env->UnSetVar(WideToASCII(kCrashOnLoadMode).c_str()); |
| 209 env->UnSetVar(WideToASCII(kCrashOnUnloadMode).c_str()); |
| 205 } | 210 } |
| 206 | 211 |
| 207 void set_exception_function(ExceptionFunction func) { | 212 void set_exception_function(ExceptionFunction func) { |
| 208 exception_function_ = func; | 213 exception_function_ = func; |
| 209 } | 214 } |
| 210 | 215 |
| 211 private: | 216 private: |
| 212 static LONG NTAPI ExceptionHandler(EXCEPTION_POINTERS* ex_ptrs){ | 217 static LONG NTAPI ExceptionHandler(EXCEPTION_POINTERS* ex_ptrs){ |
| 213 // Dispatch the exception to any exception function, | 218 // Dispatch the exception to any exception function, |
| 214 // but only on the main thread. | 219 // but only on the main thread. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 nt_loader::LDR_DATA_TABLE_ENTRY* entry = GetLoaderEntry(crash_dll); | 257 nt_loader::LDR_DATA_TABLE_ENTRY* entry = GetLoaderEntry(crash_dll); |
| 253 ASSERT_TRUE(entry != NULL); | 258 ASSERT_TRUE(entry != NULL); |
| 254 ASSERT_EQ(0, entry->Flags & LDRP_PROCESS_ATTACH_CALLED); | 259 ASSERT_EQ(0, entry->Flags & LDRP_PROCESS_ATTACH_CALLED); |
| 255 } | 260 } |
| 256 | 261 |
| 257 TEST_F(NtLoaderTest, CrashOnLoadLibrary) { | 262 TEST_F(NtLoaderTest, CrashOnLoadLibrary) { |
| 258 exceptions_handled = 0; | 263 exceptions_handled = 0; |
| 259 set_exception_function(OnCrashDuringLoadLibrary); | 264 set_exception_function(OnCrashDuringLoadLibrary); |
| 260 | 265 |
| 261 // Setup to crash on load. | 266 // Setup to crash on load. |
| 262 ::SetEnvironmentVariable(kCrashOnLoadMode, L"1"); | 267 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 268 env->SetVar(WideToASCII(kCrashOnLoadMode).c_str(), "1"); |
| 263 | 269 |
| 264 // And load it. | 270 // And load it. |
| 265 HMODULE module = ::LoadLibrary(kCrashDllName); | 271 HMODULE module = ::LoadLibrary(kCrashDllName); |
| 266 DWORD err = ::GetLastError(); | 272 DWORD err = ::GetLastError(); |
| 267 EXPECT_EQ(NULL, module); | 273 EXPECT_EQ(NULL, module); |
| 268 EXPECT_EQ(ERROR_NOACCESS, err); | 274 EXPECT_EQ(ERROR_NOACCESS, err); |
| 269 EXPECT_EQ(1, exceptions_handled); | 275 EXPECT_EQ(1, exceptions_handled); |
| 270 | 276 |
| 271 if (module != NULL) | 277 if (module != NULL) |
| 272 ::FreeLibrary(module); | 278 ::FreeLibrary(module); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 287 | 293 |
| 288 HMODULE crash_dll = ::GetModuleHandle(kCrashDllName); | 294 HMODULE crash_dll = ::GetModuleHandle(kCrashDllName); |
| 289 ASSERT_TRUE(crash_dll == NULL); | 295 ASSERT_TRUE(crash_dll == NULL); |
| 290 | 296 |
| 291 nt_loader::LDR_DATA_TABLE_ENTRY* entry = GetLoaderEntry(crash_dll); | 297 nt_loader::LDR_DATA_TABLE_ENTRY* entry = GetLoaderEntry(crash_dll); |
| 292 ASSERT_TRUE(entry == NULL); | 298 ASSERT_TRUE(entry == NULL); |
| 293 } | 299 } |
| 294 | 300 |
| 295 TEST_F(NtLoaderTest, CrashOnUnloadLibrary) { | 301 TEST_F(NtLoaderTest, CrashOnUnloadLibrary) { |
| 296 // Setup to crash on unload. | 302 // Setup to crash on unload. |
| 297 ::SetEnvironmentVariable(kCrashOnUnloadMode, L"1"); | 303 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 304 env->SetVar(WideToASCII(kCrashOnUnloadMode).c_str(), "1"); |
| 298 | 305 |
| 299 // And load it. | 306 // And load it. |
| 300 HMODULE module = ::LoadLibrary(kCrashDllName); | 307 HMODULE module = ::LoadLibrary(kCrashDllName); |
| 301 EXPECT_TRUE(module != NULL); | 308 EXPECT_TRUE(module != NULL); |
| 302 | 309 |
| 303 exceptions_handled = 0; | 310 exceptions_handled = 0; |
| 304 set_exception_function(OnCrashDuringUnloadLibrary); | 311 set_exception_function(OnCrashDuringUnloadLibrary); |
| 305 | 312 |
| 306 // We should crash during unload. | 313 // We should crash during unload. |
| 307 if (module != NULL) | 314 if (module != NULL) |
| 308 ::FreeLibrary(module); | 315 ::FreeLibrary(module); |
| 309 | 316 |
| 310 EXPECT_EQ(1, exceptions_handled); | 317 EXPECT_EQ(1, exceptions_handled); |
| 311 } | 318 } |
| OLD | NEW |