- add sources.
[platform/framework/web/crosswalk.git] / src / chrome_frame / crash_reporting / veh_test.cc
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
3 // found in the LICENSE file.
4
5 #include <atlbase.h>
6 #include "chrome_frame/crash_reporting/veh_test.h"
7 #include "testing/gmock/include/gmock/gmock.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "chrome_frame/crash_reporting/vectored_handler-impl.h"
10
11 #pragma code_seg(push, ".m$_0")
12 static void ModuleStart() {}
13 #pragma code_seg(pop)
14
15 #pragma code_seg(push, ".m$_2")
16 DECLSPEC_NOINLINE static void Undetectable(DWORD code) {
17   __try {
18     ::RaiseException(code, 0, 0, NULL);
19   } __except(EXCEPTION_EXECUTE_HANDLER) {
20
21   }
22 };
23 #pragma code_seg(pop)
24
25 #pragma code_seg(push, ".m$_3")
26 static void UndetectableEnd() {}
27 #pragma code_seg(pop)
28
29 #pragma code_seg(push, ".m$_4")
30 DECLSPEC_NOINLINE static void CatchThis() {
31   __try {
32     ::RaiseException(STATUS_ACCESS_VIOLATION, 0, 0, NULL);
33   } __except(EXCEPTION_EXECUTE_HANDLER) {
34
35   }
36
37   // this will be detected since we are on the stack!
38   Undetectable(STATUS_ILLEGAL_INSTRUCTION);
39 }
40 #pragma code_seg(pop)
41
42 #pragma code_seg(push, ".m$_9")
43 static void ModuleEnd() {}
44 #pragma code_seg(pop)
45
46 using testing::_;
47 namespace {
48 MATCHER_P(ExceptionCodeIs, code, "") {
49   return (arg->ExceptionRecord->ExceptionCode == code);
50 }
51
52 class MockApi : public Win32VEHTraits,
53                 public ModuleOfInterestWithExcludedRegion {
54  public:
55   MockApi() {
56     ModuleOfInterestWithExcludedRegion::SetModule(&ModuleStart, &ModuleEnd);
57     ModuleOfInterestWithExcludedRegion::SetExcludedRegion(&Undetectable,
58         &UndetectableEnd);
59   }
60
61   MOCK_METHOD1(WriteDump, void(const EXCEPTION_POINTERS*));
62   MOCK_METHOD0(RtlpGetExceptionList, const EXCEPTION_REGISTRATION_RECORD*());
63 };
64 };  // namespace
65
66 typedef VectoredHandlerT<MockApi> VectoredHandlerMock;
67
68 #pragma optimize("y", off)
69 static VectoredHandlerMock* g_mock_veh = NULL;
70 static LONG WINAPI VEH(EXCEPTION_POINTERS* exptrs) {
71   return g_mock_veh->Handler(exptrs);
72 }
73 #pragma optimize("y", on)
74
75 TEST(ChromeFrame, ExceptionExcludedCode) {
76   MockApi api;
77   VectoredHandlerMock veh(&api);
78
79   g_mock_veh = &veh;
80   void* id = ::AddVectoredExceptionHandler(FALSE, VEH);
81
82   EXPECT_CALL(api, RtlpGetExceptionList())
83       .WillRepeatedly(testing::Return(EXCEPTION_CHAIN_END));
84
85   testing::Sequence s;
86
87   EXPECT_CALL(api, WriteDump(ExceptionCodeIs(STATUS_ACCESS_VIOLATION)))
88     .Times(1);
89
90   EXPECT_CALL(api, WriteDump(ExceptionCodeIs(STATUS_ILLEGAL_INSTRUCTION)))
91       .Times(1);
92
93   CatchThis();
94   EXPECT_EQ(2, veh.get_exceptions_seen());
95
96   // Not detected since we are not on the stack.
97   Undetectable(STATUS_INTEGER_DIVIDE_BY_ZERO);
98   EXPECT_EQ(3, veh.get_exceptions_seen());
99
100   ::RemoveVectoredExceptionHandler(id);
101   g_mock_veh = NULL;
102 }