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

Unified Diff: third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc

Issue 9667026: Revert 126020 - Experiment for updating the tcmalloc chromium branch to r144 (gperftools 2.0). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
Index: third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc
===================================================================
--- third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc (revision 126022)
+++ third_party/tcmalloc/chromium/src/windows/preamble_patcher_test.cc (working copy)
@@ -1,367 +0,0 @@
-/* Copyright (c) 2011, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---
- * Author: Joi Sigurdsson
- * Author: Scott Francis
- *
- * Unit tests for PreamblePatcher
- */
-
-#include "config_for_unittests.h"
-#include "preamble_patcher.h"
-#include "mini_disassembler.h"
-#pragma warning(push)
-#pragma warning(disable:4553)
-#include "auto_testing_hook.h"
-#pragma warning(pop)
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <tchar.h>
-
-// Turning off all optimizations for this file, since the official build's
-// "Whole program optimization" seems to cause the TestPatchUsingDynamicStub
-// test to crash with an access violation. We debugged this and found
-// that the optimized access a register that is changed by a call to the hook
-// function.
-#pragma optimize("", off)
-
-// A convenience macro to avoid a lot of casting in the tests.
-// I tried to make this a templated function, but windows complained:
-// error C2782: 'sidestep::SideStepError `anonymous-namespace'::Unpatch(T,T,T *)' : template parameter 'T' is ambiguous
-// could be 'int (int)'
-// or 'int (__cdecl *)(int)'
-// My life isn't long enough to try to figure out how to fix this.
-#define UNPATCH(target_function, replacement_function, original_function_stub) \
- sidestep::PreamblePatcher::Unpatch((void*)(target_function), \
- (void*)(replacement_function), \
- (void*)(original_function))
-
-namespace {
-
-// Function for testing - this is what we patch
-//
-// NOTE: Because of the way the compiler optimizes this function in
-// release builds, we need to use a different input value every time we
-// call it within a function, otherwise the compiler will just reuse the
-// last calculated incremented value.
-int __declspec(noinline) IncrementNumber(int i) {
-#ifdef _M_X64
- __int64 i2 = i + 1;
- return (int) i2;
-#else
- return i + 1;
-#endif
-}
-
-extern "C" int TooShortFunction(int);
-
-extern "C" int JumpShortCondFunction(int);
-
-extern "C" int JumpNearCondFunction(int);
-
-extern "C" int JumpAbsoluteFunction(int);
-
-extern "C" int CallNearRelativeFunction(int);
-
-typedef int (*IncrementingFunc)(int);
-IncrementingFunc original_function = NULL;
-
-int HookIncrementNumber(int i) {
- SIDESTEP_ASSERT(original_function != NULL);
- int incremented_once = original_function(i);
- return incremented_once + 1;
-}
-
-// For the AutoTestingHook test, we can't use original_function, because
-// all that is encapsulated.
-// This function "increments" by 10, just to set it apart from the other
-// functions.
-int __declspec(noinline) AutoHookIncrementNumber(int i) {
- return i + 10;
-}
-
-}; // namespace
-
-namespace sidestep {
-
-bool TestDisassembler() {
- unsigned int instruction_size = 0;
- sidestep::MiniDisassembler disassembler;
- void * target = reinterpret_cast<unsigned char *>(IncrementNumber);
- void * new_target = PreamblePatcher::ResolveTarget(target);
- if (target != new_target)
- target = new_target;
-
- while (1) {
- sidestep::InstructionType instructionType = disassembler.Disassemble(
- reinterpret_cast<unsigned char *>(target) + instruction_size,
- instruction_size);
- if (sidestep::IT_RETURN == instructionType) {
- return true;
- }
- }
-}
-
-bool TestPatchWithLongJump() {
- original_function = NULL;
- void *p = ::VirtualAlloc(reinterpret_cast<void *>(0x0000020000000000), 4096,
- MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- SIDESTEP_EXPECT_TRUE(p != NULL);
- memset(p, 0xcc, 4096);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(IncrementNumber,
- (IncrementingFunc) p,
- &original_function));
- SIDESTEP_ASSERT((*original_function)(1) == 2);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(IncrementNumber,
- (IncrementingFunc)p,
- original_function));
- ::VirtualFree(p, 0, MEM_RELEASE);
- return true;
-}
-
-bool TestPatchWithPreambleShortCondJump() {
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(JumpShortCondFunction,
- HookIncrementNumber,
- &original_function));
- (*original_function)(1);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(JumpShortCondFunction,
- (void*)HookIncrementNumber,
- original_function));
- return true;
-}
-
-bool TestPatchWithPreambleNearRelativeCondJump() {
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(JumpNearCondFunction,
- HookIncrementNumber,
- &original_function));
- (*original_function)(0);
- (*original_function)(1);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(JumpNearCondFunction,
- HookIncrementNumber,
- original_function));
- return true;
-}
-
-bool TestPatchWithPreambleAbsoluteJump() {
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(JumpAbsoluteFunction,
- HookIncrementNumber,
- &original_function));
- (*original_function)(0);
- (*original_function)(1);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(JumpAbsoluteFunction,
- HookIncrementNumber,
- original_function));
- return true;
-}
-
-bool TestPatchWithPreambleNearRelativeCall() {
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(
- CallNearRelativeFunction,
- HookIncrementNumber,
- &original_function));
- (*original_function)(0);
- (*original_function)(1);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(CallNearRelativeFunction,
- HookIncrementNumber,
- original_function));
- return true;
-}
-
-bool TestPatchUsingDynamicStub() {
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(IncrementNumber,
- HookIncrementNumber,
- &original_function));
- SIDESTEP_EXPECT_TRUE(original_function);
- SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 4);
- SIDESTEP_EXPECT_TRUE(original_function(3) == 4);
-
- // Clearbox test to see that the function has been patched.
- sidestep::MiniDisassembler disassembler;
- unsigned int instruction_size = 0;
- SIDESTEP_EXPECT_TRUE(sidestep::IT_JUMP == disassembler.Disassemble(
- reinterpret_cast<unsigned char*>(IncrementNumber),
- instruction_size));
-
- // Since we patched IncrementNumber, its first statement is a
- // jmp to the hook function. So verify that we now can not patch
- // IncrementNumber because it starts with a jump.
-#if 0
- IncrementingFunc dummy = NULL;
- // TODO(joi@chromium.org): restore this test once flag is added to
- // disable JMP following
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_JUMP_INSTRUCTION ==
- sidestep::PreamblePatcher::Patch(IncrementNumber,
- HookIncrementNumber,
- &dummy));
-
- // This test disabled because code in preamble_patcher_with_stub.cc
- // asserts before returning the error code -- so there is no way
- // to get an error code here, in debug build.
- dummy = NULL;
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_FUNCTION_TOO_SMALL ==
- sidestep::PreamblePatcher::Patch(TooShortFunction,
- HookIncrementNumber,
- &dummy));
-#endif
-
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(IncrementNumber,
- HookIncrementNumber,
- original_function));
- return true;
-}
-
-bool PatchThenUnpatch() {
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- sidestep::PreamblePatcher::Patch(IncrementNumber,
- HookIncrementNumber,
- &original_function));
- SIDESTEP_EXPECT_TRUE(original_function);
- SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 3);
- SIDESTEP_EXPECT_TRUE(original_function(2) == 3);
-
- SIDESTEP_EXPECT_TRUE(sidestep::SIDESTEP_SUCCESS ==
- UNPATCH(IncrementNumber,
- HookIncrementNumber,
- original_function));
- original_function = NULL;
- SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
- return true;
-}
-
-bool AutoTestingHookTest() {
- SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-
- // Inner scope, so we can test what happens when the AutoTestingHook
- // goes out of scope
- {
- AutoTestingHook hook = MakeTestingHook(IncrementNumber,
- AutoHookIncrementNumber);
- (void) hook;
- SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 12);
- }
- SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
- return true;
-}
-
-bool AutoTestingHookInContainerTest() {
- SIDESTEP_EXPECT_TRUE(IncrementNumber(1) == 2);
-
- // Inner scope, so we can test what happens when the AutoTestingHook
- // goes out of scope
- {
- AutoTestingHookHolder hook(MakeTestingHookHolder(IncrementNumber,
- AutoHookIncrementNumber));
- (void) hook;
- SIDESTEP_EXPECT_TRUE(IncrementNumber(2) == 12);
- }
- SIDESTEP_EXPECT_TRUE(IncrementNumber(3) == 4);
-
- return true;
-}
-
-bool TestPreambleAllocation() {
- __int64 diff = 0;
- void* p1 = reinterpret_cast<void*>(0x110000000);
- void* p2 = reinterpret_cast<void*>(0x810000000);
- unsigned char* b1 = PreamblePatcher::AllocPreambleBlockNear(p1);
- SIDESTEP_EXPECT_TRUE(b1 != NULL);
- diff = reinterpret_cast<__int64>(p1) - reinterpret_cast<__int64>(b1);
- // Ensure blocks are within 2GB
- SIDESTEP_EXPECT_TRUE(diff <= INT_MAX && diff >= INT_MIN);
- unsigned char* b2 = PreamblePatcher::AllocPreambleBlockNear(p2);
- SIDESTEP_EXPECT_TRUE(b2 != NULL);
- diff = reinterpret_cast<__int64>(p2) - reinterpret_cast<__int64>(b2);
- SIDESTEP_EXPECT_TRUE(diff <= INT_MAX && diff >= INT_MIN);
-
- // Ensure we're reusing free blocks
- unsigned char* b3 = b1;
- unsigned char* b4 = b2;
- PreamblePatcher::FreePreambleBlock(b1);
- PreamblePatcher::FreePreambleBlock(b2);
- b1 = PreamblePatcher::AllocPreambleBlockNear(p1);
- SIDESTEP_EXPECT_TRUE(b1 == b3);
- b2 = PreamblePatcher::AllocPreambleBlockNear(p2);
- SIDESTEP_EXPECT_TRUE(b2 == b4);
- PreamblePatcher::FreePreambleBlock(b1);
- PreamblePatcher::FreePreambleBlock(b2);
-
- return true;
-}
-
-bool UnitTests() {
- return TestPatchWithPreambleNearRelativeCall() &&
- TestPatchWithPreambleAbsoluteJump() &&
- TestPatchWithPreambleNearRelativeCondJump() &&
- TestPatchWithPreambleShortCondJump() &&
- TestDisassembler() && TestPatchWithLongJump() &&
- TestPatchUsingDynamicStub() && PatchThenUnpatch() &&
- AutoTestingHookTest() && AutoTestingHookInContainerTest() &&
- TestPreambleAllocation();
-}
-
-}; // namespace sidestep
-
-int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
- if (size == 0) // not even room for a \0?
- return -1; // not what C99 says to do, but what windows does
- str[size-1] = '\0';
- return _vsnprintf(str, size-1, format, ap);
-}
-
-int _tmain(int argc, _TCHAR* argv[])
-{
- bool ret = sidestep::UnitTests();
- printf("%s\n", ret ? "PASS" : "FAIL");
- return ret ? 0 : -1;
-}
-
-#pragma optimize("", on)

Powered by Google App Engine
This is Rietveld 408576698