summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authormad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-20 18:55:39 +0000
committermad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-20 18:55:39 +0000
commite32e1792b61a0183fc48d4ee1cc79b7d8e89f0af (patch)
tree0e3bbc6171045171d505b503ed718e27d863e2c9 /chrome_frame
parentb5ffe4e348bab92834e34c99451f21cffc24a1e1 (diff)
downloadchromium_src-e32e1792b61a0183fc48d4ee1cc79b7d8e89f0af.zip
chromium_src-e32e1792b61a0183fc48d4ee1cc79b7d8e89f0af.tar.gz
chromium_src-e32e1792b61a0183fc48d4ee1cc79b7d8e89f0af.tar.bz2
For Steven Truong (stevet@)
Reviewed in: http://codereview.chromium.org/276068 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29543 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp1
-rw-r--r--chrome_frame/crash_reporting/crash_reporting.gyp14
-rw-r--r--chrome_frame/crash_reporting/vectored_handler_unittest.cc192
-rw-r--r--chrome_frame/test/chrome_frame_unittests.cc195
4 files changed, 215 insertions, 187 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 15ae357..3b9af9a 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -697,6 +697,7 @@
'../google_update/google_update.gyp:google_update',
# Crash Reporting
'crash_reporting/crash_reporting.gyp:crash_report',
+ 'crash_reporting/crash_reporting.gyp:vectored_handler_tests',
],
'msvs_settings': {
'VCLinkerTool': {
diff --git a/chrome_frame/crash_reporting/crash_reporting.gyp b/chrome_frame/crash_reporting/crash_reporting.gyp
index 14c0156..7d75184 100644
--- a/chrome_frame/crash_reporting/crash_reporting.gyp
+++ b/chrome_frame/crash_reporting/crash_reporting.gyp
@@ -30,6 +30,20 @@
}],
],
},
+ {
+ 'target_name': 'vectored_handler_tests',
+ 'type': 'executable',
+ 'sources': [
+ 'vectored_handler_unittest.cc',
+ ],
+ 'dependencies': [
+ 'crash_report',
+ '../../base/base.gyp:base',
+ '../../testing/gmock.gyp:gmock',
+ '../../testing/gtest.gyp:gtest',
+ '../../testing/gtest.gyp:gtestmain',
+ ],
+ },
],
}
diff --git a/chrome_frame/crash_reporting/vectored_handler_unittest.cc b/chrome_frame/crash_reporting/vectored_handler_unittest.cc
new file mode 100644
index 0000000..52c730a
--- /dev/null
+++ b/chrome_frame/crash_reporting/vectored_handler_unittest.cc
@@ -0,0 +1,192 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <atlbase.h>
+
+#include "base/logging.h"
+#include "chrome_frame/crash_reporting/vectored_handler-impl.h"
+#include "gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Class that mocks external call from VectoredHandlerT for testing purposes.
+class EMock : public VEHTraitsBase {
+ public:
+ static inline bool WriteDump(EXCEPTION_POINTERS* p) {
+ g_dump_made = true;
+ return true;
+ }
+
+ static inline void* Register(PVECTORED_EXCEPTION_HANDLER func,
+ const void* module_start,
+ const void* module_end) {
+ VEHTraitsBase::SetModule(module_start, module_end);
+ // Return some arbitrary number, expecting to get the same on Unregister()
+ return reinterpret_cast<void*>(4);
+ }
+
+ static inline ULONG Unregister(void* handle) {
+ EXPECT_EQ(handle, reinterpret_cast<void*>(4));
+ return 1;
+ }
+
+ static inline WORD RtlCaptureStackBackTrace(DWORD FramesToSkip,
+ DWORD FramesToCapture, void** BackTrace, DWORD* BackTraceHash) {
+ EXPECT_EQ(2, FramesToSkip);
+ EXPECT_LE(FramesToSkip + FramesToCapture,
+ VectoredHandlerBase::max_back_trace);
+ memcpy(BackTrace, g_stack, g_stack_entries * sizeof(BackTrace[0]));
+ return g_stack_entries;
+ }
+
+ static inline EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() {
+ return g_seh_chain;
+ }
+
+ // Test helpers
+
+ // Create fake SEH chain of random filters - with and without our module.
+ static void SetHaveSEHFilter() {
+ SetSEHChain(reinterpret_cast<const char*>(g_module_start) - 0x1000,
+ reinterpret_cast<const char*>(g_module_start) + 0x1000,
+ reinterpret_cast<const char*>(g_module_end) + 0x7127,
+ NULL);
+ }
+
+ static void SetNoSEHFilter() {
+ SetSEHChain(reinterpret_cast<const char*>(g_module_start) - 0x1000,
+ reinterpret_cast<const char*>(g_module_end) + 0x7127,
+ NULL);
+ }
+
+ // Create fake stack - with and without our module.
+ static void SetOnStack() {
+ SetStack(reinterpret_cast<const char*>(g_module_start) - 0x11283,
+ reinterpret_cast<const char*>(g_module_start) - 0x278361,
+ reinterpret_cast<const char*>(g_module_start) + 0x9171,
+ reinterpret_cast<const char*>(g_module_end) + 1231,
+ NULL);
+ }
+
+ static void SetNotOnStack() {
+ SetStack(reinterpret_cast<const char*>(g_module_start) - 0x11283,
+ reinterpret_cast<const char*>(g_module_start) - 0x278361,
+ reinterpret_cast<const char*>(g_module_end) + 1231,
+ NULL);
+ }
+
+ // Populate stack array
+ static void SetStack(const void* p, ...) {
+ va_list vl;
+ va_start(vl, p);
+ g_stack_entries = 0;
+ for (; p; ++g_stack_entries) {
+ CHECK(g_stack_entries < arraysize(g_stack));
+ g_stack[g_stack_entries] = p;
+ p = va_arg(vl, const void*);
+ }
+ }
+
+ static void SetSEHChain(const void* p, ...) {
+ va_list vl;
+ va_start(vl, p);
+ int i = 0;
+ for (; p; ++i) {
+ CHECK(i + 1 < arraysize(g_seh_chain));
+ g_seh_chain[i].Handler = const_cast<void*>(p);
+ g_seh_chain[i].Next = &g_seh_chain[i + 1];
+ p = va_arg(vl, const void*);
+ }
+
+ g_seh_chain[i].Next = EXCEPTION_CHAIN_END;
+ }
+
+ static EXCEPTION_REGISTRATION_RECORD g_seh_chain[25];
+ static const void* g_stack[VectoredHandlerBase::max_back_trace];
+ static WORD g_stack_entries;
+ static bool g_dump_made;
+};
+
+EXCEPTION_REGISTRATION_RECORD EMock::g_seh_chain[25];
+const void* EMock::g_stack[VectoredHandlerBase::max_back_trace];
+WORD EMock::g_stack_entries;
+bool EMock::g_dump_made;
+
+typedef VectoredHandlerT<EMock> VectoredHandlerMock;
+
+class ExPtrsHelper : public _EXCEPTION_POINTERS {
+ public:
+ ExPtrsHelper() {
+ ExceptionRecord = &er_;
+ ContextRecord = &ctx_;
+ ZeroMemory(&er_, sizeof(er_));
+ ZeroMemory(&ctx_, sizeof(ctx_));
+ }
+
+ void Set(DWORD code, void* address, DWORD flags) {
+ er_.ExceptionCode = code;
+ er_.ExceptionAddress = address;
+ er_.ExceptionFlags = flags;
+ }
+
+ EXCEPTION_RECORD er_;
+ CONTEXT ctx_;
+};
+
+
+TEST(ChromeFrame, ExceptionReport) {
+ char* s = reinterpret_cast<char*>(0x30000000);
+ char* e = s + 0x10000;
+ void* handler = VectoredHandlerMock::Register(s, e);
+ char* our_code = s + 0x1111;
+ char* not_our_code = s - 0x5555;
+ char* not_our_code2 = e + 0x5555;
+
+ ExPtrsHelper ex;
+ // Exception in our code, but we have SEH filter
+ ex.Set(STATUS_ACCESS_VIOLATION, our_code, 0);
+ EMock::SetHaveSEHFilter();
+ EMock::SetOnStack();
+ EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
+ EXPECT_EQ(1, VectoredHandlerMock::g_exceptions_seen);
+ EXPECT_FALSE(EMock::g_dump_made);
+
+ // RPC_E_DISCONNECTED (0x80010108) is "The object invoked has disconnected
+ // from its clients", shall not be caught since it's a warning only.
+ ex.Set(RPC_E_DISCONNECTED, our_code, 0);
+ EMock::SetHaveSEHFilter();
+ EMock::SetOnStack();
+ EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
+ EXPECT_EQ(1, VectoredHandlerMock::g_exceptions_seen);
+ EXPECT_FALSE(EMock::g_dump_made);
+
+
+ // Exception, not in our code, we do not have SEH and we are not in stack.
+ ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, not_our_code, 0);
+ EMock::SetNoSEHFilter();
+ EMock::SetNotOnStack();
+ EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
+ EXPECT_EQ(2, VectoredHandlerMock::g_exceptions_seen);
+ EXPECT_FALSE(EMock::g_dump_made);
+
+ // Exception, not in our code, no SEH, but we are on the stack.
+ ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, not_our_code2, 0);
+ EMock::SetNoSEHFilter();
+ EMock::SetOnStack();
+ EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
+ EXPECT_EQ(3, VectoredHandlerMock::g_exceptions_seen);
+ EXPECT_TRUE(EMock::g_dump_made);
+ EMock::g_dump_made = false;
+
+
+ // Exception, in our code, no SEH, not on stack (assume FPO screwed us)
+ ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, our_code, 0);
+ EMock::SetNoSEHFilter();
+ EMock::SetNotOnStack();
+ EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
+ EXPECT_EQ(4, VectoredHandlerMock::g_exceptions_seen);
+ EXPECT_TRUE(EMock::g_dump_made);
+ EMock::g_dump_made = false;
+
+ VectoredHandlerMock::Unregister();
+}
diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc
index 3c4cc94..5bf33c1 100644
--- a/chrome_frame/test/chrome_frame_unittests.cc
+++ b/chrome_frame/test/chrome_frame_unittests.cc
@@ -428,7 +428,8 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_CFInstanceNoSrc) {
const wchar_t kCFIIfrOnLoadPage[] = L"files/CFInstance_iframe_onload_host.html";
// disabled since it's unlikely that we care about this case
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceIfrOnLoad) {
+TEST_F(ChromeFrameTestWithWebServer,
+ DISABLED_WidgetModeIE_CFInstanceIfrOnLoad) {
SimpleBrowserTest(IE, kCFIIfrOnLoadPage, L"CFInstanceIfrOnLoad");
}
@@ -528,7 +529,8 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPCInternal) {
}
// Disabled: http://b/issue?id=2050201
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeFF_CFInstanceRPCInternal) {
+TEST_F(ChromeFrameTestWithWebServer,
+ DISABLED_WidgetModeFF_CFInstanceRPCInternal) {
SimpleBrowserTest(FIREFOX, kCFIRPCInternalPage, L"CFInstanceRPCInternal");
}
@@ -551,188 +553,6 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceDefaultCtor) {
SimpleBrowserTest(FIREFOX, kCFIDefaultCtorPage, L"CFInstanceDefaultCtor");
}
-// Class that mocks external call from VectoredHandlerT for testing purposes.
-class EMock : public VEHTraitsBase {
- public:
- static inline bool WriteDump(EXCEPTION_POINTERS* p) {
- g_dump_made = true;
- return true;
- }
-
- static inline void* Register(PVECTORED_EXCEPTION_HANDLER func,
- const void* module_start,
- const void* module_end) {
- VEHTraitsBase::SetModule(module_start, module_end);
- // Return some arbitrary number, expecting to get the same on Unregister()
- return reinterpret_cast<void*>(4);
- }
-
- static inline ULONG Unregister(void* handle) {
- EXPECT_EQ(handle, reinterpret_cast<void*>(4));
- return 1;
- }
-
- static inline WORD RtlCaptureStackBackTrace(DWORD FramesToSkip,
- DWORD FramesToCapture, void** BackTrace, DWORD* BackTraceHash) {
- EXPECT_EQ(2, FramesToSkip);
- EXPECT_LE(FramesToSkip + FramesToCapture,
- VectoredHandlerBase::max_back_trace);
- memcpy(BackTrace, g_stack, g_stack_entries * sizeof(BackTrace[0]));
- return g_stack_entries;
- }
-
- static inline EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() {
- return g_seh_chain;
- }
-
- // Test helpers
-
- // Create fake SEH chain of random filters - with and without our module.
- static void SetHaveSEHFilter() {
- SetSEHChain(reinterpret_cast<const char*>(g_module_start) - 0x1000,
- reinterpret_cast<const char*>(g_module_start) + 0x1000,
- reinterpret_cast<const char*>(g_module_end) + 0x7127,
- NULL);
- }
-
- static void SetNoSEHFilter() {
- SetSEHChain(reinterpret_cast<const char*>(g_module_start) - 0x1000,
- reinterpret_cast<const char*>(g_module_end) + 0x7127,
- NULL);
- }
-
- // Create fake stack - with and without our module.
- static void SetOnStack() {
- SetStack(reinterpret_cast<const char*>(g_module_start) - 0x11283,
- reinterpret_cast<const char*>(g_module_start) - 0x278361,
- reinterpret_cast<const char*>(g_module_start) + 0x9171,
- reinterpret_cast<const char*>(g_module_end) + 1231,
- NULL);
- }
-
- static void SetNotOnStack() {
- SetStack(reinterpret_cast<const char*>(g_module_start) - 0x11283,
- reinterpret_cast<const char*>(g_module_start) - 0x278361,
- reinterpret_cast<const char*>(g_module_end) + 1231,
- NULL);
- }
-
- // Populate stack array
- static void SetStack(const void* p, ...) {
- va_list vl;
- va_start(vl, p);
- g_stack_entries = 0;
- for (; p; ++g_stack_entries) {
- CHECK(g_stack_entries < arraysize(g_stack));
- g_stack[g_stack_entries] = p;
- p = va_arg(vl, const void*);
- }
- }
-
- static void SetSEHChain(const void* p, ...) {
- va_list vl;
- va_start(vl, p);
- int i = 0;
- for (; p; ++i) {
- CHECK(i + 1 < arraysize(g_seh_chain));
- g_seh_chain[i].Handler = const_cast<void*>(p);
- g_seh_chain[i].Next = &g_seh_chain[i + 1];
- p = va_arg(vl, const void*);
- }
-
- g_seh_chain[i].Next = EXCEPTION_CHAIN_END;
- }
-
- static EXCEPTION_REGISTRATION_RECORD g_seh_chain[25];
- static const void* g_stack[VectoredHandlerBase::max_back_trace];
- static WORD g_stack_entries;
- static bool g_dump_made;
-};
-
-EXCEPTION_REGISTRATION_RECORD EMock::g_seh_chain[25];
-const void* EMock::g_stack[VectoredHandlerBase::max_back_trace];
-WORD EMock::g_stack_entries;
-bool EMock::g_dump_made;
-
-typedef VectoredHandlerT<EMock> VectoredHandlerMock;
-
-class ExPtrsHelper : public _EXCEPTION_POINTERS {
- public:
- ExPtrsHelper() {
- ExceptionRecord = &er_;
- ContextRecord = &ctx_;
- ZeroMemory(&er_, sizeof(er_));
- ZeroMemory(&ctx_, sizeof(ctx_));
- }
-
- void Set(DWORD code, void* address, DWORD flags) {
- er_.ExceptionCode = code;
- er_.ExceptionAddress = address;
- er_.ExceptionFlags = flags;
- }
-
- EXCEPTION_RECORD er_;
- CONTEXT ctx_;
-};
-
-
-TEST(ChromeFrame, ExceptionReport) {
- char* s = reinterpret_cast<char*>(0x30000000);
- char* e = s + 0x10000;
- void* handler = VectoredHandlerMock::Register(s, e);
- char* our_code = s + 0x1111;
- char* not_our_code = s - 0x5555;
- char* not_our_code2 = e + 0x5555;
-
- ExPtrsHelper ex;
- // Exception in our code, but we have SEH filter
- ex.Set(STATUS_ACCESS_VIOLATION, our_code, 0);
- EMock::SetHaveSEHFilter();
- EMock::SetOnStack();
- EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
- EXPECT_EQ(1, VectoredHandlerMock::g_exceptions_seen);
- EXPECT_FALSE(EMock::g_dump_made);
-
- // RPC_E_DISCONNECTED (0x80010108) is "The object invoked has disconnected
- // from its clients", shall not be caught since it's a warning only.
- ex.Set(RPC_E_DISCONNECTED, our_code, 0);
- EMock::SetHaveSEHFilter();
- EMock::SetOnStack();
- EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
- EXPECT_EQ(1, VectoredHandlerMock::g_exceptions_seen);
- EXPECT_FALSE(EMock::g_dump_made);
-
-
- // Exception, not in our code, we do not have SEH and we are not in stack.
- ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, not_our_code, 0);
- EMock::SetNoSEHFilter();
- EMock::SetNotOnStack();
- EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
- EXPECT_EQ(2, VectoredHandlerMock::g_exceptions_seen);
- EXPECT_FALSE(EMock::g_dump_made);
-
- // Exception, not in our code, no SEH, but we are on the stack.
- ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, not_our_code2, 0);
- EMock::SetNoSEHFilter();
- EMock::SetOnStack();
- EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
- EXPECT_EQ(3, VectoredHandlerMock::g_exceptions_seen);
- EXPECT_TRUE(EMock::g_dump_made);
- EMock::g_dump_made = false;
-
-
- // Exception, in our code, no SEH, not on stack (assume FPO screwed us)
- ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, our_code, 0);
- EMock::SetNoSEHFilter();
- EMock::SetNotOnStack();
- EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
- EXPECT_EQ(4, VectoredHandlerMock::g_exceptions_seen);
- EXPECT_TRUE(EMock::g_dump_made);
- EMock::g_dump_made = false;
-
- VectoredHandlerMock::Unregister();
-}
-
const wchar_t kInitializeHiddenPage[] = L"files/initialize_hidden.html";
TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_InitializeHidden) {
@@ -745,7 +565,8 @@ TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_InitializeHidden) {
// Disabled due to a problem with Opera.
// http://b/issue?id=1708275
-TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeOpera_InitializeHidden) {
+TEST_F(ChromeFrameTestWithWebServer,
+ DISABLED_WidgetModeOpera_InitializeHidden) {
OptionalBrowserTest(OPERA, kInitializeHiddenPage, L"InitializeHidden");
}
@@ -1084,7 +905,7 @@ MATCHER_P(MsgType, msg_type, "IPC::Message::type()") {
MATCHER_P(EqNavigationInfoUrl, url, "IPC::NavigationInfo matcher") {
if (url.is_valid() && url != arg.url)
return false;
- // TODO: other members
+ // TODO(stevet): other members
return true;
}
@@ -1172,7 +993,7 @@ MATCHER_P(EqURLRequest, x, "IPC::AutomationURLRequest matcher") {
return false;
if (arg.extra_request_headers != x.extra_request_headers)
return false;
- // TODO: uploaddata member
+ // TODO(stevet): uploaddata member
return true;
}