Return error message if IndirectReferenceTable construction fails.
Previously if there was an error when constructing the
IndirectReferenceTable, the error message was lost. Now expose and
include the error message when throwing an exception related to
failures to construct the IndirectReferenceTable.
The error message is propagated through JVMEnvExt, JavaVMExt, and
Runtime::Init as well.
Bug: 32013594
Test: Added new 151-OpenFileLimit runtest.
Test: m test-art-host, m test-art-target
Change-Id: I3692f6928c9570358571bce634569d6f14cdeb05
diff --git a/test/151-OpenFileLimit/src/Main.java b/test/151-OpenFileLimit/src/Main.java
new file mode 100644
index 0000000..01a9a4e
--- /dev/null
+++ b/test/151-OpenFileLimit/src/Main.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.*;
+import java.io.*;
+import java.util.*;
+
+public class Main {
+ private static final String TEMP_FILE_NAME_PREFIX = "oflimit";
+ private static final String TEMP_FILE_NAME_SUFFIX = ".txt";
+
+ public static void main(String[] args) throws IOException {
+
+ // Exhaust the number of open file descriptors.
+ List<File> files = new ArrayList<File>();
+ List<OutputStream> streams = new ArrayList<OutputStream>();
+ try {
+ for (int i = 0; ; i++) {
+ File file = createTempFile();
+ files.add(file);
+ streams.add(Files.newOutputStream(file.toPath(), CREATE, APPEND));
+ }
+ } catch (Throwable e) {
+ if (e.getMessage().contains("Too many open files")) {
+ System.out.println("Message includes \"Too many open files\"");
+ } else {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ // Now try to create a new thread.
+ try {
+ Thread thread = new Thread() {
+ public void run() {
+ System.out.println("thread run.");
+ }
+ };
+ thread.start();
+ thread.join();
+ } catch (Throwable e) {
+ if (e.getMessage().contains("Too many open files")) {
+ System.out.println("Message includes \"Too many open files\"");
+ } else {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ streams.get(i).close();
+ files.get(i).delete();
+ }
+ System.out.println("done.");
+ }
+
+ private static File createTempFile() throws Exception {
+ try {
+ return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
+ } catch (IOException e) {
+ System.setProperty("java.io.tmpdir", "/data/local/tmp");
+ try {
+ return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
+ } catch (IOException e2) {
+ System.setProperty("java.io.tmpdir", "/sdcard");
+ return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
+ }
+ }
+ }
+}