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.
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"
11 #pragma code_seg(push, ".m$_0")
12 static void ModuleStart() {}
15 #pragma code_seg(push, ".m$_2")
16 DECLSPEC_NOINLINE
static void Undetectable(DWORD code
) {
18 ::RaiseException(code
, 0, 0, NULL
);
19 } __except(EXCEPTION_EXECUTE_HANDLER
) {
25 #pragma code_seg(push, ".m$_3")
26 static void UndetectableEnd() {}
29 #pragma code_seg(push, ".m$_4")
30 DECLSPEC_NOINLINE
static void CatchThis() {
32 ::RaiseException(STATUS_ACCESS_VIOLATION
, 0, 0, NULL
);
33 } __except(EXCEPTION_EXECUTE_HANDLER
) {
37 // this will be detected since we are on the stack!
38 Undetectable(STATUS_ILLEGAL_INSTRUCTION
);
42 #pragma code_seg(push, ".m$_9")
43 static void ModuleEnd() {}
48 MATCHER_P(ExceptionCodeIs
, code
, "") {
49 return (arg
->ExceptionRecord
->ExceptionCode
== code
);
52 class MockApi
: public Win32VEHTraits
,
53 public ModuleOfInterestWithExcludedRegion
{
56 ModuleOfInterestWithExcludedRegion::SetModule(&ModuleStart
, &ModuleEnd
);
57 ModuleOfInterestWithExcludedRegion::SetExcludedRegion(&Undetectable
,
61 MOCK_METHOD1(WriteDump
, void(const EXCEPTION_POINTERS
*));
62 MOCK_METHOD0(RtlpGetExceptionList
, const EXCEPTION_REGISTRATION_RECORD
*());
66 typedef VectoredHandlerT
<MockApi
> VectoredHandlerMock
;
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
);
73 #pragma optimize("y", on)
75 TEST(ChromeFrame
, ExceptionExcludedCode
) {
77 VectoredHandlerMock
veh(&api
);
80 void* id
= ::AddVectoredExceptionHandler(FALSE
, VEH
);
82 EXPECT_CALL(api
, RtlpGetExceptionList())
83 .WillRepeatedly(testing::Return(EXCEPTION_CHAIN_END
));
87 EXPECT_CALL(api
, WriteDump(ExceptionCodeIs(STATUS_ACCESS_VIOLATION
)))
90 EXPECT_CALL(api
, WriteDump(ExceptionCodeIs(STATUS_ILLEGAL_INSTRUCTION
)))
94 EXPECT_EQ(2, veh
.get_exceptions_seen());
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());
100 ::RemoveVectoredExceptionHandler(id
);