summaryrefslogtreecommitdiffstats
path: root/dalvik
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2014-02-28 16:43:15 +0000
committerPaul Duffin <paulduffin@google.com>2014-05-01 16:06:57 +0100
commita6f350c645dbb66d68cc2b03afb8f2eeaa88fbba (patch)
tree3625ee2813edb10bdb706e263408f744a16cccbd /dalvik
parent8ccb6f5b798aa991cccf7bba6ddb21ee8affecac (diff)
downloadlibcore-a6f350c645dbb66d68cc2b03afb8f2eeaa88fbba.zip
libcore-a6f350c645dbb66d68cc2b03afb8f2eeaa88fbba.tar.gz
libcore-a6f350c645dbb66d68cc2b03afb8f2eeaa88fbba.tar.bz2
Improve detection of CloseGuard protected resource leakage
* Add CloseGuardMonitor to intercept and collate CloseGuard reports and if necessary throw an exception listing the resource leaks. * Add ResourceLeakageDetector to abstract away the CloseGuardMonitor which will not work on RI. * Add AbstractResourceLeakageDetectorTestCase as a base class for tests that need to detect resource leaks, in future this could be handled by modifications to Cts and Vogar test runners. * Remove CloseGuardTester and its sole usage in ProcessBuilderTest. * Remove CloseGuardGuard from within URLConnectionTest * Change ZipFileTest, ProcessBuilderTest, URLConnectionTest to use new mechanism, fix issues that are identified and do some cleanup/remove duplicated code. Bug: https://code.google.com/p/android/issues/detail?id=66383 Change-Id: Id026dbb6bc66091a15f07329e6371cd0d1f32cf5
Diffstat (limited to 'dalvik')
-rw-r--r--dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java119
1 files changed, 119 insertions, 0 deletions
diff --git a/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java b/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java
new file mode 100644
index 0000000..b5bf380
--- /dev/null
+++ b/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package dalvik.system;
+
+import dalvik.system.CloseGuard.Reporter;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Provides support for detecting issues found by {@link CloseGuard} from within tests.
+ *
+ * <p>This is a best effort as it relies on both {@link CloseGuard} being enabled and being able to
+ * force a GC and finalization, none of which are directly controllable by this.
+ *
+ * <p>This is loaded using reflection by the AbstractResourceLeakageDetectorTestCase class as that
+ * class needs to run on the reference implementation which does not have this class. It implements
+ * {@link Runnable} because that is simpler than trying to manage a specialized interface.
+ *
+ * @hide
+ */
+public class CloseGuardMonitor implements Runnable {
+ /**
+ * The {@link Reporter} instance used to receive warnings from {@link CloseGuard}.
+ */
+ private final Reporter closeGuardReporter;
+
+ /**
+ * The list of allocation sites that {@link CloseGuard} has reported as not being released.
+ *
+ * <p>Is thread safe as this will be called during finalization and so there are no guarantees
+ * as to whether it will be called concurrently or not.
+ */
+ private final List<Throwable> closeGuardAllocationSites = new CopyOnWriteArrayList<>();
+
+ /**
+ * Default constructor required for reflection.
+ */
+ public CloseGuardMonitor() {
+ System.logI("Creating CloseGuard monitor");
+
+ // Save current reporter.
+ closeGuardReporter = CloseGuard.getReporter();
+
+ // Override the reporter with our own which collates the allocation sites.
+ CloseGuard.setReporter(new Reporter() {
+ @Override
+ public void report(String message, Throwable allocationSite) {
+ // Ignore message as it's always the same.
+ closeGuardAllocationSites.add(allocationSite);
+ }
+ });
+ }
+
+ /**
+ * Check to see whether any resources monitored by {@link CloseGuard} were not released before
+ * they were garbage collected.
+ */
+ @Override
+ public void run() {
+ // Create a weak reference to an object so that we can detect when it is garbage collected.
+ WeakReference<Object> reference = new WeakReference<>(new Object());
+
+ try {
+ // 'Force' a GC and finalize to cause CloseGuards to report warnings. Doesn't loop
+ // forever as there are no guarantees that the following code does anything at all so
+ // don't want a potential infinite loop.
+ Runtime runtime = Runtime.getRuntime();
+ for (int i = 0; i < 20; ++i) {
+ runtime.gc();
+ System.runFinalization();
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ throw new AssertionError(e);
+ }
+
+ // Check to see if the weak reference has been garbage collected.
+ if (reference.get() == null) {
+ System.logI("Sentry object has been freed so assuming CloseGuards have reported"
+ + " any resource leakages");
+ break;
+ }
+ }
+ } finally {
+ // Restore the reporter.
+ CloseGuard.setReporter(closeGuardReporter);
+ }
+
+ if (!closeGuardAllocationSites.isEmpty()) {
+ StringWriter writer = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(writer);
+ int i = 0;
+ for (Throwable allocationSite : closeGuardAllocationSites) {
+ printWriter.print(++i);
+ printWriter.print(") ");
+ allocationSite.printStackTrace(printWriter);
+ printWriter.println(" --------------------------------");
+ }
+ throw new AssertionError("Potential resource leakage detected:\n" + writer);
+ }
+ }
+}