Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: chrome_frame/crash_reporting/vectored_handler_unittest.cc

Issue 872004: Heuristically avoid reporting crashes during DLL loading.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <atlbase.h> 5 #include <atlbase.h>
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "chrome_frame/crash_reporting/crash_dll.h"
9 #include "chrome_frame/crash_reporting/nt_loader.h"
8 #include "chrome_frame/crash_reporting/vectored_handler-impl.h" 10 #include "chrome_frame/crash_reporting/vectored_handler-impl.h"
9 #include "chrome_frame/crash_reporting/veh_test.h" 11 #include "chrome_frame/crash_reporting/veh_test.h"
10 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
12 14
13 using testing::_; 15 using testing::_;
14 16
15 ACTION_P(StackTraceDump, s) { 17 ACTION_P(StackTraceDump, s) {
16 memcpy(arg2, s->stack_, s->count_ * sizeof(s->stack_[0])); 18 memcpy(arg2, s->stack_, s->count_ * sizeof(s->stack_[0]));
17 return s->count_; 19 return s->count_;
(...skipping 20 matching lines...) Expand all
38 void SetStack(const StackHelper& s) { 40 void SetStack(const StackHelper& s) {
39 EXPECT_CALL(*this, RtlCaptureStackBackTrace(_, _, _, _)) 41 EXPECT_CALL(*this, RtlCaptureStackBackTrace(_, _, _, _))
40 .Times(testing::AnyNumber()) 42 .Times(testing::AnyNumber())
41 .WillRepeatedly(StackTraceDump(&s)); 43 .WillRepeatedly(StackTraceDump(&s));
42 } 44 }
43 45
44 enum {max_back_trace = 15}; 46 enum {max_back_trace = 15};
45 }; 47 };
46 }; // namespace 48 }; // namespace
47 49
50 typedef VectoredHandlerT<MockApi> VectoredHandlerMock;
51 static VectoredHandlerMock* g_mock_veh = NULL;
52 static LONG WINAPI VEH(EXCEPTION_POINTERS* exptrs) {
53 return g_mock_veh->Handler(exptrs);
54 }
48 55
49 typedef VectoredHandlerT<MockApi> VectoredHandlerMock;
50 TEST(ChromeFrame, ExceptionReport) { 56 TEST(ChromeFrame, ExceptionReport) {
51 MockApi api; 57 MockApi api;
52 VectoredHandlerMock veh(&api); 58 VectoredHandlerMock veh(&api);
53 59
54 // Start address of our module. 60 // Start address of our module.
55 char* s = reinterpret_cast<char*>(0x30000000); 61 char* s = reinterpret_cast<char*>(0x30000000);
56 char *e = s + 0x10000; 62 char *e = s + 0x10000;
57 api.SetModule(s, e); 63 api.SetModule(s, e);
58 64
59 SEHChain have_seh(s - 0x1000, s + 0x1000, e + 0x7127, NULL); 65 SEHChain have_seh(s - 0x1000, s + 0x1000, e + 0x7127, NULL);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 veh.Handler(&ExceptionInfo(STATUS_ACCESS_VIOLATION, ignore_address))); 121 veh.Handler(&ExceptionInfo(STATUS_ACCESS_VIOLATION, ignore_address)));
116 testing::Mock::VerifyAndClearExpectations(&api); 122 testing::Mock::VerifyAndClearExpectations(&api);
117 123
118 // Exception, in IsBadStringPtrA, we are not on the stack. 124 // Exception, in IsBadStringPtrA, we are not on the stack.
119 api.SetSEH(no_seh); 125 api.SetSEH(no_seh);
120 api.SetStack(not_on_stack); 126 api.SetStack(not_on_stack);
121 EXPECT_CALL(api, WriteDump(_)).Times(0); 127 EXPECT_CALL(api, WriteDump(_)).Times(0);
122 EXPECT_EQ(ExceptionContinueSearch, 128 EXPECT_EQ(ExceptionContinueSearch,
123 veh.Handler(&ExceptionInfo(STATUS_ACCESS_VIOLATION, ignore_address))); 129 veh.Handler(&ExceptionInfo(STATUS_ACCESS_VIOLATION, ignore_address)));
124 testing::Mock::VerifyAndClearExpectations(&api); 130 testing::Mock::VerifyAndClearExpectations(&api);
131
132 // Exception in a loading module, we are on the stack.
133 // Make sure we don't report it.
134 api.SetSEH(no_seh);
135 api.SetStack(on_stack);
136 EXPECT_CALL(api, WriteDump(_)).Times(0);
137
138 g_mock_veh = &veh;
139 void* id = ::AddVectoredExceptionHandler(FALSE, VEH);
140
141 EXPECT_TRUE(::SetEnvironmentVariable(kCrashOnLoadMode, L"1"));
142 long exceptions_seen = veh.get_exceptions_seen();
143 HMODULE module = ::LoadLibrary(kCrashDllName);
144 EXPECT_EQ(NULL, module);
145
146 testing::Mock::VerifyAndClearExpectations(&api);
147 EXPECT_EQ(exceptions_seen + 1, veh.get_exceptions_seen());
148 EXPECT_TRUE(::SetEnvironmentVariable(kCrashOnLoadMode, NULL));
149
150 // Exception in an unloading module, we are on the stack/
151 // Make sure we report it.
152 EXPECT_TRUE(::SetEnvironmentVariable(kCrashOnUnloadMode, L"1"));
153
154 module = ::LoadLibrary(kCrashDllName);
155
156 api.SetSEH(no_seh);
157 api.SetStack(on_stack);
158 EXPECT_CALL(api, WriteDump(_)).Times(1);
159 EXPECT_TRUE(module != NULL);
160 exceptions_seen = veh.get_exceptions_seen();
161
162 // Crash on unloading.
163 ::FreeLibrary(module);
164
165 EXPECT_EQ(exceptions_seen + 1, veh.get_exceptions_seen());
166 testing::Mock::VerifyAndClearExpectations(&api);
167
168 ::RemoveVectoredExceptionHandler(id);
169 g_mock_veh = NULL;
125 } 170 }
126 171
127 MATCHER_P(ExceptionCodeIs, code, "") { 172 MATCHER_P(ExceptionCodeIs, code, "") {
128 return (arg->ExceptionRecord->ExceptionCode == code); 173 return (arg->ExceptionRecord->ExceptionCode == code);
129 } 174 }
130 175
131 DECLSPEC_NOINLINE static void OverflowStack() { 176 DECLSPEC_NOINLINE static void OverflowStack() {
132 char tmp[1024 * 2048] = {0}; 177 char tmp[1024 * 2048] = {0};
133 GetSystemInfo(reinterpret_cast<SYSTEM_INFO*>(&tmp)); 178 GetSystemInfo(reinterpret_cast<SYSTEM_INFO*>(&tmp));
134 } 179 }
135 180
136 DWORD WINAPI CrashingThread(PVOID tmp) { 181 DWORD WINAPI CrashingThread(PVOID tmp) {
137 __try { 182 __try {
138 OverflowStack(); 183 OverflowStack();
139 } __except(EXCEPTION_EXECUTE_HANDLER) { 184 } __except(EXCEPTION_EXECUTE_HANDLER) {
140 185
141 } 186 }
142 187
143 // This will cause STATUS_ACCESS_VIOLATION 188 // This will cause STATUS_ACCESS_VIOLATION
144 __try { 189 __try {
145 OverflowStack(); 190 OverflowStack();
146 } __except(EXCEPTION_EXECUTE_HANDLER) { 191 } __except(EXCEPTION_EXECUTE_HANDLER) {
147 192
148 } 193 }
149 194
150 return 0; 195 return 0;
151 } 196 }
152 197
153 static VectoredHandlerMock* g_mock_veh = NULL;
154 static LONG WINAPI VEH(EXCEPTION_POINTERS* exptrs) {
155 return g_mock_veh->Handler(exptrs);
156 }
157
158 TEST(ChromeFrame, TrickyStackOverflow) { 198 TEST(ChromeFrame, TrickyStackOverflow) {
159 MockApi api; 199 MockApi api;
160 VectoredHandlerMock veh(&api); 200 VectoredHandlerMock veh(&api);
161 201
162 // Start address of our module. 202 // Start address of our module.
163 char* s = reinterpret_cast<char*>(0x30000000); 203 char* s = reinterpret_cast<char*>(0x30000000);
164 char *e = s + 0x10000; 204 char *e = s + 0x10000;
165 api.SetModule(s, e); 205 api.SetModule(s, e);
166 206
167 SEHChain no_seh(s - 0x1000, e + 0x7127, NULL); 207 SEHChain no_seh(s - 0x1000, e + 0x7127, NULL);
168 StackHelper on_stack(s - 0x11283, s - 0x278361, s + 0x9171, e + 1231, NULL); 208 StackHelper on_stack(s - 0x11283, s - 0x278361, s + 0x9171, e + 1231, NULL);
169 api.SetSEH(no_seh); 209 api.SetSEH(no_seh);
170 api.SetStack(on_stack); 210 api.SetStack(on_stack);
171 211
172 EXPECT_CALL(api, WriteDump(ExceptionCodeIs(STATUS_STACK_OVERFLOW))).Times(1); 212 EXPECT_CALL(api, WriteDump(ExceptionCodeIs(STATUS_STACK_OVERFLOW))).Times(1);
173 213
174 g_mock_veh = &veh; 214 g_mock_veh = &veh;
175 void* id = ::AddVectoredExceptionHandler(FALSE, VEH); 215 void* id = ::AddVectoredExceptionHandler(FALSE, VEH);
176 216
177 DWORD tid; 217 DWORD tid;
178 HANDLE h = ::CreateThread(0, 0, CrashingThread, 0, 0, &tid); 218 HANDLE h = ::CreateThread(0, 0, CrashingThread, 0, 0, &tid);
179 ::WaitForSingleObject(h, INFINITE); 219 ::WaitForSingleObject(h, INFINITE);
180 ::CloseHandle(h); 220 ::CloseHandle(h);
181 221
182 EXPECT_EQ(2, veh.get_exceptions_seen()); 222 EXPECT_EQ(2, veh.get_exceptions_seen());
183 ::RemoveVectoredExceptionHandler(id); 223 ::RemoveVectoredExceptionHandler(id);
184 g_mock_veh = NULL; 224 g_mock_veh = NULL;
185 } 225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698