OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/message_loop/message_loop.h" | |
6 #include "base/win/wrapped_window_proc.h" | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 | |
9 namespace { | |
10 | |
11 DWORD kExceptionCode = 12345; | |
12 WPARAM kCrashMsg = 98765; | |
13 | |
14 // A trivial WindowProc that generates an exception. | |
15 LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT message, | |
16 WPARAM wparam, LPARAM lparam) { | |
17 if (message == kCrashMsg) | |
18 RaiseException(kExceptionCode, 0, 0, NULL); | |
19 return DefWindowProc(hwnd, message, wparam, lparam); | |
20 } | |
21 | |
22 // This class implements an exception filter that can be queried about a past | |
23 // exception. | |
24 class TestWrappedExceptionFiter { | |
25 public: | |
26 TestWrappedExceptionFiter() : called_(false) { | |
27 EXPECT_FALSE(s_filter_); | |
28 s_filter_ = this; | |
29 } | |
30 | |
31 ~TestWrappedExceptionFiter() { | |
32 EXPECT_EQ(s_filter_, this); | |
33 s_filter_ = NULL; | |
34 } | |
35 | |
36 bool called() { | |
37 return called_; | |
38 } | |
39 | |
40 // The actual exception filter just records the exception. | |
41 static int Filter(EXCEPTION_POINTERS* info) { | |
42 EXPECT_FALSE(s_filter_->called_); | |
43 if (info->ExceptionRecord->ExceptionCode == kExceptionCode) | |
44 s_filter_->called_ = true; | |
45 return EXCEPTION_EXECUTE_HANDLER; | |
46 } | |
47 | |
48 private: | |
49 bool called_; | |
50 static TestWrappedExceptionFiter* s_filter_; | |
51 }; | |
52 TestWrappedExceptionFiter* TestWrappedExceptionFiter::s_filter_ = NULL; | |
53 | |
54 } // namespace. | |
55 | |
56 TEST(WrappedWindowProc, CatchesExceptions) { | |
57 HINSTANCE hinst = GetModuleHandle(NULL); | |
58 std::wstring class_name(L"TestClass"); | |
59 | |
60 WNDCLASS wc = {0}; | |
61 wc.lpfnWndProc = base::win::WrappedWindowProc<TestWindowProc>; | |
62 wc.hInstance = hinst; | |
63 wc.lpszClassName = class_name.c_str(); | |
64 RegisterClass(&wc); | |
65 | |
66 HWND window = CreateWindow(class_name.c_str(), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, | |
67 0, hinst, 0); | |
68 ASSERT_TRUE(window); | |
69 | |
70 // Before generating the exception we make sure that the filter will see it. | |
71 TestWrappedExceptionFiter wrapper; | |
72 base::win::WinProcExceptionFilter old_filter = | |
73 base::win::SetWinProcExceptionFilter(TestWrappedExceptionFiter::Filter); | |
74 | |
75 SendMessage(window, kCrashMsg, 0, 0); | |
76 EXPECT_TRUE(wrapper.called()); | |
77 | |
78 base::win::SetWinProcExceptionFilter(old_filter); | |
79 } | |
OLD | NEW |