src/share/vm/memory/guardedMemory.cpp

Tue, 16 Feb 2016 21:42:29 +0000

author
poonam
date
Tue, 16 Feb 2016 21:42:29 +0000
changeset 8308
6acf14e730dd
parent 7032
fa62fb12cdca
child 9336
0fa4c2b668b9
permissions
-rw-r--r--

8072725: Provide more granular levels for GC verification
Summary: Add option VerifySubSet to selectively verify the memory sub-systems
Reviewed-by: kevinw, jmasa

dsimms@7032 1 /*
dsimms@7032 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
dsimms@7032 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
dsimms@7032 4 *
dsimms@7032 5 * This code is free software; you can redistribute it and/or modify it
dsimms@7032 6 * under the terms of the GNU General Public License version 2 only, as
dsimms@7032 7 * published by the Free Software Foundation.
dsimms@7032 8 *
dsimms@7032 9 * This code is distributed in the hope that it will be useful, but WITHOUT
dsimms@7032 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
dsimms@7032 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dsimms@7032 12 * version 2 for more details (a copy is included in the LICENSE file that
dsimms@7032 13 * accompanied this code).
dsimms@7032 14 *
dsimms@7032 15 * You should have received a copy of the GNU General Public License version
dsimms@7032 16 * 2 along with this work; if not, write to the Free Software Foundation,
dsimms@7032 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
dsimms@7032 18 *
dsimms@7032 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
dsimms@7032 20 * or visit www.oracle.com if you need additional information or have any
dsimms@7032 21 * questions.
dsimms@7032 22 *
dsimms@7032 23 */
dsimms@7032 24 #include "precompiled.hpp"
dsimms@7032 25 #include "memory/allocation.hpp"
dsimms@7032 26 #include "memory/allocation.inline.hpp"
dsimms@7032 27 #include "memory/guardedMemory.hpp"
dsimms@7032 28 #include "runtime/os.hpp"
dsimms@7032 29
dsimms@7032 30 void* GuardedMemory::wrap_copy(const void* ptr, const size_t len, const void* tag) {
dsimms@7032 31 size_t total_sz = GuardedMemory::get_total_size(len);
dsimms@7032 32 void* outerp = os::malloc(total_sz, mtInternal);
dsimms@7032 33 if (outerp != NULL) {
dsimms@7032 34 GuardedMemory guarded(outerp, len, tag);
dsimms@7032 35 void* innerp = guarded.get_user_ptr();
dsimms@7032 36 memcpy(innerp, ptr, len);
dsimms@7032 37 return innerp;
dsimms@7032 38 }
dsimms@7032 39 return NULL; // OOM
dsimms@7032 40 }
dsimms@7032 41
dsimms@7032 42 bool GuardedMemory::free_copy(void* p) {
dsimms@7032 43 if (p == NULL) {
dsimms@7032 44 return true;
dsimms@7032 45 }
dsimms@7032 46 GuardedMemory guarded((u_char*)p);
dsimms@7032 47 bool verify_ok = guarded.verify_guards();
dsimms@7032 48
dsimms@7032 49 /* always attempt to free, pass problem on to any nested memchecker */
dsimms@7032 50 os::free(guarded.release_for_freeing());
dsimms@7032 51
dsimms@7032 52 return verify_ok;
dsimms@7032 53 }
dsimms@7032 54
dsimms@7032 55 void GuardedMemory::print_on(outputStream* st) const {
dsimms@7032 56 if (_base_addr == NULL) {
dsimms@7032 57 st->print_cr("GuardedMemory(" PTR_FORMAT ") not associated to any memory", p2i(this));
dsimms@7032 58 return;
dsimms@7032 59 }
dsimms@7032 60 st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT
dsimms@7032 61 " tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT,
dsimms@7032 62 p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr()));
dsimms@7032 63
dsimms@7032 64 Guard* guard = get_head_guard();
dsimms@7032 65 st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
dsimms@7032 66 guard = get_tail_guard();
dsimms@7032 67 st->print_cr(" Trailer guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
dsimms@7032 68
dsimms@7032 69 u_char udata = *get_user_ptr();
dsimms@7032 70 switch (udata) {
dsimms@7032 71 case uninitBlockPad:
dsimms@7032 72 st->print_cr(" User data appears unused");
dsimms@7032 73 break;
dsimms@7032 74 case freeBlockPad:
dsimms@7032 75 st->print_cr(" User data appears to have been freed");
dsimms@7032 76 break;
dsimms@7032 77 default:
dsimms@7032 78 st->print_cr(" User data appears to be in use");
dsimms@7032 79 break;
dsimms@7032 80 }
dsimms@7032 81 }
dsimms@7032 82
dsimms@7032 83 // test code...
dsimms@7032 84
dsimms@7032 85 #ifndef PRODUCT
dsimms@7032 86
dsimms@7032 87 static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
dsimms@7032 88 assert(p != NULL, "NULL pointer given to check");
dsimms@7032 89 u_char* c = (u_char*) p;
dsimms@7032 90 GuardedMemory guarded(c);
dsimms@7032 91 assert(guarded.get_tag() == tag, "Tag is not the same as supplied");
dsimms@7032 92 assert(guarded.get_user_ptr() == c, "User pointer is not the same as supplied");
dsimms@7032 93 assert(guarded.get_user_size() == sz, "User size is not the same as supplied");
dsimms@7032 94 assert(guarded.verify_guards(), "Guard broken");
dsimms@7032 95 }
dsimms@7032 96
dsimms@7032 97 void GuardedMemory::test_guarded_memory() {
dsimms@7032 98 // Test the basic characteristics...
dsimms@7032 99 size_t total_sz = GuardedMemory::get_total_size(1);
dsimms@7032 100 assert(total_sz > 1 && total_sz >= (sizeof(GuardHeader) + 1 + sizeof(Guard)), "Unexpected size");
dsimms@7032 101 u_char* basep = (u_char*) os::malloc(total_sz, mtInternal);
dsimms@7032 102
dsimms@7032 103 GuardedMemory guarded(basep, 1, (void*)0xf000f000);
dsimms@7032 104
dsimms@7032 105 assert(*basep == badResourceValue, "Expected guard in the form of badResourceValue");
dsimms@7032 106 u_char* userp = guarded.get_user_ptr();
dsimms@7032 107 assert(*userp == uninitBlockPad, "Expected uninitialized data in the form of uninitBlockPad");
dsimms@7032 108 guarded_memory_test_check(userp, 1, (void*)0xf000f000);
dsimms@7032 109
dsimms@7032 110 void* freep = guarded.release_for_freeing();
dsimms@7032 111 assert((u_char*)freep == basep, "Expected the same pointer guard was ");
dsimms@7032 112 assert(*userp == freeBlockPad, "Expected user data to be free block padded");
dsimms@7032 113 assert(!guarded.verify_guards(), "Expected failed");
dsimms@7032 114 os::free(freep);
dsimms@7032 115
dsimms@7032 116 // Test a number of odd sizes...
dsimms@7032 117 size_t sz = 0;
dsimms@7032 118 do {
dsimms@7032 119 void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
dsimms@7032 120 void* up = guarded.wrap_with_guards(p, sz, (void*)1);
dsimms@7032 121 memset(up, 0, sz);
dsimms@7032 122 guarded_memory_test_check(up, sz, (void*)1);
dsimms@7032 123 os::free(guarded.release_for_freeing());
dsimms@7032 124 sz = (sz << 4) + 1;
dsimms@7032 125 } while (sz < (256 * 1024));
dsimms@7032 126
dsimms@7032 127 // Test buffer overrun into head...
dsimms@7032 128 basep = (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
dsimms@7032 129 guarded.wrap_with_guards(basep, 1);
dsimms@7032 130 *basep = 0;
dsimms@7032 131 assert(!guarded.verify_guards(), "Expected failure");
dsimms@7032 132 os::free(basep);
dsimms@7032 133
dsimms@7032 134 // Test buffer overrun into tail with a number of odd sizes...
dsimms@7032 135 sz = 1;
dsimms@7032 136 do {
dsimms@7032 137 void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
dsimms@7032 138 void* up = guarded.wrap_with_guards(p, sz, (void*)1);
dsimms@7032 139 memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
dsimms@7032 140 assert(!guarded.verify_guards(), "Guard was not broken as expected");
dsimms@7032 141 os::free(guarded.release_for_freeing());
dsimms@7032 142 sz = (sz << 4) + 1;
dsimms@7032 143 } while (sz < (256 * 1024));
dsimms@7032 144
dsimms@7032 145 // Test wrap_copy/wrap_free...
dsimms@7032 146 assert(GuardedMemory::free_copy(NULL), "Expected free NULL to be OK");
dsimms@7032 147
dsimms@7032 148 const char* str = "Check my bounds out";
dsimms@7032 149 size_t str_sz = strlen(str) + 1;
dsimms@7032 150 char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
dsimms@7032 151 guarded_memory_test_check(str_copy, str_sz, NULL);
dsimms@7032 152 assert(strcmp(str, str_copy) == 0, "Not identical copy");
dsimms@7032 153 assert(GuardedMemory::free_copy(str_copy), "Free copy failed to verify");
dsimms@7032 154
dsimms@7032 155 void* no_data = NULL;
dsimms@7032 156 void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
dsimms@7032 157 assert(GuardedMemory::free_copy(no_data_copy), "Expected valid guards even for no data copy");
dsimms@7032 158 }
dsimms@7032 159
dsimms@7032 160 #endif // !PRODUCT
dsimms@7032 161

mercurial