01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one or more
03: * contributor license agreements. See the NOTICE file distributed with
04: * this work for additional information regarding copyright ownership.
05: * The ASF licenses this file to You under the Apache License, Version 2.0
06: * (the "License"); you may not use this file except in compliance with
07: * the License. You may obtain a copy of the License at
08: *
09: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
16: */
17:
18: package org.apache.harmony.luni.platform;
19:
20: /**
21: * This memory spy tries to be as protective as possible, and fail as early as
22: * posible for misbehaving allocators.
23: *
24: */
25: final class DebugMemorySpy extends AbstractMemorySpy {
26:
27: private final boolean stackDump = true;
28:
29: public DebugMemorySpy() {
30: super ();
31: startSpy();
32: }
33:
34: public boolean free(PlatformAddress address) {
35: boolean vetoed = super .free(address);
36: if (!vetoed && stackDump) {
37: Thread.dumpStack();
38: }
39: return vetoed;
40: }
41:
42: /*
43: * If this is memory that we allocated then we can check the access is
44: * within range. However, we cannot check the range for memory that has been
45: * allocated by the OS, or for addresses that we have computed. i.e. it is
46: * quite possible that the range checker does <em>not</em> catch some
47: * buffer overruns.
48: */
49: public void rangeCheck(PlatformAddress address, int offset,
50: int length) throws IndexOutOfBoundsException {
51: AddressWrapper wrapper = (AddressWrapper) memoryInUse
52: .get(address);
53: if (wrapper != null) {
54: PlatformAddress accessStart = address.offsetBytes(offset);
55: PlatformAddress accessEnd = accessStart.offsetBytes(length);
56: PlatformAddress allocStart = wrapper.shadow;
57: PlatformAddress allocEnd = allocStart
58: .offsetBytes(address.size);
59: boolean under = (accessStart.compareTo(allocStart)) == -1;
60: boolean over = (accessEnd.compareTo(allocEnd)) == 1;
61: if (under || over) {
62: System.err
63: .println("Memory Spy! Access out of allocated range"); //$NON-NLS-1$
64: System.err
65: .println("\tAlloc range : [" + allocStart + " ... " + allocEnd + "]"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
66: System.err
67: .println("\tAccess range : [" + accessStart + " ... " + accessEnd + "]"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
68: if (stackDump) {
69: Thread.dumpStack();
70: }
71: // throw new IndexOutOfBoundsException();
72: }
73: }
74: }
75:
76: private void startSpy() {
77: Thread spy = new Thread(new Runnable() {
78: public void run() {
79: while (true) {
80: try {
81: orphanedMemory(notifyQueue.remove()); // Blocks until
82: // notified of
83: // collected
84: // reference
85: } catch (InterruptedException e) {
86: // Ignore interruptions
87: }
88: }
89: }
90: });
91: spy.setDaemon(true);
92: spy.setName("Platform Interface Memory Spy"); //$NON-NLS-1$
93: spy.setPriority(Thread.MAX_PRIORITY);
94: spy.start();
95: }
96: }
|