summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Android.bp31
-rw-r--r--tools/PresubmitJsonLinter.java197
l---------tools/ahat/.clang-format1
-rw-r--r--tools/ahat/Android.bp2
-rwxr-xr-xtools/ahat/ahat.sh (renamed from tools/ahat/ahat)0
-rw-r--r--tools/ahat/etc/style.css25
-rw-r--r--tools/ahat/src/main/com/android/ahat/DocString.java8
-rw-r--r--tools/ahat/src/main/com/android/ahat/HtmlDoc.java15
-rw-r--r--tools/ahat/src/main/com/android/ahat/ObjectsHandler.java2
-rw-r--r--tools/ahat/src/main/com/android/ahat/OverviewHandler.java2
-rw-r--r--tools/ahat/src/main/com/android/ahat/SiteHandler.java2
-rw-r--r--tools/ahat/src/test-dump/Main.java4
-rw-r--r--tools/ahat/src/test/com/android/ahat/InstanceTest.java1
-rw-r--r--tools/art_boot.cc55
-rw-r--r--tools/art_verifier/art_verifier.cc6
-rwxr-xr-xtools/build_linux_bionic.sh81
-rwxr-xr-xtools/build_linux_bionic_tests.sh78
-rwxr-xr-xtools/buildbot-build.sh77
-rwxr-xr-xtools/buildbot-cleanup-device.sh17
-rwxr-xr-xtools/buildbot-setup-device.sh42
-rwxr-xr-xtools/buildbot-sync.sh113
-rwxr-xr-xtools/buildbot-teardown-device.sh5
-rwxr-xr-xtools/buildbot-utils.sh36
-rwxr-xr-xtools/buildbot-vm.sh128
-rwxr-xr-xtools/check_presubmit_json_expectations.sh50
-rw-r--r--tools/checker/Android.bp41
-rwxr-xr-xtools/compile-jar.py6
-rw-r--r--tools/cpp-define-generator/globals.def9
-rw-r--r--tools/cpp-define-generator/lockword.def4
-rw-r--r--tools/cpp-define-generator/mirror_class.def15
-rw-r--r--tools/cpp-define-generator/runtime.def4
-rw-r--r--tools/cpp-define-generator/thread.def4
-rw-r--r--tools/dexanalyze/Android.bp1
-rw-r--r--tools/dexanalyze/dexanalyze.cc30
-rw-r--r--tools/dexanalyze/dexanalyze_experiments.cc1
-rw-r--r--tools/dexanalyze/dexanalyze_test.cc4
l---------tools/dexfuzz/.clang-format1
-rw-r--r--tools/dexfuzz/Android.bp4
-rwxr-xr-xtools/dexfuzz/dexfuzz.sh (renamed from tools/dexfuzz/dexfuzz)0
-rwxr-xr-xtools/dist_linux_bionic.sh16
-rw-r--r--tools/dmtracedump/createtesttrace.cc7
-rw-r--r--tools/dmtracedump/tracedump.cc8
-rw-r--r--tools/external_oj_libjdwp_art_no_read_barrier_failures.txt9
-rwxr-xr-xtools/generate_cmake_lists.py3
-rwxr-xr-xtools/generate_operator_out.py2
-rwxr-xr-xtools/golem/build-target.sh2
-rw-r--r--tools/hiddenapi/hiddenapi.cc458
-rw-r--r--tools/hiddenapi/hiddenapi_test.cc9
-rwxr-xr-xtools/host_bcp.sh50
-rw-r--r--tools/jvmti-agents/chain-agents/chainagents.cc2
-rw-r--r--tools/jvmti-agents/field-counts/fieldcount.cc2
-rw-r--r--tools/jvmti-agents/simple-force-redefine/forceredefine.cc2
-rw-r--r--tools/jvmti-agents/simple-profile/simple_profile.cc7
-rw-r--r--tools/libcore_failures.txt22
-rw-r--r--tools/libcore_fugu_failures.txt107
-rw-r--r--tools/libcore_gcstress_debug_failures.txt7
-rw-r--r--tools/libcore_gcstress_failures.txt1
-rw-r--r--tools/luci/config/generated/cr-buildbucket.cfg114
-rw-r--r--tools/luci/config/generated/luci-scheduler.cfg34
-rw-r--r--tools/luci/config/generated/project.cfg2
-rwxr-xr-xtools/luci/config/main.star76
-rw-r--r--tools/prebuilt_libjdwp_art_failures.txt2
-rw-r--r--tools/public.libraries.buildbot.txt2
-rwxr-xr-xtools/run-gtests.sh31
-rwxr-xr-xtools/run-libcore-tests.py160
-rwxr-xr-xtools/run-libjdwp-tests.sh4
-rw-r--r--tools/signal_dumper/Android.bp16
-rw-r--r--tools/signal_dumper/signal_dumper.cc86
-rw-r--r--tools/tracefast-plugin/tracefast.cc4
-rw-r--r--tools/veridex/Android.bp1
-rw-r--r--tools/veridex/Android.mk4
-rw-r--r--tools/veridex/flow_analysis.cc4
-rw-r--r--tools/veridex/hidden_api.cc13
-rw-r--r--tools/veridex/veridex.cc23
74 files changed, 1611 insertions, 781 deletions
diff --git a/tools/Android.bp b/tools/Android.bp
index b7f5c1b08b..207a121848 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -37,6 +37,17 @@ soong_config_module_type_import {
],
}
+cc_binary {
+ name: "art_boot",
+ defaults: ["art_defaults"],
+ srcs: ["art_boot.cc"],
+ shared_libs: ["libbase"],
+ apex_available: [
+ "com.android.art",
+ "com.android.art.debug",
+ ],
+}
+
// Copy the art shell script to the host and target's bin directory
art_module_sh_binary {
name: "art-script",
@@ -97,23 +108,3 @@ sh_binary {
},
},
}
-
-python_binary_host {
- name: "art-run-test-checker",
- srcs: [
- "checker/**/*.py",
- ],
- main: "checker/checker.py",
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
- test_suites: [
- "general-tests",
- "mts-art",
- ],
-}
diff --git a/tools/PresubmitJsonLinter.java b/tools/PresubmitJsonLinter.java
new file mode 100644
index 0000000000..334d20079d
--- /dev/null
+++ b/tools/PresubmitJsonLinter.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2022 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 com.google.gson.stream.JsonReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Pre upload hook that ensures art-buildbot expectation files (files under //art/tools ending with
+ * "_failures.txt", e.g. //art/tools/libcore_failures.txt) are well-formed json files.
+ *
+ * It makes basic validation of the keys but does not cover all the cases. Parser structure is
+ * based on external/vogar/src/vogar/ExpectationStore.java.
+ *
+ * Hook is set up in //art/PREUPLOAD.cfg See also //tools/repohooks/README.md
+ */
+class PresubmitJsonLinter {
+
+ private static final int FLAGS = Pattern.MULTILINE | Pattern.DOTALL;
+ private static final Set<String> RESULTS = new HashSet<>();
+
+ static {
+ RESULTS.addAll(List.of(
+ "UNSUPPORTED",
+ "COMPILE_FAILED",
+ "EXEC_FAILED",
+ "EXEC_TIMEOUT",
+ "ERROR",
+ "SUCCESS"
+ ));
+ }
+
+ public static void main(String[] args) {
+ for (String arg : args) {
+ info("Checking " + arg);
+ checkExpectationFile(arg);
+ }
+ }
+
+ private static void info(String message) {
+ System.err.println(message);
+ }
+
+ private static void error(String message) {
+ System.err.println(message);
+ System.exit(1);
+ }
+
+ private static void checkExpectationFile(String arg) {
+ JsonReader reader;
+ try {
+ reader = new JsonReader(new FileReader(arg));
+ } catch (FileNotFoundException e) {
+ error("File '" + arg + "' is not found");
+ return;
+ }
+ reader.setLenient(true);
+ try {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ readExpectation(reader);
+ }
+ reader.endArray();
+ } catch (IOException e) {
+ error("Malformed json: " + reader);
+ }
+ }
+
+ private static void readExpectation(JsonReader reader) throws IOException {
+ Set<String> names = new LinkedHashSet<String>();
+ Set<String> tags = new LinkedHashSet<String>();
+ boolean readResult = false;
+ boolean readDescription = false;
+
+ reader.beginObject();
+ while (reader.hasNext()) {
+ String name = reader.nextName();
+ switch (name) {
+ case "result":
+ String result = reader.nextString();
+ if (!RESULTS.contains(result)) {
+ error("Invalid 'result' value: '" + result +
+ "'. Expected one of " + String.join(", ", RESULTS) +
+ ". " + reader);
+ }
+ readResult = true;
+ break;
+ case "substring": {
+ try {
+ Pattern.compile(
+ ".*" + Pattern.quote(reader.nextString()) + ".*", FLAGS);
+ } catch (PatternSyntaxException e) {
+ error("Malformed 'substring' value: " + reader);
+ }
+ }
+ case "pattern": {
+ try {
+ Pattern.compile(reader.nextString(), FLAGS);
+ } catch (PatternSyntaxException e) {
+ error("Malformed 'pattern' value: " + reader);
+ }
+ break;
+ }
+ case "failure":
+ names.add(reader.nextString());
+ break;
+ case "description":
+ reader.nextString();
+ readDescription = true;
+ break;
+ case "name":
+ names.add(reader.nextString());
+ break;
+ case "names":
+ readStrings(reader, names);
+ break;
+ case "tags":
+ readStrings(reader, tags);
+ break;
+ case "bug":
+ reader.nextLong();
+ break;
+ case "modes":
+ readModes(reader);
+ break;
+ case "modes_variants":
+ readModesAndVariants(reader);
+ break;
+ default:
+ error("Unknown key '" + name + "' in expectations file");
+ reader.skipValue();
+ break;
+ }
+ }
+ reader.endObject();
+
+ if (names.isEmpty()) {
+ error("Missing 'name' or 'failure' key in " + reader);
+ }
+ if (!readResult) {
+ error("Missing 'result' key in " + reader);
+ }
+ if (!readDescription) {
+ error("Missing 'description' key in " + reader);
+ }
+ }
+
+ private static void readStrings(JsonReader reader, Set<String> output) throws IOException {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ output.add(reader.nextString());
+ }
+ reader.endArray();
+ }
+
+ private static void readModes(JsonReader reader) throws IOException {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ reader.nextString();
+ }
+ reader.endArray();
+ }
+
+ /**
+ * Expected format: mode_variants: [["host", "X32"], ["host", "X64"]]
+ */
+ private static void readModesAndVariants(JsonReader reader) throws IOException {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ reader.beginArray();
+ reader.nextString();
+ reader.nextString();
+ reader.endArray();
+ }
+ reader.endArray();
+ }
+} \ No newline at end of file
diff --git a/tools/ahat/.clang-format b/tools/ahat/.clang-format
new file mode 120000
index 0000000000..88ab38e627
--- /dev/null
+++ b/tools/ahat/.clang-format
@@ -0,0 +1 @@
+../../.clang-format-java-2 \ No newline at end of file
diff --git a/tools/ahat/Android.bp b/tools/ahat/Android.bp
index affa2e0585..5f6ba819fc 100644
--- a/tools/ahat/Android.bp
+++ b/tools/ahat/Android.bp
@@ -27,7 +27,7 @@ java_binary_host {
visibility: [
"//libcore/metrictests/memory/host",
],
- wrapper: "ahat",
+ wrapper: "ahat.sh",
srcs: ["src/main/**/*.java"],
manifest: "etc/ahat.mf",
java_resources: ["etc/style.css"],
diff --git a/tools/ahat/ahat b/tools/ahat/ahat.sh
index 77c1d6e430..77c1d6e430 100755
--- a/tools/ahat/ahat
+++ b/tools/ahat/ahat.sh
diff --git a/tools/ahat/etc/style.css b/tools/ahat/etc/style.css
index 47fae1d551..83e5b20c3c 100644
--- a/tools/ahat/etc/style.css
+++ b/tools/ahat/etc/style.css
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+html {
+ /* Roboto has tabular numbers, use it if available, fallback to other sans. */
+ font-family: "Roboto", "Arial", "sans-serif";
+}
+
div.menu {
background-color: #eeffff;
}
@@ -39,3 +44,23 @@ table th {
padding-left: 8px;
padding-right: 8px;
}
+
+.sidebar {
+ position: fixed;
+ right: 0;
+ top: 48px;
+ padding-left: 12px;
+ padding-right: 24px;
+ font-size: small;
+ border-left: 4px solid #dcedc8;
+}
+
+.sidebar a {
+ text-decoration: none;
+ color: #4285f4;
+}
+
+.sidebar a:hover {
+ text-decoration: underline;
+ color: #073042;
+} \ No newline at end of file
diff --git a/tools/ahat/src/main/com/android/ahat/DocString.java b/tools/ahat/src/main/com/android/ahat/DocString.java
index eda9b383c4..ca5dbf06ce 100644
--- a/tools/ahat/src/main/com/android/ahat/DocString.java
+++ b/tools/ahat/src/main/com/android/ahat/DocString.java
@@ -136,7 +136,7 @@ class DocString {
if (isPlaceHolder) {
string.append(DocString.removed("del"));
} else if (size != 0) {
- string.appendFormat("%,14d", size);
+ string.appendFormat("%,d", size);
}
return string;
}
@@ -162,13 +162,13 @@ class DocString {
public DocString appendDelta(boolean noCurrent, boolean noBaseline,
long current, long baseline) {
if (noCurrent) {
- append(removed(format("%+,14d", 0 - baseline)));
+ append(removed(format("%+,d", 0 - baseline)));
} else if (noBaseline) {
append(added("new"));
} else if (current > baseline) {
- append(added(format("%+,14d", current - baseline)));
+ append(added(format("%+,d", current - baseline)));
} else if (current < baseline) {
- append(removed(format("%+,14d", current - baseline)));
+ append(removed(format("%+,d", current - baseline)));
}
return this;
}
diff --git a/tools/ahat/src/main/com/android/ahat/HtmlDoc.java b/tools/ahat/src/main/com/android/ahat/HtmlDoc.java
index d5106dc1dd..6c3ab2fe3e 100644
--- a/tools/ahat/src/main/com/android/ahat/HtmlDoc.java
+++ b/tools/ahat/src/main/com/android/ahat/HtmlDoc.java
@@ -18,6 +18,7 @@ package com.android.ahat;
import java.io.PrintStream;
import java.net.URI;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -26,6 +27,7 @@ import java.util.List;
class HtmlDoc implements Doc {
private PrintStream ps;
private Column[] mCurrentTableColumns;
+ private List<String> mSections;
/**
* Create an HtmlDoc that writes to the given print stream.
@@ -34,6 +36,7 @@ class HtmlDoc implements Doc {
*/
public HtmlDoc(PrintStream ps, DocString title, URI style) {
this.ps = ps;
+ mSections = new ArrayList<>();
ps.println("<!DOCTYPE html>");
ps.println("<html>");
@@ -59,9 +62,10 @@ class HtmlDoc implements Doc {
@Override
public void section(String title) {
- ps.print("<h2>");
+ ps.format("<h2 id=\"%d\">", mSections.size());
ps.print(DocString.text(title).html());
ps.println(":</h2>");
+ mSections.add(title);
}
@Override
@@ -182,8 +186,17 @@ class HtmlDoc implements Doc {
mCurrentTableColumns = null;
}
+ private void sidebar() {
+ ps.println("<div class=\"sidebar\">");
+ for (int i = 0; i < mSections.size(); i++) {
+ ps.format("<p><a href=\"#%d\">%s</a></p>", i, mSections.get(i));
+ }
+ ps.println("</div>");
+ }
+
@Override
public void close() {
+ sidebar();
ps.println("</body>");
ps.println("</html>");
ps.close();
diff --git a/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java b/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
index 81611b6c72..4cdbaf4270 100644
--- a/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
+++ b/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
@@ -111,7 +111,7 @@ class ObjectsHandler implements AhatHandler {
heapChoice.append(")");
doc.description(DocString.text("Heap"), heapChoice);
- doc.description(DocString.text("Count"), DocString.format("%,14d", insts.size()));
+ doc.description(DocString.text("Count"), DocString.format("%,d", insts.size()));
doc.end();
doc.println(DocString.text(""));
diff --git a/tools/ahat/src/main/com/android/ahat/OverviewHandler.java b/tools/ahat/src/main/com/android/ahat/OverviewHandler.java
index 5f0b473d1d..c6f4a54080 100644
--- a/tools/ahat/src/main/com/android/ahat/OverviewHandler.java
+++ b/tools/ahat/src/main/com/android/ahat/OverviewHandler.java
@@ -57,8 +57,6 @@ class OverviewHandler implements AhatHandler {
doc.section("Bytes Retained by Heap");
printHeapSizes(doc);
-
- doc.big(Menu.getMenu());
}
private void printHeapSizes(Doc doc) {
diff --git a/tools/ahat/src/main/com/android/ahat/SiteHandler.java b/tools/ahat/src/main/com/android/ahat/SiteHandler.java
index 5093f0d43e..671784efca 100644
--- a/tools/ahat/src/main/com/android/ahat/SiteHandler.java
+++ b/tools/ahat/src/main/com/android/ahat/SiteHandler.java
@@ -102,7 +102,7 @@ class SiteHandler implements AhatHandler {
DocString.link(
DocString.formattedUri("objects?id=%d&heap=%s&class=%s",
site.getId(), info.heap.getName(), className),
- DocString.format("%,14d", info.numInstances)),
+ DocString.format("%,d", info.numInstances)),
DocString.delta(false, false, info.numInstances, baseinfo.numInstances),
DocString.text(info.heap.getName()),
Summarizer.summarize(info.classObj));
diff --git a/tools/ahat/src/test-dump/Main.java b/tools/ahat/src/test-dump/Main.java
index 2e2907690d..711d66200c 100644
--- a/tools/ahat/src/test-dump/Main.java
+++ b/tools/ahat/src/test-dump/Main.java
@@ -43,6 +43,10 @@ public class Main {
// Allocate the instance of DumpedStuff.
stuff = new DumpedStuff(baseline);
+ // Preemptively garbage collect to avoid an inopportune GC triggering
+ // after this.
+ Runtime.getRuntime().gc();
+
// Create a bunch of unreachable objects pointing to basicString for the
// reverseReferencesAreNotUnreachable test
for (int i = 0; i < 100; i++) {
diff --git a/tools/ahat/src/test/com/android/ahat/InstanceTest.java b/tools/ahat/src/test/com/android/ahat/InstanceTest.java
index 376122ba23..1f290304c0 100644
--- a/tools/ahat/src/test/com/android/ahat/InstanceTest.java
+++ b/tools/ahat/src/test/com/android/ahat/InstanceTest.java
@@ -224,6 +224,7 @@ public class InstanceTest {
@Test
public void reachability() throws IOException {
TestDump dump = TestDump.getTestDump();
+ // We were careful to avoid GC before dumping, so nothing here should be null.
AhatInstance strong1 = dump.getDumpedAhatInstance("reachabilityReferenceChain");
AhatInstance soft1 = strong1.getField("referent").asAhatInstance();
AhatInstance strong2 = soft1.getField("referent").asAhatInstance();
diff --git a/tools/art_boot.cc b/tools/art_boot.cc
new file mode 100644
index 0000000000..f725fc828e
--- /dev/null
+++ b/tools/art_boot.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// This binary is run on boot as a oneshot service. It should not be run at any
+// other point.
+
+#include <string>
+
+#include "android-base/logging.h"
+#include "android-base/properties.h"
+
+// Copies the value of one system property to another if it isn't empty and
+// passes the predicate test_fn.
+static void CopyPropertyIf(const char* src, const char* dst, bool (*test_fn)(const std::string&)) {
+ std::string prop = android::base::GetProperty(src, "");
+ if (prop.empty()) {
+ LOG(INFO) << "Property " << src << " not set";
+ } else if (!test_fn(prop)) {
+ LOG(INFO) << "Property " << src << " has ignored value " << prop;
+ } else {
+ if (android::base::SetProperty(dst, prop)) {
+ LOG(INFO) << "Set property " << dst << " to " << prop << " from " << src;
+ } else {
+ LOG(ERROR) << "Failed to set property " << dst << " to " << prop;
+ }
+ }
+}
+
+int main(int, char** argv) {
+ android::base::InitLogging(argv);
+
+ // Copy properties that must only be set at boot and not change value later.
+ // Note that P/H can change the properties in the experiment namespaces at any
+ // time.
+ CopyPropertyIf("persist.device_config.runtime_native_boot.useartservice",
+ "dalvik.vm.useartservice",
+ // If an OEM has set dalvik.vm.useartservice to false we
+ // shouldn't override it to true from the P/H property.
+ [](const std::string& prop) { return prop == "false"; });
+
+ return 0;
+}
diff --git a/tools/art_verifier/art_verifier.cc b/tools/art_verifier/art_verifier.cc
index 2f2562b973..e68d2ca3d5 100644
--- a/tools/art_verifier/art_verifier.cc
+++ b/tools/art_verifier/art_verifier.cc
@@ -42,11 +42,9 @@ namespace {
bool LoadDexFile(const std::string& dex_filename,
std::vector<std::unique_ptr<const DexFile>>* dex_files) {
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(dex_filename);
std::string error_msg;
- if (!dex_file_loader.Open(dex_filename.c_str(),
- dex_filename.c_str(),
- /* verify= */ true,
+ if (!dex_file_loader.Open(/* verify= */ true,
/* verify_checksum= */ true,
&error_msg,
dex_files)) {
diff --git a/tools/build_linux_bionic.sh b/tools/build_linux_bionic.sh
index 8992512d57..bbe71b6f6f 100755
--- a/tools/build_linux_bionic.sh
+++ b/tools/build_linux_bionic.sh
@@ -16,83 +16,38 @@
# This will build a target using linux_bionic. It can be called with normal make
# flags.
-#
-# TODO This runs a 'm clean' prior to building the targets in order to ensure
-# that obsolete kati files don't mess up the build.
-if [[ -z $ANDROID_BUILD_TOP ]]; then
- pushd .
-else
- pushd $ANDROID_BUILD_TOP
-fi
+set -e
if [ ! -d art ]; then
echo "Script needs to be run at the root of the android tree"
exit 1
fi
+export TARGET_PRODUCT=linux_bionic
+
+# Avoid Soong error about invalid dependencies on disabled libLLVM_android,
+# which we get due to the --soong-only mode. (Another variant is to set
+# SOONG_ALLOW_MISSING_DEPENDENCIES).
+export FORCE_BUILD_LLVM_COMPONENTS=true
+
# TODO(b/194433871): Set MODULE_BUILD_FROM_SOURCE to disable prebuilt modules,
# which Soong otherwise can create duplicate install rules for in --soong-only
# mode.
-soong_args="MODULE_BUILD_FROM_SOURCE=true"
+export MODULE_BUILD_FROM_SOURCE=true
# Switch the build system to unbundled mode in the reduced manifest branch.
if [ ! -d frameworks/base ]; then
- soong_args="$soong_args TARGET_BUILD_UNBUNDLED=true"
-fi
-
-source build/envsetup.sh >&/dev/null # for get_build_var
-# Soong needs a bunch of variables set and will not run if they are missing.
-# The default values of these variables is only contained in make, so use
-# nothing to create the variables then remove all the other artifacts.
-# Lunch since it seems we cannot find the build-number otherwise.
-lunch aosp_x86-eng
-build/soong/soong_ui.bash --make-mode $soong_args nothing
-
-if [ $? != 0 ]; then
- exit 1
+ export TARGET_BUILD_UNBUNDLED=true
fi
-out_dir=$(get_build_var OUT_DIR)
-host_out=$(get_build_var HOST_OUT)
-
-# TODO(b/31559095) Figure out a better way to do this.
-#
-# There is no good way to force soong to generate host-bionic builds currently
-# so this is a hacky workaround.
-tmp_soong_var=$(mktemp --tmpdir soong.variables.bak.XXXXXX)
-tmp_build_number=$(cat ${out_dir}/soong/build_number.txt)
-
-cat $out_dir/soong/soong.variables > ${tmp_soong_var}
-
-# See comment above about b/123645297 for why we cannot just do m clean. Clear
-# out all files except for intermediates and installed files and dexpreopt.config.
-find $out_dir/ -maxdepth 1 -mindepth 1 \
- -not -name soong \
- -not -name host \
- -not -name target | xargs -I '{}' rm -rf '{}'
-find $out_dir/soong/ -maxdepth 1 -mindepth 1 \
- -not -name .intermediates \
- -not -name host \
- -not -name dexpreopt.config \
- -not -name target | xargs -I '{}' rm -rf '{}'
-
-python3 <<END - ${tmp_soong_var} ${out_dir}/soong/soong.variables
-import json
-import sys
-x = json.load(open(sys.argv[1]))
-x['Allow_missing_dependencies'] = True
-x['HostArch'] = 'x86_64'
-x['CrossHost'] = 'linux_bionic'
-x['CrossHostArch'] = 'x86_64'
-if 'CrossHostSecondaryArch' in x:
- del x['CrossHostSecondaryArch']
-json.dump(x, open(sys.argv[2], mode='w'))
-END
-
-rm $tmp_soong_var
+vars="$(build/soong/soong_ui.bash --dumpvars-mode --vars="OUT_DIR BUILD_NUMBER")"
+# Assign to a variable and eval that, since bash ignores any error status from
+# the command substitution if it's directly on the eval line.
+eval $vars
-# Write a new build-number
-echo ${tmp_build_number}_SOONG_ONLY_BUILD > ${out_dir}/soong/build_number.txt
+# This file is currently not created in --soong-only mode, but some build
+# targets depend on it.
+printf %s "${BUILD_NUMBER}" > ${OUT_DIR}/soong/build_number.txt
-build/soong/soong_ui.bash --make-mode --skip-config --soong-only $soong_args $@
+build/soong/soong_ui.bash --make-mode --soong-only "$@"
diff --git a/tools/build_linux_bionic_tests.sh b/tools/build_linux_bionic_tests.sh
index 7379e9a092..0470d6d24c 100755
--- a/tools/build_linux_bionic_tests.sh
+++ b/tools/build_linux_bionic_tests.sh
@@ -14,64 +14,36 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-if [[ -z $ANDROID_BUILD_TOP ]]; then
- pushd .
-else
- pushd $ANDROID_BUILD_TOP
-fi
+set -e
if [ ! -d art ]; then
echo "Script needs to be run at the root of the android tree"
exit 1
fi
-soong_args=""
-
# Switch the build system to unbundled mode in the reduced manifest branch.
if [ ! -d frameworks/base ]; then
- soong_args="$soong_args TARGET_BUILD_UNBUNDLED=true"
+ export TARGET_BUILD_UNBUNDLED=true
fi
-source build/envsetup.sh >&/dev/null # for get_build_var
-
-out_dir=$(get_build_var OUT_DIR)
-host_out=$(get_build_var HOST_OUT)
-
-# TODO(b/31559095) Figure out a better way to do this.
-#
-# There is no good way to force soong to generate host-bionic builds currently
-# so this is a hacky workaround.
+vars="$(build/soong/soong_ui.bash --dumpvars-mode --vars="OUT_DIR HOST_OUT")"
+# Assign to a variable and eval that, since bash ignores any error status from
+# the command substitution if it's directly on the eval line.
+eval $vars
# First build all the targets still in .mk files (also build normal glibc host
# targets so we know what's needed to run the tests).
-build/soong/soong_ui.bash --make-mode $soong_args "$@" test-art-host-run-test-dependencies build-art-host-tests
-if [ $? != 0 ]; then
- exit 1
-fi
+build/soong/soong_ui.bash --make-mode "$@" test-art-host-run-test-dependencies build-art-host-tests
-tmp_soong_var=$(mktemp --tmpdir soong.variables.bak.XXXXXX)
+# Next build the Linux host Bionic targets in --soong-only mode.
+export TARGET_PRODUCT=linux_bionic
-echo "Saving soong.variables to " $tmp_soong_var
-cat $out_dir/soong/soong.variables > ${tmp_soong_var}
-python3 <<END - ${tmp_soong_var} ${out_dir}/soong/soong.variables
-import json
-import sys
-x = json.load(open(sys.argv[1]))
-x['Allow_missing_dependencies'] = True
-x['HostArch'] = 'x86_64'
-x['CrossHost'] = 'linux_bionic'
-x['CrossHostArch'] = 'x86_64'
-if 'CrossHostSecondaryArch' in x:
- del x['CrossHostSecondaryArch']
-json.dump(x, open(sys.argv[2], mode='w'))
-END
-if [ $? != 0 ]; then
- mv $tmp_soong_var $out_dir/soong/soong.variables
- exit 2
-fi
+# Avoid Soong error about invalid dependencies on disabled libLLVM_android,
+# which we get due to the --soong-only mode. (Another variant is to set
+# SOONG_ALLOW_MISSING_DEPENDENCIES).
+export FORCE_BUILD_LLVM_COMPONENTS=true
-soong_out=$out_dir/soong/host/linux_bionic-x86
+soong_out=$OUT_DIR/soong/host/linux_bionic-x86
declare -a bionic_targets
# These are the binaries actually used in tests. Since some of the files are
# java targets or 32 bit we cannot just do the same find for the bin files.
@@ -89,24 +61,10 @@ bionic_targets=(
$soong_out/bin/hprof-conv
$soong_out/bin/signal_dumper
$soong_out/lib64/libclang_rt.ubsan_standalone-x86_64-android.so
- $(find $host_out/apex/com.android.art.host.zipapex -type f | sed "s:$host_out:$soong_out:g")
- $(find $host_out/lib64 -type f | sed "s:$host_out:$soong_out:g")
- $(find $host_out/nativetest64 -type f | sed "s:$host_out:$soong_out:g"))
+ $(find $HOST_OUT/apex/com.android.art.host.zipapex -type f | sed "s:$HOST_OUT:$soong_out:g")
+ $(find $HOST_OUT/lib64 -type f | sed "s:$HOST_OUT:$soong_out:g")
+ $(find $HOST_OUT/nativetest64 -type f | sed "s:$HOST_OUT:$soong_out:g"))
echo building ${bionic_targets[*]}
-build/soong/soong_ui.bash --make-mode --skip-config --soong-only $soong_args "$@" ${bionic_targets[*]}
-ret=$?
-
-mv $tmp_soong_var $out_dir/soong/soong.variables
-
-# Having built with host-bionic confuses soong somewhat by making it think the
-# linux_bionic targets are needed for art phony targets like
-# test-art-host-run-test-dependencies. To work around this blow away all
-# ninja files in OUT_DIR. The build system is smart enough to not need to
-# rebuild stuff so this should be fine.
-rm -f $OUT_DIR/*.ninja $OUT_DIR/soong/*.ninja
-
-popd
-
-exit $ret
+build/soong/soong_ui.bash --make-mode --soong-only "$@" ${bionic_targets[*]}
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
index 48fc004506..cac98cb131 100755
--- a/tools/buildbot-build.sh
+++ b/tools/buildbot-build.sh
@@ -25,8 +25,6 @@ if [ ! -d art ]; then
exit 1
fi
-TARGET_ARCH=$(source build/envsetup.sh > /dev/null; get_build_var TARGET_ARCH)
-
# Logic for setting out_dir from build/make/core/envsetup.mk:
if [[ -z $OUT_DIR ]]; then
if [[ -z $OUT_DIR_COMMON_BASE ]]; then
@@ -69,6 +67,9 @@ while true; do
elif [[ "$1" == "--showcommands" ]]; then
showcommands="showcommands"
shift
+ elif [[ "$1" == "--dist" ]]; then
+ common_targets="$common_targets dist"
+ shift
elif [[ "$1" == "" ]]; then
break
else
@@ -83,11 +84,25 @@ if [[ $build_host == "no" ]] && [[ $build_target == "no" ]]; then
build_target="yes"
fi
-# Allow to build successfully in master-art.
-extra_args="SOONG_ALLOW_MISSING_DEPENDENCIES=true"
+implementation_libs=(
+ "heapprofd_client_api"
+ "libandroid_runtime_lazy"
+ "libartpalette-system"
+ "libbinder"
+ "libbinder_ndk"
+ "libcutils"
+ "libutils"
+ "libvndksupport"
+)
-# Switch the build system to unbundled mode in the reduced manifest branch.
-if [ ! -d frameworks/base ]; then
+if [ -d frameworks/base ]; then
+ # In full manifest branches, build the implementation libraries from source
+ # instead of using prebuilts.
+ common_targets="$common_targets ${implementation_libs[*]}"
+else
+ # Allow to build successfully in master-art.
+ extra_args="SOONG_ALLOW_MISSING_DEPENDENCIES=true BUILD_BROKEN_DISABLE_BAZEL=true"
+ # Switch the build system to unbundled mode in the reduced manifest branch.
extra_args="$extra_args TARGET_BUILD_UNBUNDLED=true"
fi
@@ -120,13 +135,12 @@ if [[ $build_target == "yes" ]]; then
# Indirect dependencies in the platform, e.g. through heapprofd_client_api.
# These are built to go into system/lib(64) to be part of the system linker
# namespace.
- make_command+=" libbacktrace libnetd_client-target libprocinfo libtombstoned_client libunwindstack"
+ make_command+=" libnetd_client-target libprocinfo libtombstoned_client libunwindstack"
# Stubs for other APEX SDKs, for use by vogar. Referenced from DEVICE_JARS in
# external/vogar/src/vogar/ModeId.java.
# Note these go into out/target/common/obj/JAVA_LIBRARIES which isn't removed
# by "m installclean".
make_command+=" i18n.module.public.api.stubs conscrypt.module.public.api.stubs"
- make_command+=" ${ANDROID_PRODUCT_OUT#"${ANDROID_BUILD_TOP}/"}/system/etc/public.libraries.txt"
# Targets required to generate a linker configuration for device within the
# chroot environment. The *.libraries.txt targets are required by
# the source linkerconfig but not included in the prebuilt one.
@@ -166,6 +180,8 @@ if [[ $build_target == "yes" ]]; then
# Extract prebuilt APEXes.
debugfs=$ANDROID_HOST_OUT/bin/debugfs_static
+ fsckerofs=$ANDROID_HOST_OUT/bin/fsck.erofs
+ blkid=$ANDROID_HOST_OUT/bin/blkid_static
for apex in ${apexes[@]}; do
dir="$ANDROID_PRODUCT_OUT/system/apex/${apex}"
apexbase="$ANDROID_PRODUCT_OUT/system/apex/${apex}"
@@ -179,20 +195,16 @@ if [[ $build_target == "yes" ]]; then
msginfo "Extracting APEX file:" "${file}"
rm -rf $dir
mkdir -p $dir
- $ANDROID_HOST_OUT/bin/deapexer --debugfs_path $debugfs extract $file $dir
+ $ANDROID_HOST_OUT/bin/deapexer --debugfs_path $debugfs --fsckerofs_path $fsckerofs \
+ --blkid_path $blkid extract $file $dir
fi
done
- # Replace stub libraries with implemenation libraries: because we do chroot
+ # Replace stub libraries with implementation libraries: because we do chroot
# testing, we need to install an implementation of the libraries (and cannot
# rely on the one already installed on the device, if the device is post R and
# has it).
- implementation_libs=(
- "heapprofd_client_api.so"
- "libartpalette-system.so"
- "liblog.so"
- )
- if [ -d prebuilts/runtime/mainline/platform/impl ]; then
+ if [ -d prebuilts/runtime/mainline/platform/impl -a ! -d frameworks/base ]; then
if [[ $TARGET_ARCH = arm* ]]; then
arch32=arm
arch64=arm64
@@ -200,18 +212,22 @@ if [[ $build_target == "yes" ]]; then
arch32=x86
arch64=x86_64
fi
- for so in ${implementation_libs[@]}; do
- if [ -d "$ANDROID_PRODUCT_OUT/system/lib" ]; then
- cmd="cp -p prebuilts/runtime/mainline/platform/impl/$arch32/$so $ANDROID_PRODUCT_OUT/system/lib/$so"
- msginfo "Executing" "$cmd"
- eval "$cmd"
- fi
- if [ -d "$ANDROID_PRODUCT_OUT/system/lib64" ]; then
- cmd="cp -p prebuilts/runtime/mainline/platform/impl/$arch64/$so $ANDROID_PRODUCT_OUT/system/lib64/$so"
- msginfo "Executing" "$cmd"
- eval "$cmd"
- fi
- done
+ if [ "$TARGET_ARCH" = riscv64 ]; then
+ true # no 32-bit arch for RISC-V
+ else
+ for so in ${implementation_libs[@]}; do
+ if [ -d "$ANDROID_PRODUCT_OUT/system/lib" ]; then
+ cmd="cp -p prebuilts/runtime/mainline/platform/impl/$arch32/${so}.so $ANDROID_PRODUCT_OUT/system/lib/${so}.so"
+ msginfo "Executing" "$cmd"
+ eval "$cmd"
+ fi
+ if [ -d "$ANDROID_PRODUCT_OUT/system/lib64" ]; then
+ cmd="cp -p prebuilts/runtime/mainline/platform/impl/$arch64/${so}.so $ANDROID_PRODUCT_OUT/system/lib64/${so}.so"
+ msginfo "Executing" "$cmd"
+ eval "$cmd"
+ fi
+ done
+ fi
fi
# Create canonical name -> file name symlink in the symbol directory for the
@@ -299,6 +315,11 @@ if [[ $build_target == "yes" ]]; then
mkdir -p $linkerconfig_root/system
cp -r $ANDROID_PRODUCT_OUT/system/etc $linkerconfig_root/system
+ # Use our smaller public.libraries.txt that contains only the public libraries
+ # pushed to the chroot directory.
+ cp $ANDROID_BUILD_TOP/art/tools/public.libraries.buildbot.txt \
+ $linkerconfig_root/system/etc/public.libraries.txt
+
# For linkerconfig to pick up the APEXes correctly we need to make them
# available in $linkerconfig_root/apex.
mkdir -p $linkerconfig_root/apex
diff --git a/tools/buildbot-cleanup-device.sh b/tools/buildbot-cleanup-device.sh
index 7dee149129..7fd57b413e 100755
--- a/tools/buildbot-cleanup-device.sh
+++ b/tools/buildbot-cleanup-device.sh
@@ -16,7 +16,22 @@
. "$(dirname $0)/buildbot-utils.sh"
-# Setup as root, as device cleanup requires it.
+# Testing on a Linux VM requires special cleanup.
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+ [[ -d "$ART_TEST_VM_DIR" ]] || { msgfatal "no VM found in $ART_TEST_VM_DIR"; }
+ $ART_SSH_CMD "true" || { msgfatal "VM not responding (tried \"$ART_SSH_CMD true\""; }
+ $ART_SSH_CMD "
+ sudo umount $ART_TEST_CHROOT/proc
+ sudo umount $ART_TEST_CHROOT/sys
+ sudo umount $ART_TEST_CHROOT/dev
+ sudo umount $ART_TEST_CHROOT/bin
+ sudo umount $ART_TEST_CHROOT/lib
+ rm -rf $ART_TEST_CHROOT
+ "
+ exit 0
+fi
+
+# Regular Android device. Setup as root, as device cleanup requires it.
adb root
adb wait-for-device
diff --git a/tools/buildbot-setup-device.sh b/tools/buildbot-setup-device.sh
index ad2c59cea5..90d680b7d2 100755
--- a/tools/buildbot-setup-device.sh
+++ b/tools/buildbot-setup-device.sh
@@ -25,7 +25,39 @@ else
verbose=false
fi
-# Setup as root, as some actions performed here require it.
+# Testing on a Linux VM requires special setup.
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+ [[ -d "$ART_TEST_VM_DIR" ]] || { msgfatal "no VM found in $ART_TEST_VM_DIR"; }
+ $ART_SSH_CMD "true" || { msgerror "no VM (tried \"$ART_SSH_CMD true\""; }
+ $ART_SSH_CMD "
+ mkdir $ART_TEST_CHROOT
+
+ mkdir $ART_TEST_CHROOT/apex
+ mkdir $ART_TEST_CHROOT/bin
+ mkdir $ART_TEST_CHROOT/data
+ mkdir $ART_TEST_CHROOT/data/local
+ mkdir $ART_TEST_CHROOT/data/local/tmp
+ mkdir $ART_TEST_CHROOT/dev
+ mkdir $ART_TEST_CHROOT/etc
+ mkdir $ART_TEST_CHROOT/lib
+ mkdir $ART_TEST_CHROOT/linkerconfig
+ mkdir $ART_TEST_CHROOT/proc
+ mkdir $ART_TEST_CHROOT/sys
+ mkdir $ART_TEST_CHROOT/system
+ mkdir $ART_TEST_CHROOT/tmp
+
+ sudo mount -t proc /proc art-test-chroot/proc
+ sudo mount -t sysfs /sys art-test-chroot/sys
+ sudo mount --bind /dev art-test-chroot/dev
+ sudo mount --bind /bin art-test-chroot/bin
+ sudo mount --bind /lib art-test-chroot/lib
+ $ART_CHROOT_CMD echo \"Hello from chroot! I am \$(uname -a).\"
+ "
+ exit 0
+fi
+
+# Regular Android device. Setup as root, as some actions performed here require it.
+adb version
adb root
adb wait-for-device
@@ -36,7 +68,11 @@ msginfo "Date on device"
adb shell date
host_seconds_since_epoch=$(date -u +%s)
-device_seconds_since_epoch=$(adb shell date -u +%s)
+
+# Get the device time in seconds, but filter the output as some
+# devices emit CRLF at the end of the command which then breaks the
+# time comparisons in this script (Hammerhead, MRA59G 2457013).
+device_seconds_since_epoch=$(adb shell date -u +%s | tr -c -d '[:digit:]')
abs_time_difference_in_seconds=$(expr $host_seconds_since_epoch - $device_seconds_since_epoch)
if [ $abs_time_difference_in_seconds -lt 0 ]; then
@@ -173,6 +209,8 @@ if [[ -n "$ART_TEST_CHROOT" ]]; then
|| adb shell mount -o bind /dev "$ART_TEST_CHROOT/dev"
adb shell mount | grep -q "^devpts on $ART_TEST_CHROOT/dev/pts type devpts " \
|| adb shell mount -o bind /dev/pts "$ART_TEST_CHROOT/dev/pts"
+ adb shell mount | grep -q " on $ART_TEST_CHROOT/dev/cpuset type cgroup " \
+ || adb shell mount -o bind /dev/cpuset "$ART_TEST_CHROOT/dev/cpuset"
# Create /apex directory in chroot.
adb shell mkdir -p "$ART_TEST_CHROOT/apex"
diff --git a/tools/buildbot-sync.sh b/tools/buildbot-sync.sh
index 28dab0ce04..ef9ec8b3a0 100755
--- a/tools/buildbot-sync.sh
+++ b/tools/buildbot-sync.sh
@@ -20,27 +20,21 @@ set -e
. "$(dirname $0)/buildbot-utils.sh"
-# Setup as root, as some actions performed here require it.
-adb root
-adb wait-for-device
-
-if [[ -z "$ANDROID_BUILD_TOP" ]]; then
- msgerror 'ANDROID_BUILD_TOP environment variable is empty; did you forget to run `lunch`?'
- exit 1
-fi
-
-if [[ -z "$ANDROID_PRODUCT_OUT" ]]; then
- msgerror 'ANDROID_PRODUCT_OUT environment variable is empty; did you forget to run `lunch`?'
- exit 1
+if [[ -z "$ART_TEST_ON_VM" ]]; then
+ # Setup as root, as some actions performed here require it.
+ adb root
+ adb wait-for-device
fi
-if [[ -z "$ART_TEST_CHROOT" ]]; then
- msgerror 'ART_TEST_CHROOT environment variable is empty; ' \
+if [[ -z "$ANDROID_BUILD_TOP" ]]; then
+ msgfatal 'ANDROID_BUILD_TOP environment variable is empty; did you forget to run `lunch`?'
+elif [[ -z "$ANDROID_PRODUCT_OUT" ]]; then
+ msgfatal 'ANDROID_PRODUCT_OUT environment variable is empty; did you forget to run `lunch`?'
+elif [[ -z "$ART_TEST_CHROOT" ]]; then
+ msgfatal 'ART_TEST_CHROOT environment variable is empty; ' \
'please set it before running this script.'
- exit 1
fi
-
# Sync relevant product directories
# ---------------------------------
@@ -53,23 +47,40 @@ fi
continue
fi
msginfo "Syncing $dir directory..."
- adb shell mkdir -p "$ART_TEST_CHROOT/$dir"
- adb push $dir "$ART_TEST_CHROOT/$(dirname $dir)"
+ if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_RSYNC_CMD -R $dir "$ART_TEST_SSH_USER@$ART_TEST_SSH_HOST:$ART_TEST_CHROOT"
+ else
+ adb shell mkdir -p "$ART_TEST_CHROOT/$dir"
+ adb push $dir "$ART_TEST_CHROOT/$(dirname $dir)"
+ fi
done
)
# Overwrite the default public.libraries.txt file with a smaller one that
# contains only the public libraries pushed to the chroot directory.
-adb push "$ANDROID_BUILD_TOP/art/tools/public.libraries.buildbot.txt" \
- "$ART_TEST_CHROOT/system/etc/public.libraries.txt"
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_RSYNC_CMD "$ANDROID_BUILD_TOP/art/tools/public.libraries.buildbot.txt" \
+ "$ART_TEST_SSH_USER@$ART_TEST_SSH_HOST:$ART_TEST_CHROOT/system/etc/public.libraries.txt"
+else
+ adb push "$ANDROID_BUILD_TOP/art/tools/public.libraries.buildbot.txt" \
+ "$ART_TEST_CHROOT/system/etc/public.libraries.txt"
+fi
# Create the framework directory if it doesn't exist. Some gtests need it.
-adb shell mkdir -p "$ART_TEST_CHROOT/system/framework"
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_SSH_CMD "$ART_CHROOT_CMD mkdir -p $ART_TEST_CHROOT/system/framework"
+else
+ adb shell mkdir -p "$ART_TEST_CHROOT/system/framework"
+fi
# APEX packages activation.
# -------------------------
-adb shell mkdir -p "$ART_TEST_CHROOT/apex"
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_SSH_CMD "$ART_CHROOT_CMD mkdir -p $ART_TEST_CHROOT/apex"
+else
+ adb shell mkdir -p "$ART_TEST_CHROOT/apex"
+fi
# Manually "activate" the flattened APEX $1 by syncing it to /apex/$2 in the
# chroot. $2 defaults to $1.
@@ -95,12 +106,19 @@ activate_apex() {
msginfo "Extracting APEX ${src_apex_file}..."
mkdir -p $src_apex_path
$ANDROID_HOST_OUT/bin/deapexer --debugfs_path $ANDROID_HOST_OUT/bin/debugfs_static \
+ --fsckerofs_path $ANDROID_HOST_OUT/bin/fsck.erofs \
+ --blkid_path $ANDROID_HOST_OUT/bin/blkid_static \
extract ${src_apex_file} $src_apex_path
fi
msginfo "Activating APEX ${src_apex} as ${dst_apex}..."
- adb shell rm -rf "$ART_TEST_CHROOT/apex/${dst_apex}"
- adb push $src_apex_path "$ART_TEST_CHROOT/apex/${dst_apex}"
+ if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_RSYNC_CMD $src_apex_path/* \
+ "$ART_TEST_SSH_USER@$ART_TEST_SSH_HOST:$ART_TEST_CHROOT/apex/${dst_apex}"
+ else
+ adb shell rm -rf "$ART_TEST_CHROOT/apex/${dst_apex}"
+ adb push $src_apex_path "$ART_TEST_CHROOT/apex/${dst_apex}"
+ fi
}
# "Activate" the required APEX modules.
@@ -111,19 +129,34 @@ activate_apex com.android.tzdata
activate_apex com.android.conscrypt
activate_apex com.android.os.statsd
-# Generate primary boot images on device for testing.
-for b in {32,64}; do
- basename="generate-boot-image$b"
- bin_on_host="$ANDROID_PRODUCT_OUT/system/bin/$basename"
- bin_on_device="/data/local/tmp/$basename"
- output_dir="/system/framework/art_boot_images"
- if [ -f $bin_on_host ]; then
- msginfo "Generating the primary boot image ($b-bit)..."
- adb push "$bin_on_host" "$ART_TEST_CHROOT$bin_on_device"
- adb shell mkdir -p "$ART_TEST_CHROOT$output_dir"
- # `compiler-filter=speed-profile` is required because OatDumpTest checks the compiled code in
- # the boot image.
- adb shell chroot "$ART_TEST_CHROOT" \
- "$bin_on_device" --output-dir=$output_dir --compiler-filter=speed-profile
- fi
-done
+if [[ "$TARGET_ARCH" = "riscv64" ]]; then
+ true # Skip boot image generation for RISC-V; it's not supported.
+else
+ # Generate primary boot images on device for testing.
+ for b in {32,64}; do
+ basename="generate-boot-image$b"
+ bin_on_host="$ANDROID_PRODUCT_OUT/system/bin/$basename"
+ bin_on_device="/data/local/tmp/$basename"
+ output_dir="/system/framework/art_boot_images"
+ if [ -f $bin_on_host ]; then
+ msginfo "Generating the primary boot image ($b-bit)..."
+ if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_RSYNC_CMD "$bin_on_host" \
+ "$ART_TEST_SSH_USER@$ART_TEST_SSH_HOST:$ART_TEST_CHROOT$bin_on_device"
+ $ART_SSH_CMD "mkdir -p $ART_TEST_CHROOT$output_dir"
+ else
+ adb push "$bin_on_host" "$ART_TEST_CHROOT$bin_on_device"
+ adb shell mkdir -p "$ART_TEST_CHROOT$output_dir"
+ fi
+ # `compiler-filter=speed-profile` is required because OatDumpTest checks the compiled code in
+ # the boot image.
+ if [[ -n "$ART_TEST_ON_VM" ]]; then
+ $ART_SSH_CMD \
+ "$ART_CHROOT_CMD $bin_on_device --output-dir=$output_dir --compiler-filter=speed-profile"
+ else
+ adb shell chroot "$ART_TEST_CHROOT" \
+ "$bin_on_device" --output-dir=$output_dir --compiler-filter=speed-profile
+ fi
+ fi
+ done
+fi
diff --git a/tools/buildbot-teardown-device.sh b/tools/buildbot-teardown-device.sh
index 927e3c5421..e71dcbef0b 100755
--- a/tools/buildbot-teardown-device.sh
+++ b/tools/buildbot-teardown-device.sh
@@ -19,6 +19,8 @@
. "$(dirname $0)/buildbot-utils.sh"
+[[ -n "$ART_TEST_ON_VM" ]] && exit 0
+
# Setup as root, as some actions performed here require it.
adb root
adb wait-for-device
@@ -79,7 +81,7 @@ if [[ -n "$ART_TEST_CHROOT" ]]; then
local remove_dir=$3
local dir="$ART_TEST_CHROOT/$dir_in_chroot"
adb shell test -d "$dir" \
- && adb shell mount | grep -q "^$fstype on $dir type $fstype " \
+ && adb shell mount | grep -q " on $dir type $fstype " \
&& if adb shell umount "$dir"; then
$remove_dir && adb shell rmdir "$dir"
else
@@ -95,6 +97,7 @@ if [[ -n "$ART_TEST_CHROOT" ]]; then
adb shell rm -rf "$ART_TEST_CHROOT/apex"
# Remove /dev from chroot.
+ remove_filesystem_from_chroot dev/cpuset cgroup false
remove_filesystem_from_chroot dev/pts devpts false
remove_filesystem_from_chroot dev tmpfs true
diff --git a/tools/buildbot-utils.sh b/tools/buildbot-utils.sh
index 32ed234d90..6a0714dcd4 100755
--- a/tools/buildbot-utils.sh
+++ b/tools/buildbot-utils.sh
@@ -53,7 +53,43 @@ function msgerror() {
echo -e "${boldred}Error: ${nc}${message}"
}
+function msgfatal() {
+ local message="$*"
+ echo -e "${boldred}Fatal: ${nc}${message}"
+ exit 1
+}
+
function msgnote() {
local message="$*"
echo -e "${boldcyan}Note: ${nc}${message}"
}
+
+export TARGET_ARCH=$(build/soong/soong_ui.bash --dumpvar-mode TARGET_ARCH)
+
+# Do some checks and prepare environment for tests that run on Linux (not on Android).
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+ if [[ -z $ANDROID_BUILD_TOP ]]; then
+ msgfatal "ANDROID_BUILD_TOP is not set"
+ elif [[ -z "$ART_TEST_SSH_USER" ]]; then
+ msgfatal "ART_TEST_SSH_USER not set"
+ elif [[ -z "$ART_TEST_SSH_HOST" ]]; then
+ msgfatal "ART_TEST_SSH_HOST not set"
+ elif [[ -z "$ART_TEST_SSH_PORT" ]]; then
+ msgfatal "ART_TEST_SSH_PORT not set"
+ fi
+
+ export ART_TEST_CHROOT="/home/$ART_TEST_SSH_USER/art-test-chroot"
+ export ART_CHROOT_CMD="unshare --user --map-root-user chroot art-test-chroot"
+ export ART_SSH_CMD="ssh -q -p $ART_TEST_SSH_PORT $ART_TEST_SSH_USER@$ART_TEST_SSH_HOST -o IdentityAgent=none"
+ export ART_SCP_CMD="scp -P $ART_TEST_SSH_PORT -p -r -o IdentityAgent=none"
+ export ART_RSYNC_CMD="rsync -az"
+ export RSYNC_RSH="ssh -p $ART_TEST_SSH_PORT -o IdentityAgent=none" # don't prefix with "ART_", rsync expects this name
+
+ if [[ "$TARGET_ARCH" =~ ^(arm64|riscv64)$ ]]; then
+ export ART_TEST_VM_IMG="ubuntu-22.04-server-cloudimg-$TARGET_ARCH.img"
+ export ART_TEST_VM_DIR="$ANDROID_BUILD_TOP/vm/$TARGET_ARCH"
+ export ART_TEST_VM="$ART_TEST_VM_DIR/$ART_TEST_VM_IMG"
+ else
+ msgfatal "unexpected TARGET_ARCH=$TARGET_ARCH; expected one of {arm64,riscv64}"
+ fi
+fi
diff --git a/tools/buildbot-vm.sh b/tools/buildbot-vm.sh
new file mode 100755
index 0000000000..9574c9f0a5
--- /dev/null
+++ b/tools/buildbot-vm.sh
@@ -0,0 +1,128 @@
+#! /bin/bash
+#
+# Copyright (C) 2023 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.
+
+set -e
+
+ART_TEST_ON_VM=true . "$(dirname $0)/buildbot-utils.sh"
+
+known_actions="create|boot|setup-ssh|connect|quit"
+
+if [[ -z $ANDROID_BUILD_TOP ]]; then
+ msgfatal "ANDROID_BUILD_TOP is not set"
+elif [[ ( $# -ne 1 ) || ! ( "$1" =~ ^($known_actions)$ ) ]]; then
+ msgfatal "usage: $0 <$known_actions>"
+fi
+
+action="$1"
+
+get_stable_binary() {
+ mkdir tmp && cd tmp
+ wget "http://security.ubuntu.com/ubuntu/pool/main/$1"
+ 7z x "$(basename $1)" && zstd -d data.tar.zst && tar -xf data.tar
+ mv "$2" ..
+ cd .. && rm -rf tmp
+}
+
+if [[ $action = create ]]; then
+(
+ rm -rf "$ART_TEST_VM_DIR"
+ mkdir -p "$ART_TEST_VM_DIR"
+ cd "$ART_TEST_VM_DIR"
+
+ # sudo apt install qemu-system-<arch> qemu-efi cloud-image-utils
+
+ # Get the cloud image for Ubunty 22.04 (Jammy)
+ wget "http://cloud-images.ubuntu.com/releases/22.04/release/$ART_TEST_VM_IMG"
+
+ if [[ "$TARGET_ARCH" = "riscv64" ]]; then
+ # Get U-Boot for Ubuntu 22.04 (Jammy)
+ get_stable_binary \
+ u/u-boot/u-boot-qemu_2022.01+dfsg-2ubuntu2.3_all.deb \
+ usr/lib/u-boot/qemu-riscv64_smode/uboot.elf
+
+ # Get OpenSBI for Ubuntu 22.04 (Jammy)
+ get_stable_binary \
+ o/opensbi/opensbi_1.1-0ubuntu0.22.04.1_all.deb \
+ usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf
+
+ elif [[ "$TARGET_ARCH" = "arm64" ]]; then
+ # Get EFI (ARM64) for Ubuntu 22.04 (Jammy)
+ get_stable_binary \
+ e/edk2/qemu-efi-aarch64_2022.02-3ubuntu0.22.04.1_all.deb \
+ usr/share/qemu-efi-aarch64/QEMU_EFI.fd
+
+ dd if=/dev/zero of=flash0.img bs=1M count=64
+ dd if=QEMU_EFI.fd of=flash0.img conv=notrunc
+ dd if=/dev/zero of=flash1.img bs=1M count=64
+ fi
+
+ qemu-img resize "$ART_TEST_VM_IMG" +128G
+
+ # https://help.ubuntu.com/community/CloudInit
+ cat >user-data <<EOF
+#cloud-config
+ssh_pwauth: true
+chpasswd:
+ expire: false
+ list:
+ - $ART_TEST_SSH_USER:ubuntu
+EOF
+ cloud-localds user-data.img user-data
+)
+elif [[ $action = boot ]]; then
+(
+ cd "$ART_TEST_VM_DIR"
+ if [[ "$TARGET_ARCH" = "riscv64" ]]; then
+ qemu-system-riscv64 \
+ -m 16G \
+ -smp 8 \
+ -M virt \
+ -nographic \
+ -bios fw_jump.elf \
+ -kernel uboot.elf \
+ -drive file="$ART_TEST_VM_IMG",if=virtio \
+ -drive file=user-data.img,format=raw,if=virtio \
+ -device virtio-net-device,netdev=usernet \
+ -netdev user,id=usernet,hostfwd=tcp::$ART_TEST_SSH_PORT-:22
+ elif [[ "$TARGET_ARCH" = "arm64" ]]; then
+ qemu-system-aarch64 \
+ -m 16G \
+ -smp 8 \
+ -cpu cortex-a57 \
+ -M virt \
+ -nographic \
+ -drive if=none,file="$ART_TEST_VM_IMG",id=hd0 \
+ -pflash flash0.img \
+ -pflash flash1.img \
+ -drive file=user-data.img,format=raw,id=cloud \
+ -device virtio-blk-device,drive=hd0 \
+ -device virtio-net-device,netdev=usernet \
+ -netdev user,id=usernet,hostfwd=tcp::$ART_TEST_SSH_PORT-:22
+ fi
+
+)
+elif [[ $action = setup-ssh ]]; then
+ # Clean up mentions of this VM from known_hosts
+ sed -i -E "/\[$ART_TEST_SSH_HOST.*\]:$ART_TEST_SSH_PORT .*/d" $HOME/.ssh/known_hosts
+ ssh-copy-id -p "$ART_TEST_SSH_PORT" -o IdentityAgent=none "$ART_TEST_SSH_USER@$ART_TEST_SSH_HOST"
+
+elif [[ $action = connect ]]; then
+ $ART_SSH_CMD
+
+elif [[ $action = quit ]]; then
+ $ART_SSH_CMD "sudo poweroff"
+
+fi
diff --git a/tools/check_presubmit_json_expectations.sh b/tools/check_presubmit_json_expectations.sh
new file mode 100755
index 0000000000..ecb1e3e344
--- /dev/null
+++ b/tools/check_presubmit_json_expectations.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# Copyright (C) 2022 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.
+
+set -e
+
+REPO_ROOT="$1"
+
+FILES_TO_CHECK=()
+for i in "${@:2}"; do
+ if [[ $i == *_failures.txt ]]; then
+ FILES_TO_CHECK+=($i)
+ fi
+done
+
+# if no libcore_*_failures.txt files were changed
+if [ ${#FILES_TO_CHECK[@]} -eq 0 ]; then
+ exit 0
+fi
+
+TMP_DIR=`mktemp -d`
+# check if tmp dir was created
+if [[ ! "$TMP_DIR" || ! -d "$TMP_DIR" ]]; then
+ echo "Could not create temp dir"
+ exit 1
+fi
+
+function cleanup {
+ rm -rf "$TMP_DIR"
+}
+
+# register the cleanup function to be called on the EXIT signal
+trap cleanup EXIT
+
+GSON_JAR="${REPO_ROOT}/external/caliper/lib/gson-2.2.2.jar"
+
+javac --class-path "$GSON_JAR" "${REPO_ROOT}/art/tools/PresubmitJsonLinter.java" -d "$TMP_DIR"
+java --class-path "$TMP_DIR:$GSON_JAR" PresubmitJsonLinter "${FILES_TO_CHECK[@]}"
diff --git a/tools/checker/Android.bp b/tools/checker/Android.bp
new file mode 100644
index 0000000000..db2c597bf4
--- /dev/null
+++ b/tools/checker/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2022 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "art_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["art_license"],
+}
+
+python_binary_host {
+ name: "art-run-test-checker",
+ srcs: [
+ "**/*.py",
+ ],
+ main: "checker.py",
+ version: {
+ py3: {
+ embedded_launcher: true,
+ },
+ },
+ test_suites: [
+ "general-tests",
+ "mts-art",
+ ],
+}
diff --git a/tools/compile-jar.py b/tools/compile-jar.py
index 56a07d5a61..d3484460ce 100755
--- a/tools/compile-jar.py
+++ b/tools/compile-jar.py
@@ -105,19 +105,17 @@ def get_bcp_runtime_args(additions, image, arch):
"art/tools/host_bcp.sh",
os.path.expandvars(
"${{OUT}}/system/framework/oat/{}/services.odex".format(arch)),
- "--use-first-dir"
]
print("Running: {}".format(run_print(args)))
print("=START=======================================")
res = subprocess.run(args, capture_output=True, text=True)
print("=END=========================================")
if res.returncode != 0:
- print("Falling back to com.android.art BCP")
+ print("Falling back to ART boot image: {}".format(res))
args = [
"art/tools/host_bcp.sh",
os.path.expandvars(
- "${{OUT}}/apex/com.android.art.debug/javalib/{}/boot.oat".format(arch)),
- "--use-first-dir"
+ "${{OUT}}/apex/art_boot_images/javalib/{}/boot.oat".format(arch)),
]
print("Running: {}".format(run_print(args)))
print("=START=======================================")
diff --git a/tools/cpp-define-generator/globals.def b/tools/cpp-define-generator/globals.def
index 2572ea6f9b..459e5a8164 100644
--- a/tools/cpp-define-generator/globals.def
+++ b/tools/cpp-define-generator/globals.def
@@ -28,6 +28,7 @@
#include "mirror/object_reference.h"
#include "runtime_globals.h"
#include "stack.h"
+#include "entrypoints/quick/callee_save_frame.h"
#endif
ASM_DEFINE(ACCESS_FLAGS_METHOD_IS_NATIVE,
@@ -82,3 +83,11 @@ ASM_DEFINE(STD_MEMORY_ORDER_RELAXED,
std::memory_order_relaxed)
ASM_DEFINE(STACK_OVERFLOW_RESERVED_BYTES,
GetStackOverflowReservedBytes(art::kRuntimeISA))
+ASM_DEFINE(CALLEE_SAVE_EVERYTHING_NUM_CORE_SPILLS,
+ art::POPCOUNT(art::RuntimeCalleeSaveFrame::GetCoreSpills(
+ art::CalleeSaveType::kSaveEverything)))
+ASM_DEFINE(TAGGED_JNI_SP_MASK, art::ManagedStack::kTaggedJniSpMask)
+ASM_DEFINE(TAGGED_JNI_SP_MASK_TOGGLED32,
+ ~static_cast<uint32_t>(art::ManagedStack::kTaggedJniSpMask))
+ASM_DEFINE(TAGGED_JNI_SP_MASK_TOGGLED64,
+ ~static_cast<uint64_t>(art::ManagedStack::kTaggedJniSpMask))
diff --git a/tools/cpp-define-generator/lockword.def b/tools/cpp-define-generator/lockword.def
index a170c15f8b..5494d59d1d 100644
--- a/tools/cpp-define-generator/lockword.def
+++ b/tools/cpp-define-generator/lockword.def
@@ -30,10 +30,8 @@ ASM_DEFINE(LOCK_WORD_MARK_BIT_MASK_SHIFTED,
art::LockWord::kMarkBitStateMaskShifted)
ASM_DEFINE(LOCK_WORD_MARK_BIT_SHIFT,
art::LockWord::kMarkBitStateShift)
-ASM_DEFINE(LOCK_WORD_READ_BARRIER_STATE_MASK,
+ASM_DEFINE(LOCK_WORD_READ_BARRIER_STATE_MASK_SHIFTED,
art::LockWord::kReadBarrierStateMaskShifted)
-ASM_DEFINE(LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED,
- art::LockWord::kReadBarrierStateMaskShiftedToggled)
ASM_DEFINE(LOCK_WORD_READ_BARRIER_STATE_SHIFT,
art::LockWord::kReadBarrierStateShift)
ASM_DEFINE(LOCK_WORD_STATE_FORWARDING_ADDRESS,
diff --git a/tools/cpp-define-generator/mirror_class.def b/tools/cpp-define-generator/mirror_class.def
index 8cfd54e8d6..062a7aa4b7 100644
--- a/tools/cpp-define-generator/mirror_class.def
+++ b/tools/cpp-define-generator/mirror_class.def
@@ -16,6 +16,7 @@
#if ASM_DEFINE_INCLUDE_DEPENDENCIES
#include "mirror/class.h"
+#include "subtype_check.h"
#endif
ASM_DEFINE(MIRROR_CLASS_ACCESS_FLAGS_OFFSET,
@@ -49,3 +50,17 @@ ASM_DEFINE(MIRROR_CLASS_SUPER_CLASS_OFFSET,
ASM_DEFINE(MIRROR_CLASS_IS_INTERFACE_FLAG, art::kAccInterface)
ASM_DEFINE(MIRROR_CLASS_IS_INTERFACE_FLAG_BIT,
art::WhichPowerOf2(art::kAccInterface))
+ASM_DEFINE(MIRROR_CLASS_IS_VISIBLY_INITIALIZED_OFFSET,
+ art::mirror::Class::StatusOffset().SizeValue() +
+ (art::SubtypeCheckBits::BitStructSizeOf() / art::kBitsPerByte))
+ASM_DEFINE(MIRROR_CLASS_IS_VISIBLY_INITIALIZED_VALUE,
+ art::enum_cast<uint32_t>(art::ClassStatus::kVisiblyInitialized) <<
+ (art::SubtypeCheckBits::BitStructSizeOf() % art::kBitsPerByte))
+ASM_DEFINE(MIRROR_CLASS_IS_INITIALIZING_VALUE,
+ art::enum_cast<uint32_t>(art::ClassStatus::kInitializing) <<
+ (art::SubtypeCheckBits::BitStructSizeOf() % art::kBitsPerByte))
+ASM_DEFINE(MIRROR_CLASS_IS_INITIALIZED_VALUE,
+ art::enum_cast<uint32_t>(art::ClassStatus::kInitialized) <<
+ (art::SubtypeCheckBits::BitStructSizeOf() % art::kBitsPerByte))
+ASM_DEFINE(MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET,
+ art::mirror::Class::ClinitThreadIdOffset().Int32Value())
diff --git a/tools/cpp-define-generator/runtime.def b/tools/cpp-define-generator/runtime.def
index 2a2e303ba2..fd6567d87e 100644
--- a/tools/cpp-define-generator/runtime.def
+++ b/tools/cpp-define-generator/runtime.def
@@ -30,3 +30,7 @@ ASM_DEFINE(RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET,
art::Runtime::GetCalleeSaveMethodOffset(art::CalleeSaveType::kSaveRefsAndArgs))
ASM_DEFINE(RUNTIME_SAVE_REFS_ONLY_METHOD_OFFSET,
art::Runtime::GetCalleeSaveMethodOffset(art::CalleeSaveType::kSaveRefsOnly))
+ASM_DEFINE(RUNTIME_INSTRUMENTATION_OFFSET, art::Runtime::GetInstrumentationOffset().Int32Value())
+ASM_DEFINE(RUN_EXIT_HOOKS_OFFSET_FROM_RUNTIME_INSTANCE,
+ art::Runtime::GetInstrumentationOffset().Int32Value() +
+ art::instrumentation::Instrumentation::RunExitHooksOffset().Int32Value())
diff --git a/tools/cpp-define-generator/thread.def b/tools/cpp-define-generator/thread.def
index bae92009b2..97033fcaf2 100644
--- a/tools/cpp-define-generator/thread.def
+++ b/tools/cpp-define-generator/thread.def
@@ -37,6 +37,8 @@ ASM_DEFINE(THREAD_INTERPRETER_CACHE_SIZE_SHIFT,
(art::WhichPowerOf2(sizeof(art::InterpreterCache::Entry)) - 2))
ASM_DEFINE(THREAD_IS_GC_MARKING_OFFSET,
art::Thread::IsGcMarkingOffset<art::kRuntimePointerSize>().Int32Value())
+ASM_DEFINE(THREAD_DEOPT_CHECK_REQUIRED_OFFSET,
+ art::Thread::DeoptCheckRequiredOffset<art::kRuntimePointerSize>().Int32Value())
ASM_DEFINE(THREAD_LOCAL_ALLOC_STACK_END_OFFSET,
art::Thread::ThreadLocalAllocStackEndOffset<art::kRuntimePointerSize>().Int32Value())
ASM_DEFINE(THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET,
@@ -69,3 +71,5 @@ ASM_DEFINE(THREAD_READ_BARRIER_MARK_REG00_OFFSET,
art::Thread::ReadBarrierMarkEntryPointsOffset<art::kRuntimePointerSize>(0))
ASM_DEFINE(THREAD_SHARED_METHOD_HOTNESS_OFFSET,
art::Thread::SharedMethodHotnessOffset<art::kRuntimePointerSize>().Int32Value())
+ASM_DEFINE(THREAD_TID_OFFSET,
+ art::Thread::TidOffset<art::kRuntimePointerSize>().Int32Value())
diff --git a/tools/dexanalyze/Android.bp b/tools/dexanalyze/Android.bp
index 2a625d6e6b..5b875594cf 100644
--- a/tools/dexanalyze/Android.bp
+++ b/tools/dexanalyze/Android.bp
@@ -49,6 +49,7 @@ art_cc_binary {
apex_available: [
"com.android.art",
"com.android.art.debug",
+ "test_broken_com.android.art",
],
}
diff --git a/tools/dexanalyze/dexanalyze.cc b/tools/dexanalyze/dexanalyze.cc
index f0ce4c4607..79602aacbc 100644
--- a/tools/dexanalyze/dexanalyze.cc
+++ b/tools/dexanalyze/dexanalyze.cc
@@ -14,20 +14,21 @@
* limitations under the License.
*/
+#include <android-base/file.h>
+
#include <cstdint>
#include <iostream>
#include <set>
#include <sstream>
-#include <android-base/file.h>
-
-#include "dexanalyze_bytecode.h"
-#include "dexanalyze_experiments.h"
-#include "dexanalyze_strings.h"
+#include "base/mem_map.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "dex/dex_instruction-inl.h"
+#include "dexanalyze_bytecode.h"
+#include "dexanalyze_experiments.h"
+#include "dexanalyze_strings.h"
namespace art {
namespace dexanalyze {
@@ -202,20 +203,18 @@ class DexAnalyze {
for (const std::string& filename : options.filenames_) {
std::string content;
// TODO: once added, use an API to android::base to read a std::vector<uint8_t>.
- if (!android::base::ReadFileToString(filename.c_str(), &content)) {
+ if (!android::base::ReadFileToString(filename, &content)) {
LOG(ERROR) << "ReadFileToString failed for " + filename << std::endl;
return kExitCodeFailedToOpenFile;
}
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const DexFileLoader dex_file_loader;
- if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
- content.size(),
- filename.c_str(),
- options.run_dex_file_verifier_,
- options.verify_checksum_,
- &error_code,
- &error_msg,
- &dex_files)) {
+ DexFileLoader dex_file_loader(
+ reinterpret_cast<const uint8_t*>(content.data()), content.size(), filename);
+ if (!dex_file_loader.Open(options.run_dex_file_verifier_,
+ options.verify_checksum_,
+ &error_code,
+ &error_msg,
+ &dex_files)) {
LOG(ERROR) << "OpenAll failed for " + filename << " with " << error_msg << std::endl;
return kExitCodeFailedToOpenDex;
}
@@ -240,6 +239,7 @@ class DexAnalyze {
} // namespace art
int main(int argc, char** argv) {
+ art::MemMap::Init();
return art::dexanalyze::DexAnalyze::Run(argc, argv);
}
diff --git a/tools/dexanalyze/dexanalyze_experiments.cc b/tools/dexanalyze/dexanalyze_experiments.cc
index b124f433b3..384ab374cd 100644
--- a/tools/dexanalyze/dexanalyze_experiments.cc
+++ b/tools/dexanalyze/dexanalyze_experiments.cc
@@ -459,6 +459,7 @@ void CountDexIndices::ProcessDexFile(const DexFile& dex_file) {
}
// Count uses of top 16n.
std::vector<size_t> uses;
+ uses.reserve(types_accessed.size());
for (auto&& p : types_accessed) {
uses.push_back(p.second);
}
diff --git a/tools/dexanalyze/dexanalyze_test.cc b/tools/dexanalyze/dexanalyze_test.cc
index 9e6ed6df67..474615dec2 100644
--- a/tools/dexanalyze/dexanalyze_test.cc
+++ b/tools/dexanalyze/dexanalyze_test.cc
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include "common_runtime_test.h"
+#include "base/common_art_test.h"
#include "exec_utils.h"
namespace art {
-class DexAnalyzeTest : public CommonRuntimeTest {
+class DexAnalyzeTest : public CommonArtTest {
public:
std::string GetDexAnalyzePath() {
return GetArtBinDir() + "/dexanalyze";
diff --git a/tools/dexfuzz/.clang-format b/tools/dexfuzz/.clang-format
new file mode 120000
index 0000000000..88ab38e627
--- /dev/null
+++ b/tools/dexfuzz/.clang-format
@@ -0,0 +1 @@
+../../.clang-format-java-2 \ No newline at end of file
diff --git a/tools/dexfuzz/Android.bp b/tools/dexfuzz/Android.bp
index 02bda0e25a..083ecd74a9 100644
--- a/tools/dexfuzz/Android.bp
+++ b/tools/dexfuzz/Android.bp
@@ -33,6 +33,6 @@ java_library_host {
// --- dexfuzz script ----------------
sh_binary_host {
name: "dexfuzz-script",
- src: "dexfuzz",
- filename_from_src: true,
+ src: "dexfuzz.sh",
+ filename: "dexfuzz",
}
diff --git a/tools/dexfuzz/dexfuzz b/tools/dexfuzz/dexfuzz.sh
index cd47008d09..cd47008d09 100755
--- a/tools/dexfuzz/dexfuzz
+++ b/tools/dexfuzz/dexfuzz.sh
diff --git a/tools/dist_linux_bionic.sh b/tools/dist_linux_bionic.sh
index 4c7ba1ca3f..f71031065e 100755
--- a/tools/dist_linux_bionic.sh
+++ b/tools/dist_linux_bionic.sh
@@ -19,12 +19,6 @@ set -e
# Builds the given targets using linux-bionic and moves the output files to the
# DIST_DIR. Takes normal make arguments.
-if [[ -z $ANDROID_BUILD_TOP ]]; then
- pushd .
-else
- pushd $ANDROID_BUILD_TOP
-fi
-
if [[ -z $DIST_DIR ]]; then
echo "DIST_DIR must be set!"
exit 1
@@ -35,10 +29,12 @@ if [ ! -d art ]; then
exit 1
fi
-source build/envsetup.sh >&/dev/null # for get_build_var
-out_dir=$(get_build_var OUT_DIR)
+vars="$(build/soong/soong_ui.bash --dumpvars-mode --vars="OUT_DIR")"
+# Assign to a variable and eval that, since bash ignores any error status from
+# the command substitution if it's directly on the eval line.
+eval $vars
-./art/tools/build_linux_bionic.sh $@
+./art/tools/build_linux_bionic.sh "$@"
mkdir -p $DIST_DIR
-cp -R ${out_dir}/soong/host/* $DIST_DIR/
+cp -R ${OUT_DIR}/soong/host/* $DIST_DIR/
diff --git a/tools/dmtracedump/createtesttrace.cc b/tools/dmtracedump/createtesttrace.cc
index 444cce4082..7bb5a7f9f1 100644
--- a/tools/dmtracedump/createtesttrace.cc
+++ b/tools/dmtracedump/createtesttrace.cc
@@ -22,6 +22,7 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <memory>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -114,7 +115,7 @@ char* strndup(const char* src, size_t len) {
* 2 and increments by 2 for each line.
*/
void parseInputFile(const char* inputFileName) {
- FILE* inputFp = fopen(inputFileName, "r");
+ FILE* inputFp = fopen(inputFileName, "re");
if (inputFp == nullptr) {
perror(inputFileName);
exit(1);
@@ -143,7 +144,7 @@ void parseInputFile(const char* inputFileName) {
/* Add space for a sentinel record at the end */
numRecords += 1;
records = new dataRecord[numRecords];
- stack* callStack = new stack[numThreads];
+ std::unique_ptr<stack[]> callStack(new stack[numThreads]);
for (int32_t ii = 0; ii < numThreads; ++ii) {
callStack[ii].frames = nullptr;
callStack[ii].indentLevel = 0;
@@ -395,7 +396,7 @@ void writeDataRecords(FILE* dataFp) {
}
void writeTrace(const char* traceFileName) {
- FILE* fp = fopen(traceFileName, "w");
+ FILE* fp = fopen(traceFileName, "we");
if (fp == nullptr) {
perror(traceFileName);
exit(1);
diff --git a/tools/dmtracedump/tracedump.cc b/tools/dmtracedump/tracedump.cc
index 3cb737474f..3385f4ac84 100644
--- a/tools/dmtracedump/tracedump.cc
+++ b/tools/dmtracedump/tracedump.cc
@@ -1046,7 +1046,7 @@ void dumpTrace() {
for (int32_t i = 0; i < MAX_THREADS; i++)
traceData.depth[i] = 2; // adjust for return from start function
- FILE* dataFp = fopen(gOptions.traceFileName, "rb");
+ FILE* dataFp = fopen(gOptions.traceFileName, "rbe");
if (dataFp == nullptr) return;
DataKeys* pKeys = parseKeys(dataFp, 1);
@@ -1465,7 +1465,7 @@ void createInclusiveProfileGraphNew(DataKeys* dataKeys) {
snprintf(path, FILENAME_MAX, "dot-%d-%d.dot", (int32_t)time(nullptr), rand());
}
- FILE* file = fopen(path, "w+");
+ FILE* file = fopen(path, "we+");
fprintf(file, "digraph g {\nnode [shape = record,height=.1];\n");
@@ -1490,10 +1490,8 @@ void printInclusiveProfile(MethodEntry** pMethods, int32_t numMethods, uint64_t
char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE];
char signatureBuf[HTML_BUFSIZE];
char anchor_buf[80];
- const char* anchor_close = "";
anchor_buf[0] = 0;
if (gOptions.outputHtml) {
- anchor_close = "</a>";
printf("<a name=\"inclusive\"></a>\n");
printf("<hr>\n");
outputNavigationBar();
@@ -2035,7 +2033,7 @@ void printMethodProfiles(TraceData* traceData, uint64_t sumThreadTime) {
DataKeys* parseDataKeys(TraceData* traceData, const char* traceFileName, uint64_t* threadTime) {
MethodEntry* caller;
- FILE* dataFp = fopen(traceFileName, "rb");
+ FILE* dataFp = fopen(traceFileName, "rbe");
if (dataFp == nullptr) return nullptr;
DataKeys* dataKeys = parseKeys(dataFp, 0);
diff --git a/tools/external_oj_libjdwp_art_no_read_barrier_failures.txt b/tools/external_oj_libjdwp_art_no_read_barrier_failures.txt
new file mode 100644
index 0000000000..920b611e43
--- /dev/null
+++ b/tools/external_oj_libjdwp_art_no_read_barrier_failures.txt
@@ -0,0 +1,9 @@
+/*
+ * This file contains expectations for ART's buildbot. The purpose of this file is
+ * to temporarily list failing tests and not break the bots.
+ *
+ * This file contains the expectations for the 'libjdwp-aot' and 'libjdwp-jit'
+ * test groups on the chromium buildbot running without read-barrier.
+ */
+[
+]
diff --git a/tools/generate_cmake_lists.py b/tools/generate_cmake_lists.py
index b19c2920f0..3fda0034b2 100755
--- a/tools/generate_cmake_lists.py
+++ b/tools/generate_cmake_lists.py
@@ -32,6 +32,7 @@ Steps to setup CLion.
(Also, exclude projects that you don't bother about. This will make
the indexing faster).
"""
+from __future__ import print_function
import sys
import os
@@ -47,7 +48,7 @@ def get_android_build_top():
path_to_top = os.path.realpath(path_to_top)
if not os.path.exists(os.path.join(path_to_top, 'build/envsetup.sh')):
- print path_to_top
+ print(path_to_top)
raise AssertionError("geneate_cmake_lists.py must be located inside an android source tree")
return path_to_top
diff --git a/tools/generate_operator_out.py b/tools/generate_operator_out.py
index f1491d827f..f3de61c134 100755
--- a/tools/generate_operator_out.py
+++ b/tools/generate_operator_out.py
@@ -65,7 +65,7 @@ def ProcessFile(filename):
continue
# Is this the start or end of a namespace?
- m = re.search(r'^namespace (\S+) \{', raw_line)
+ m = re.search(r'^namespace (\S+) (HIDDEN |EXPORT )?\{', raw_line)
if m:
namespaces.append(m.group(1))
continue
diff --git a/tools/golem/build-target.sh b/tools/golem/build-target.sh
index d8ec58b364..1ebd7c9544 100755
--- a/tools/golem/build-target.sh
+++ b/tools/golem/build-target.sh
@@ -269,6 +269,8 @@ if [[ $mode == "golem" ]]; then
execute lunch "$lunch_target"
# Golem uses master-art repository which is missing a lot of other libraries.
setenv SOONG_ALLOW_MISSING_DEPENDENCIES true
+ # master-art cannot build with Bazel.
+ setenv BUILD_BROKEN_DISABLE_BAZEL true
# Let the build system know we're not aiming to do a full platform build.
if [ ! -d frameworks/base ]; then
setenv TARGET_BUILD_UNBUNDLED true
diff --git a/tools/hiddenapi/hiddenapi.cc b/tools/hiddenapi/hiddenapi.cc
index aee3f9acd3..5c750af4aa 100644
--- a/tools/hiddenapi/hiddenapi.cc
+++ b/tools/hiddenapi/hiddenapi.cc
@@ -16,14 +16,15 @@
#include <fstream>
#include <iostream>
+#include <iterator>
#include <map>
#include <set>
#include <string>
#include <string_view>
+#include <vector>
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
-
#include "base/bit_utils.h"
#include "base/hiddenapi_flags.h"
#include "base/mem_map.h"
@@ -34,6 +35,7 @@
#include "dex/art_dex_file_loader.h"
#include "dex/class_accessor-inl.h"
#include "dex/dex_file-inl.h"
+#include "dex/dex_file_structs.h"
namespace art {
namespace hiddenapi {
@@ -244,8 +246,15 @@ class DexMember {
class ClassPath final {
public:
- ClassPath(const std::vector<std::string>& dex_paths, bool open_writable, bool ignore_empty) {
- OpenDexFiles(dex_paths, open_writable, ignore_empty);
+ ClassPath(const std::vector<std::string>& dex_paths, bool ignore_empty) {
+ OpenDexFiles(dex_paths, ignore_empty);
+ }
+
+ template <typename Fn>
+ void ForEachDexClass(const DexFile* dex_file, Fn fn) {
+ for (ClassAccessor accessor : dex_file->GetClasses()) {
+ fn(DexClass(accessor));
+ }
}
template<typename Fn>
@@ -283,47 +292,18 @@ class ClassPath final {
}
private:
- void OpenDexFiles(const std::vector<std::string>& dex_paths,
- bool open_writable,
- bool ignore_empty) {
- ArtDexFileLoader dex_loader;
+ void OpenDexFiles(const std::vector<std::string>& dex_paths, bool ignore_empty) {
std::string error_msg;
- if (open_writable) {
- for (const std::string& filename : dex_paths) {
- File fd(filename.c_str(), O_RDWR, /* check_usage= */ false);
- CHECK_NE(fd.Fd(), -1) << "Unable to open file '" << filename << "': " << strerror(errno);
-
- // Memory-map the dex file with MAP_SHARED flag so that changes in memory
- // propagate to the underlying file. We run dex file verification as if
- // the dex file was not in boot claass path to check basic assumptions,
- // such as that at most one of public/private/protected flag is set.
- // We do those checks here and skip them when loading the processed file
- // into boot class path.
- std::unique_ptr<const DexFile> dex_file(dex_loader.OpenDex(fd.Release(),
- /* location= */ filename,
- /* verify= */ true,
- /* verify_checksum= */ true,
- /* mmap_shared= */ true,
- &error_msg));
- CHECK(dex_file.get() != nullptr) << "Open failed for '" << filename << "' " << error_msg;
- CHECK(dex_file->IsStandardDexFile()) << "Expected a standard dex file '" << filename << "'";
- CHECK(dex_file->EnableWrite())
- << "Failed to enable write permission for '" << filename << "'";
- dex_files_.push_back(std::move(dex_file));
- }
- } else {
- for (const std::string& filename : dex_paths) {
- bool success = dex_loader.Open(filename.c_str(),
- /* location= */ filename,
- /* verify= */ true,
- /* verify_checksum= */ true,
- &error_msg,
- &dex_files_);
- // If requested ignore a jar with no classes.dex files.
- if (!success && ignore_empty && error_msg != "Entry not found") {
- CHECK(success) << "Open failed for '" << filename << "' " << error_msg;
- }
+ for (const std::string& filename : dex_paths) {
+ DexFileLoader dex_file_loader(filename);
+ bool success = dex_file_loader.Open(/* verify= */ true,
+ /* verify_checksum= */ true,
+ &error_msg,
+ &dex_files_);
+ // If requested ignore a jar with no classes.dex files.
+ if (!success && ignore_empty && error_msg != "Entry not found") {
+ CHECK(success) << "Open failed for '" << filename << "' " << error_msg;
}
}
}
@@ -669,215 +649,125 @@ class HiddenapiClassDataBuilder final {
// Edits a dex file, inserting a new HiddenapiClassData section.
class DexFileEditor final {
public:
- DexFileEditor(const DexFile& old_dex, const std::vector<uint8_t>& hiddenapi_class_data)
- : old_dex_(old_dex),
- hiddenapi_class_data_(hiddenapi_class_data),
- loaded_dex_header_(nullptr),
- loaded_dex_maplist_(nullptr) {}
-
- // Copies dex file into a backing data vector, appends the given HiddenapiClassData
- // and updates the MapList.
- void Encode() {
+ // Add dex file to copy to output (possibly several files for multi-dex).
+ void Add(const DexFile* dex, const std::vector<uint8_t>&& hiddenapi_data) {
// We do not support non-standard dex encodings, e.g. compact dex.
- CHECK(old_dex_.IsStandardDexFile());
-
- // If there are no data to append, copy the old dex file and return.
- if (hiddenapi_class_data_.empty()) {
- AllocateMemory(old_dex_.Size());
- Append(old_dex_.Begin(), old_dex_.Size(), /* update_header= */ false);
- return;
- }
-
- // Find the old MapList, find its size.
- const dex::MapList* old_map = old_dex_.GetMapList();
- CHECK_LT(old_map->size_, std::numeric_limits<uint32_t>::max());
-
- // Compute the size of the new dex file. We append the HiddenapiClassData,
- // one MapItem and possibly some padding to align the new MapList.
- CHECK(IsAligned<kMapListAlignment>(old_dex_.Size()))
- << "End of input dex file is not 4-byte aligned, possibly because its MapList is not "
- << "at the end of the file.";
- size_t size_delta =
- RoundUp(hiddenapi_class_data_.size(), kMapListAlignment) + sizeof(dex::MapItem);
- size_t new_size = old_dex_.Size() + size_delta;
- AllocateMemory(new_size);
-
- // Copy the old dex file into the backing data vector. Load the copied
- // dex file to obtain pointers to its header and MapList.
- Append(old_dex_.Begin(), old_dex_.Size(), /* update_header= */ false);
- ReloadDex(/* verify= */ false);
-
- // Truncate the new dex file before the old MapList. This assumes that
- // the MapList is the last entry in the dex file. This is currently true
- // for our tooling.
- // TODO: Implement the general case by zero-ing the old MapList (turning
- // it into padding.
- RemoveOldMapList();
-
- // Append HiddenapiClassData.
- size_t payload_offset = AppendHiddenapiClassData();
-
- // Wrute new MapList with an entry for HiddenapiClassData.
- CreateMapListWithNewItem(payload_offset);
-
- // Check that the pre-computed size matches the actual size.
- CHECK_EQ(offset_, new_size);
-
- // Reload to all data structures.
- ReloadDex(/* verify= */ false);
-
- // Update the dex checksum.
- UpdateChecksum();
-
- // Run DexFileVerifier on the new dex file as a CHECK.
- ReloadDex(/* verify= */ true);
+ CHECK(dex->IsStandardDexFile());
+ inputs_.emplace_back(dex, std::move(hiddenapi_data));
}
// Writes the edited dex file into a file.
void WriteTo(const std::string& path) {
- CHECK(!data_.empty());
+ std::vector<uint8_t> output;
+
+ // Copy the old dex files into the backing data vector.
+ size_t truncated_size = 0;
+ std::vector<size_t> header_offset;
+ for (size_t i = 0; i < inputs_.size(); i++) {
+ const DexFile* dex = inputs_[i].first;
+ header_offset.push_back(output.size());
+ std::copy(
+ dex->Begin(), dex->Begin() + dex->GetHeader().file_size_, std::back_inserter(output));
+
+ // Clear the old map list (make it into padding).
+ const dex::MapList* map = dex->GetMapList();
+ size_t map_off = dex->GetHeader().map_off_;
+ size_t map_size = sizeof(map->size_) + map->size_ * sizeof(map->list_[0]);
+ CHECK_LE(map_off, output.size()) << "Map list past the end of file";
+ CHECK_EQ(map_size, output.size() - map_off) << "Map list expected at the end of file";
+ std::fill_n(output.data() + map_off, map_size, 0);
+ truncated_size = output.size() - map_size;
+ }
+ output.resize(truncated_size); // Truncate last map list.
+
+ // Append the hidden api data into the backing data vector.
+ std::vector<size_t> hiddenapi_offset;
+ for (size_t i = 0; i < inputs_.size(); i++) {
+ const std::vector<uint8_t>& hiddenapi_data = inputs_[i].second;
+ output.resize(RoundUp(output.size(), kHiddenapiClassDataAlignment)); // Align.
+ hiddenapi_offset.push_back(output.size());
+ std::copy(hiddenapi_data.begin(), hiddenapi_data.end(), std::back_inserter(output));
+ }
+
+ // Update the dex headers and map lists.
+ for (size_t i = 0; i < inputs_.size(); i++) {
+ output.resize(RoundUp(output.size(), kMapListAlignment)); // Align.
+
+ const DexFile* dex = inputs_[i].first;
+ const dex::MapList* map = dex->GetMapList();
+ std::vector<dex::MapItem> items(map->list_, map->list_ + map->size_);
+
+ // Check the header entry.
+ CHECK(!items.empty());
+ CHECK_EQ(items[0].type_, DexFile::kDexTypeHeaderItem);
+ CHECK_EQ(items[0].offset_, header_offset[i]);
+
+ // Check and remove the old map list entry (it does not have to be last).
+ auto is_map_list = [](auto it) { return it.type_ == DexFile::kDexTypeMapList; };
+ auto it = std::find_if(items.begin(), items.end(), is_map_list);
+ CHECK(it != items.end());
+ CHECK_EQ(it->offset_, dex->GetHeader().map_off_);
+ items.erase(it);
+
+ // Write new map list.
+ if (!inputs_[i].second.empty()) {
+ uint32_t payload_offset = hiddenapi_offset[i];
+ items.push_back(dex::MapItem{DexFile::kDexTypeHiddenapiClassData, 0, 1u, payload_offset});
+ }
+ uint32_t map_offset = output.size();
+ items.push_back(dex::MapItem{DexFile::kDexTypeMapList, 0, 1u, map_offset});
+ uint32_t item_count = items.size();
+ Append(&output, &item_count, 1);
+ Append(&output, items.data(), items.size());
+
+ // Update header.
+ uint8_t* begin = output.data() + header_offset[i];
+ auto* header = reinterpret_cast<DexFile::Header*>(begin);
+ header->map_off_ = map_offset;
+ if (i + 1 < inputs_.size()) {
+ CHECK_EQ(header->file_size_, header_offset[i + 1] - header_offset[i]);
+ } else {
+ // Extend last dex file until the end of the file.
+ header->data_size_ = output.size() - header->data_off_;
+ header->file_size_ = output.size() - header_offset[i];
+ }
+ header->checksum_ = DexFile::CalculateChecksum(begin, header->file_size_);
+ // TODO: We should also update the SHA1 signature.
+ }
+
+ // Write the output file.
+ CHECK(!output.empty());
std::ofstream ofs(path.c_str(), std::ofstream::out | std::ofstream::binary);
- ofs.write(reinterpret_cast<const char*>(data_.data()), data_.size());
+ ofs.write(reinterpret_cast<const char*>(output.data()), output.size());
ofs.flush();
CHECK(ofs.good());
ofs.close();
+
+ ReloadDex(path.c_str());
}
private:
static constexpr size_t kMapListAlignment = 4u;
static constexpr size_t kHiddenapiClassDataAlignment = 4u;
- void ReloadDex(bool verify) {
+ void ReloadDex(const char* filename) {
std::string error_msg;
- DexFileLoader loader;
- loaded_dex_ = loader.Open(
- data_.data(),
- data_.size(),
- "test_location",
- old_dex_.GetLocationChecksum(),
- /* oat_dex_file= */ nullptr,
- /* verify= */ verify,
- /* verify_checksum= */ verify,
- &error_msg);
- if (loaded_dex_.get() == nullptr) {
- LOG(FATAL) << "Failed to load edited dex file: " << error_msg;
- UNREACHABLE();
- }
-
- // Load the location of header and map list before we start editing the file.
- loaded_dex_header_ = const_cast<DexFile::Header*>(&loaded_dex_->GetHeader());
- loaded_dex_maplist_ = const_cast<dex::MapList*>(loaded_dex_->GetMapList());
- }
-
- DexFile::Header& GetHeader() const {
- CHECK(loaded_dex_header_ != nullptr);
- return *loaded_dex_header_;
- }
-
- dex::MapList& GetMapList() const {
- CHECK(loaded_dex_maplist_ != nullptr);
- return *loaded_dex_maplist_;
- }
-
- void AllocateMemory(size_t total_size) {
- data_.clear();
- data_.resize(total_size);
- CHECK(IsAligned<kMapListAlignment>(data_.data()));
- CHECK(IsAligned<kHiddenapiClassDataAlignment>(data_.data()));
- offset_ = 0;
- }
-
- uint8_t* GetCurrentDataPtr() {
- return data_.data() + offset_;
- }
-
- void UpdateDataSize(off_t delta, bool update_header) {
- offset_ += delta;
- if (update_header) {
- DexFile::Header& header = GetHeader();
- header.file_size_ += delta;
- header.data_size_ += delta;
- }
- }
-
- template<typename T>
- T* Append(const T* src, size_t len, bool update_header = true) {
- CHECK_LE(offset_ + len, data_.size());
- uint8_t* dst = GetCurrentDataPtr();
- memcpy(dst, src, len);
- UpdateDataSize(len, update_header);
- return reinterpret_cast<T*>(dst);
- }
-
- void InsertPadding(size_t alignment) {
- size_t len = RoundUp(offset_, alignment) - offset_;
- std::vector<uint8_t> padding(len, 0);
- Append(padding.data(), padding.size());
- }
-
- void RemoveOldMapList() {
- size_t map_size = GetMapList().Size();
- uint8_t* map_start = reinterpret_cast<uint8_t*>(&GetMapList());
- CHECK_EQ(map_start + map_size, GetCurrentDataPtr()) << "MapList not at the end of dex file";
- UpdateDataSize(-static_cast<off_t>(map_size), /* update_header= */ true);
- CHECK_EQ(map_start, GetCurrentDataPtr());
- loaded_dex_maplist_ = nullptr; // do not use this map list any more
- }
-
- void CreateMapListWithNewItem(size_t payload_offset) {
- InsertPadding(/* alignment= */ kMapListAlignment);
-
- size_t new_map_offset = offset_;
- dex::MapList* map = Append(old_dex_.GetMapList(), old_dex_.GetMapList()->Size());
-
- // Check last map entry is a pointer to itself.
- dex::MapItem& old_item = map->list_[map->size_ - 1];
- CHECK(old_item.type_ == DexFile::kDexTypeMapList);
- CHECK_EQ(old_item.size_, 1u);
- CHECK_EQ(old_item.offset_, GetHeader().map_off_);
-
- // Create a new MapItem entry with new MapList details.
- dex::MapItem new_item;
- new_item.type_ = old_item.type_;
- new_item.unused_ = 0u; // initialize to ensure dex output is deterministic (b/119308882)
- new_item.size_ = old_item.size_;
- new_item.offset_ = new_map_offset;
-
- // Update pointer in the header.
- GetHeader().map_off_ = new_map_offset;
-
- // Append a new MapItem and return its pointer.
- map->size_++;
- Append(&new_item, sizeof(dex::MapItem));
-
- // Change penultimate entry to point to metadata.
- old_item.type_ = DexFile::kDexTypeHiddenapiClassData;
- old_item.size_ = 1u; // there is only one section
- old_item.offset_ = payload_offset;
- }
-
- size_t AppendHiddenapiClassData() {
- size_t payload_offset = offset_;
- CHECK_EQ(kMapListAlignment, kHiddenapiClassDataAlignment);
- CHECK(IsAligned<kHiddenapiClassDataAlignment>(payload_offset))
- << "Should not need to align the section, previous data was already aligned";
- Append(hiddenapi_class_data_.data(), hiddenapi_class_data_.size());
- return payload_offset;
+ ArtDexFileLoader loader(filename);
+ std::vector<std::unique_ptr<const DexFile>> dex_files;
+ bool ok = loader.Open(/*verify*/ true,
+ /*verify_checksum*/ true,
+ &error_msg,
+ &dex_files);
+ CHECK(ok) << "Failed to load edited dex file: " << error_msg;
}
- void UpdateChecksum() {
- GetHeader().checksum_ = loaded_dex_->CalculateChecksum();
+ template <typename T>
+ void Append(std::vector<uint8_t>* output, const T* src, size_t len) {
+ const uint8_t* ptr = reinterpret_cast<const uint8_t*>(src);
+ std::copy(ptr, ptr + len * sizeof(T), std::back_inserter(*output));
}
- const DexFile& old_dex_;
- const std::vector<uint8_t>& hiddenapi_class_data_;
-
- std::vector<uint8_t> data_;
- size_t offset_;
-
- std::unique_ptr<const DexFile> loaded_dex_;
- DexFile::Header* loaded_dex_header_;
- dex::MapList* loaded_dex_maplist_;
+ std::vector<std::pair<const DexFile*, const std::vector<uint8_t>>> inputs_;
};
class HiddenApi final {
@@ -991,48 +881,41 @@ class HiddenApi final {
const std::string& input_path = boot_dex_paths_[i];
const std::string& output_path = output_dex_paths_[i];
- ClassPath boot_classpath({ input_path },
- /* open_writable= */ false,
- /* ignore_empty= */ false);
- std::vector<const DexFile*> input_dex_files = boot_classpath.GetDexFiles();
- CHECK_EQ(input_dex_files.size(), 1u);
- const DexFile& input_dex = *input_dex_files[0];
-
- HiddenapiClassDataBuilder builder(input_dex);
- boot_classpath.ForEachDexClass([&](const DexClass& boot_class) {
- builder.BeginClassDef(boot_class.GetClassDefIndex());
- if (boot_class.GetData() != nullptr) {
- auto fn_shared = [&](const DexMember& boot_member) {
- auto signature = boot_member.GetApiEntry();
- auto it = api_list.find(signature);
- bool api_list_found = (it != api_list.end());
- CHECK(!force_assign_all_ || api_list_found)
- << "Could not find hiddenapi flags for dex entry: " << signature;
- if (api_list_found && it->second.GetIntValue() > max_hiddenapi_level_.GetIntValue()) {
- ApiList without_domain(it->second.GetIntValue());
- LOG(ERROR) << "Hidden api flag " << without_domain
- << " for member " << signature
- << " in " << input_path
- << " exceeds maximum allowable flag "
- << max_hiddenapi_level_;
- max_hiddenapi_level_error = true;
- } else {
- builder.WriteFlags(api_list_found ? it->second : ApiList::Sdk());
- }
- };
- auto fn_field = [&](const ClassAccessor::Field& boot_field) {
- fn_shared(DexMember(boot_class, boot_field));
- };
- auto fn_method = [&](const ClassAccessor::Method& boot_method) {
- fn_shared(DexMember(boot_class, boot_method));
- };
- boot_class.VisitFieldsAndMethods(fn_field, fn_field, fn_method, fn_method);
- }
- builder.EndClassDef(boot_class.GetClassDefIndex());
- });
-
- DexFileEditor dex_editor(input_dex, builder.GetData());
- dex_editor.Encode();
+ ClassPath boot_classpath({input_path}, /* ignore_empty= */ false);
+ DexFileEditor dex_editor;
+ for (const DexFile* input_dex : boot_classpath.GetDexFiles()) {
+ HiddenapiClassDataBuilder builder(*input_dex);
+ boot_classpath.ForEachDexClass(input_dex, [&](const DexClass& boot_class) {
+ builder.BeginClassDef(boot_class.GetClassDefIndex());
+ if (boot_class.GetData() != nullptr) {
+ auto fn_shared = [&](const DexMember& boot_member) {
+ auto signature = boot_member.GetApiEntry();
+ auto it = api_list.find(signature);
+ bool api_list_found = (it != api_list.end());
+ CHECK(!force_assign_all_ || api_list_found)
+ << "Could not find hiddenapi flags for dex entry: " << signature;
+ if (api_list_found && it->second.GetIntValue() > max_hiddenapi_level_.GetIntValue()) {
+ ApiList without_domain(it->second.GetIntValue());
+ LOG(ERROR) << "Hidden api flag " << without_domain << " for member " << signature
+ << " in " << input_path << " exceeds maximum allowable flag "
+ << max_hiddenapi_level_;
+ max_hiddenapi_level_error = true;
+ } else {
+ builder.WriteFlags(api_list_found ? it->second : ApiList::Sdk());
+ }
+ };
+ auto fn_field = [&](const ClassAccessor::Field& boot_field) {
+ fn_shared(DexMember(boot_class, boot_field));
+ };
+ auto fn_method = [&](const ClassAccessor::Method& boot_method) {
+ fn_shared(DexMember(boot_class, boot_method));
+ };
+ boot_class.VisitFieldsAndMethods(fn_field, fn_field, fn_method, fn_method);
+ }
+ builder.EndClassDef(boot_class.GetClassDefIndex());
+ });
+ dex_editor.Add(input_dex, std::move(builder.GetData()));
+ }
dex_editor.WriteTo(output_path);
}
@@ -1057,6 +940,7 @@ class HiddenApi final {
std::map<std::string, ApiList> api_flag_map;
size_t line_number = 1;
+ bool errors = false;
for (std::string line; std::getline(api_file, line); line_number++) {
// Every line contains a comma separated list with the signature as the
// first element and the api flags as the rest
@@ -1074,13 +958,21 @@ class HiddenApi final {
std::vector<std::string>::iterator apiListBegin = values.begin() + 1;
std::vector<std::string>::iterator apiListEnd = values.end();
bool success = ApiList::FromNames(apiListBegin, apiListEnd, &membership);
- CHECK(success) << path << ":" << line_number
- << ": Some flags were not recognized: " << line << kErrorHelp;
- CHECK(membership.IsValid()) << path << ":" << line_number
- << ": Invalid combination of flags: " << line << kErrorHelp;
+ if (!success) {
+ LOG(ERROR) << path << ":" << line_number
+ << ": Some flags were not recognized: " << line << kErrorHelp;
+ errors = true;
+ continue;
+ } else if (!membership.IsValid()) {
+ LOG(ERROR) << path << ":" << line_number
+ << ": Invalid combination of flags: " << line << kErrorHelp;
+ errors = true;
+ continue;
+ }
api_flag_map.emplace(signature, membership);
}
+ CHECK(!errors) << "Errors encountered while parsing file " << path;
api_file.close();
return api_flag_map;
@@ -1107,9 +999,7 @@ class HiddenApi final {
std::set<std::string> unresolved;
// Open all dex files.
- ClassPath boot_classpath(boot_dex_paths_,
- /* open_writable= */ false,
- /* ignore_empty= */ false);
+ ClassPath boot_classpath(boot_dex_paths_, /* ignore_empty= */ false);
Hierarchy boot_hierarchy(boot_classpath, fragment_, verbose_);
// Mark all boot dex members private.
@@ -1118,9 +1008,7 @@ class HiddenApi final {
});
// Open all dependency API stub dex files.
- ClassPath dependency_classpath(dependency_stub_dex_paths_,
- /* open_writable= */ false,
- /* ignore_empty= */ false);
+ ClassPath dependency_classpath(dependency_stub_dex_paths_, /* ignore_empty= */ false);
// Mark all dependency API stub dex members as coming from the dependency.
dependency_classpath.ForEachDexMember([&](const DexMember& boot_member) {
@@ -1132,9 +1020,7 @@ class HiddenApi final {
// Ignore any empty stub jars as it just means that they provide no APIs
// for the current kind, e.g. framework-sdkextensions does not provide
// any public APIs.
- ClassPath stub_classpath(android::base::Split(cp_entry.first, ":"),
- /* open_writable= */ false,
- /* ignore_empty= */ true);
+ ClassPath stub_classpath(android::base::Split(cp_entry.first, ":"), /*ignore_empty=*/true);
Hierarchy stub_hierarchy(stub_classpath, fragment_, verbose_);
const ApiStubs::Kind stub_api = cp_entry.second;
diff --git a/tools/hiddenapi/hiddenapi_test.cc b/tools/hiddenapi/hiddenapi_test.cc
index 3a0e62586d..36e80c5c23 100644
--- a/tools/hiddenapi/hiddenapi_test.cc
+++ b/tools/hiddenapi/hiddenapi_test.cc
@@ -106,7 +106,6 @@ class HiddenApiTest : public CommonRuntimeTest {
}
std::unique_ptr<const DexFile> OpenDex(const ScratchFile& file) {
- ArtDexFileLoader dex_loader;
std::string error_msg;
File fd(file.GetFilename(), O_RDONLY, /* check_usage= */ false);
@@ -115,9 +114,9 @@ class HiddenApiTest : public CommonRuntimeTest {
UNREACHABLE();
}
- std::unique_ptr<const DexFile> dex_file(dex_loader.OpenDex(
- fd.Release(), /* location= */ file.GetFilename(), /* verify= */ true,
- /* verify_checksum= */ true, /* mmap_shared= */ false, &error_msg));
+ ArtDexFileLoader dex_loader(fd.Release(), file.GetFilename());
+ std::unique_ptr<const DexFile> dex_file(dex_loader.Open(
+ /* verify= */ true, /* verify_checksum= */ true, /* mmap_shared= */ false, &error_msg));
if (dex_file.get() == nullptr) {
LOG(FATAL) << "Open failed for '" << file.GetFilename() << "' " << error_msg;
UNREACHABLE();
@@ -143,7 +142,7 @@ class HiddenApiTest : public CommonRuntimeTest {
std::map<std::string, std::string> flags;
for (std::string line; std::getline(ifs, line);) {
- std::size_t comma = line.find(",");
+ std::size_t comma = line.find(',');
if (comma == std::string::npos) {
flags.emplace(line, "");
} else {
diff --git a/tools/host_bcp.sh b/tools/host_bcp.sh
index 26231cdca1..62ebae70d7 100755
--- a/tools/host_bcp.sh
+++ b/tools/host_bcp.sh
@@ -14,27 +14,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-if [[ ${#@} != 1 ]] && [[ ${#@} != 2 ]]; then
+if [[ ${#@} != 1 ]]; then
cat <<EOF
Usage
- host_bcp <image> [--use-first-dir] | xargs <art-host-tool> ...
+ host_bcp <image> | xargs <art-host-tool> ...
Extracts boot class path locations from <image> and outputs the appropriate
--runtime-arg -Xbootclasspath:...
--runtime-arg -Xbootclasspath-locations:...
arguments for many ART host tools based on the \$ANDROID_PRODUCT_OUT variable
-and existing \$ANDROID_PRODUCT_OUT/apex/com.android.art* paths.
-If --use-first-dir is specified, the script will use the first apex dir instead
-of resulting in an error.
+and existing \$ANDROID_PRODUCT_OUT/apex/* paths.
EOF
exit 1
fi
IMAGE=$1
-USE_FIRST_DIR=false
-
-if [[ $2 == "--use-first-dir" ]]; then
- USE_FIRST_DIR=true
-fi
if [[ ! -e ${IMAGE} ]]; then
IMAGE=${ANDROID_PRODUCT_OUT}/$1
@@ -50,34 +43,33 @@ if [[ "x${BCPL}" == "x" ]]; then
exit 1
fi
-MANIFEST=/apex_manifest.pb
-ART_APEX=/apex/com.android.art
-ART_APEX_SELECTED=
-for m in `ls -1 -d ${ANDROID_PRODUCT_OUT}{,/system}${ART_APEX}*${MANIFEST} 2>/dev/null`; do
- d=${m:0:-${#MANIFEST}}
- if [[ "x${ART_APEX_SELECTED}" != "x" ]]; then
- if [[ $USE_FIRST_DIR == true ]]; then
- break
- fi
- echo "Multiple ART APEX dirs: ${ART_APEX_SELECTED}, ${d}."
- exit 1
- fi
- ART_APEX_SELECTED=${d}
-done
-if [[ "x${ART_APEX_SELECTED}" == "x" ]]; then
- echo "No ART APEX dir."
+APEX_INFO_LIST=${ANDROID_PRODUCT_OUT}/apex/apex-info-list.xml
+if [[ ! -e ${APEX_INFO_LIST} ]]; then
+ echo "Failed to locate apex info at ${APEX_INFO_LIST}."
exit 1
fi
BCP=
OLD_IFS=${IFS}
IFS=:
+APEX_PREFIX=/apex/
for COMPONENT in ${BCPL}; do
HEAD=${ANDROID_PRODUCT_OUT}
TAIL=${COMPONENT}
- if [[ ${COMPONENT:0:${#ART_APEX}} = ${ART_APEX} ]]; then
- HEAD=${ART_APEX_SELECTED}
- TAIL=${COMPONENT:${#ART_APEX}}
+ # Apex module paths aren't symlinked on the host, so map from the symbolic
+ # device path to the prebuilt (host) module path using the apex info table.
+ if [[ ${COMPONENT:0:${#APEX_PREFIX}} = ${APEX_PREFIX} ]]; then
+ # First extract the symbolic module name and its (internal) jar path.
+ COMPONENT=${COMPONENT#${APEX_PREFIX}}
+ MODULE_NAME=${COMPONENT%%/*}
+ MODULE_JAR=${COMPONENT#*/}
+ # Use the module name to look up the preinstalled module path..
+ HOST_MODULE=`xmllint --xpath "string(//apex-info[@moduleName=\"${MODULE_NAME}\"]/@preinstalledModulePath)" ${APEX_INFO_LIST}`
+ # Extract the preinstalled module name from the full path (strip prefix/suffix).
+ HOST_MODULE_NAME=${HOST_MODULE#*${APEX_PREFIX}}
+ HOST_MODULE_NAME=${HOST_MODULE_NAME%.*apex}
+ # Rebuild the host path using the preinstalled module name.
+ TAIL="${APEX_PREFIX}${HOST_MODULE_NAME}/${MODULE_JAR}"
fi
if [[ ! -e $HEAD$TAIL ]]; then
echo "File does not exist: $HEAD$TAIL"
diff --git a/tools/jvmti-agents/chain-agents/chainagents.cc b/tools/jvmti-agents/chain-agents/chainagents.cc
index 1242409bdf..d272fc120a 100644
--- a/tools/jvmti-agents/chain-agents/chainagents.cc
+++ b/tools/jvmti-agents/chain-agents/chainagents.cc
@@ -53,7 +53,7 @@ enum class StartType {
OnLoad,
};
-static std::pair<std::string, std::string> Split(std::string source, char delim) {
+static std::pair<std::string, std::string> Split(const std::string& source, char delim) {
std::string first(source.substr(0, source.find(delim)));
if (source.find(delim) == std::string::npos) {
return std::pair(first, "");
diff --git a/tools/jvmti-agents/field-counts/fieldcount.cc b/tools/jvmti-agents/field-counts/fieldcount.cc
index c31a973712..5a4b00e7a5 100644
--- a/tools/jvmti-agents/field-counts/fieldcount.cc
+++ b/tools/jvmti-agents/field-counts/fieldcount.cc
@@ -182,7 +182,7 @@ static void DataDumpRequestCb(jvmtiEnv* jvmti) {
<< "\t" << "<ALL_TYPES>"
<< "\t" << obj_len
<< "\t" << total_size;
- for (auto sz : class_sizes) {
+ for (const std::pair<std::string, size_t> sz : class_sizes) {
size_t count = class_counts[sz.first];
LOG(INFO) << "\t" << field_class_name << "." << field_name << ":" << field_sig
<< "\t" << sz.first
diff --git a/tools/jvmti-agents/simple-force-redefine/forceredefine.cc b/tools/jvmti-agents/simple-force-redefine/forceredefine.cc
index 055fb8aee8..34742388cb 100644
--- a/tools/jvmti-agents/simple-force-redefine/forceredefine.cc
+++ b/tools/jvmti-agents/simple-force-redefine/forceredefine.cc
@@ -94,7 +94,7 @@ class JvmtiAllocator : public dex::Writer::Allocator {
jvmtiEnv* jvmti_;
};
-static void Transform(std::shared_ptr<ir::DexFile> ir) {
+static void Transform(const std::shared_ptr<ir::DexFile>& ir) {
std::unique_ptr<ir::Builder> builder;
for (auto& method : ir->encoded_methods) {
// Do not look into abstract/bridge/native/synthetic methods.
diff --git a/tools/jvmti-agents/simple-profile/simple_profile.cc b/tools/jvmti-agents/simple-profile/simple_profile.cc
index 5ead97edd8..7161142839 100644
--- a/tools/jvmti-agents/simple-profile/simple_profile.cc
+++ b/tools/jvmti-agents/simple-profile/simple_profile.cc
@@ -26,6 +26,7 @@
#include <sstream>
#include <string>
#include <unordered_map>
+#include <utility>
#include <vector>
#include "android-base/unique_fd.h"
@@ -55,7 +56,7 @@ class SimpleProfileData {
SimpleProfileData(
jvmtiEnv* env, std::string out_fd_name, int fd, bool dump_on_shutdown, bool dump_on_main_stop)
: dump_id_(0),
- out_fd_name_(out_fd_name),
+ out_fd_name_(std::move(out_fd_name)),
out_fd_(fd),
shutdown_(false),
dump_on_shutdown_(dump_on_shutdown || dump_on_main_stop),
@@ -79,7 +80,7 @@ class SimpleProfileData {
void Shutdown(jvmtiEnv* jvmti, JNIEnv* jni);
private:
- void DoDump(jvmtiEnv* jvmti, JNIEnv* jni, std::unordered_map<jmethodID, uint64_t> copy);
+ void DoDump(jvmtiEnv* jvmti, JNIEnv* jni, const std::unordered_map<jmethodID, uint64_t>& copy);
jlong dump_id_;
jrawMonitorID mon_;
@@ -320,7 +321,7 @@ std::ostream& operator<<(std::ostream& os, ScopedMethodInfo const& method) {
void SimpleProfileData::DoDump(jvmtiEnv* jvmti,
JNIEnv* jni,
- std::unordered_map<jmethodID, uint64_t> copy) {
+ const std::unordered_map<jmethodID, uint64_t>& copy) {
std::ostringstream oss;
oss << "[";
bool is_first = true;
diff --git a/tools/libcore_failures.txt b/tools/libcore_failures.txt
index 6e6ccb8921..fc28acd22b 100644
--- a/tools/libcore_failures.txt
+++ b/tools/libcore_failures.txt
@@ -330,5 +330,27 @@
bug: 228441328,
names: ["tck.java.time",
"test.java.time"]
+},
+{
+ description: "Timing out after ojluni tests were enabled",
+ result: ERROR,
+ bug: 231439593,
+ names: ["org.apache.harmony.tests.java.math.BigIntegerConstructorsTest#testConstructorPrime"]
+},
+{
+ description: "libcore.android.system.OsConstantsTest CAP constants tests work on device only",
+ result: EXEC_FAILED,
+ modes: [host],
+ names: ["libcore.android.system.OsConstantsTest#test_CAP_TO_INDEX",
+ "libcore.android.system.OsConstantsTest#test_CAP_TO_MASK",
+ "libcore.android.system.OsConstantsTest#test_CAP_constants"]
+},
+{
+ description: "Record test doens't work properly on vogar/",
+ result: EXEC_FAILED,
+ bug: 272698028,
+ names: ["libcore.java.lang.RecordTest",
+ "crossvmtest.java.lang.RecordComponentTest",
+ "crossvmtest.java.lang.RecordTest"]
}
]
diff --git a/tools/libcore_fugu_failures.txt b/tools/libcore_fugu_failures.txt
index 0fff814f5e..60b43d0571 100644
--- a/tools/libcore_fugu_failures.txt
+++ b/tools/libcore_fugu_failures.txt
@@ -25,6 +25,8 @@
names: [
"libcore.java.math.BigIntegerTest#test_Constructor_IILjava_util_Random",
"libcore.java.math.BigIntegerTest#test_probablePrime",
+ "libcore.java.util.UUIDTest#testJava11Implementation_invalidInputs",
+ "libcore.java.util.UUIDTest#testJava8Implementation_allowsLongInputs",
"libcore.javax.crypto.CipherInputStreamTest#testDecryptCorruptGCM",
"libcore.javax.crypto.CipherOutputStreamTest#testDecryptCorruptGCM",
"libcore.libcore.timezone.TelephonyLookupTest#createInstanceWithFallback",
@@ -112,7 +114,6 @@
"org.apache.harmony.crypto.tests.javax.crypto.func.CipherRSATest#test_RSANoPadding",
"org.apache.harmony.crypto.tests.javax.crypto.func.CipherRSATest#test_RSAShortKey",
"org.apache.harmony.crypto.tests.javax.crypto.func.KeyGeneratorFunctionalTest#test_",
- "org.apache.harmony.tests.java.math.BigIntegerConstructorsTest#testConstructorPrime",
"org.apache.harmony.tests.java.math.BigIntegerTest#test_isProbablePrimeI",
"org.apache.harmony.tests.java.math.OldBigIntegerTest#test_ConstructorIILjava_util_Random",
"org.apache.harmony.tests.java.math.OldBigIntegerTest#test_isProbablePrimeI",
@@ -127,5 +128,109 @@
"org.apache.harmony.tests.javax.security.OldSHA1PRNGSecureRandomTest#testNextBytesbyteArray03",
"org.apache.harmony.tests.javax.security.OldSHA1PRNGSecureRandomTest#testSetSeedbyteArray02"
]
+},
+{
+ description: "Test using the getrandom() syscall, only available from Linux 3.17.",
+ result: ERROR,
+ bug: 141230711,
+ modes: [device],
+ names: [
+ "test.java.awt",
+ "test.java.io.ByteArrayInputStream",
+ "test.java.io.ByteArrayOutputStream",
+ "test.java.io.FileReader",
+ "test.java.io.FileWriter",
+ "test.java.io.InputStream",
+ "test.java.io.OutputStream",
+ "test.java.io.PrintStream",
+ "test.java.io.PrintWriter",
+ "test.java.io.Reader",
+ "test.java.io.Writer",
+ "test.java.lang.Boolean",
+ "test.java.lang.ClassLoader",
+ "test.java.lang.Double",
+ "test.java.lang.Float",
+ "test.java.lang.Integer",
+ "test.java.lang.Long",
+ "test.java.lang.StackWalker#main",
+ "test.java.lang.StrictMath.CubeRootTests",
+ "test.java.lang.StrictMath.ExactArithTests",
+ "test.java.lang.StrictMath.Expm1Tests",
+ "test.java.lang.StrictMath.ExpTests",
+ "test.java.lang.StrictMath.HyperbolicTests",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard1",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard2",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard3",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard4",
+ "test.java.lang.StrictMath.HypotTests#testHypot",
+ "test.java.lang.StrictMath.Log1pTests",
+ "test.java.lang.StrictMath.Log10Tests",
+ "test.java.lang.StrictMath.MultiplicationTests",
+ "test.java.lang.StrictMath.PowTests",
+ "test.java.lang.String",
+ "test.java.lang.Thread",
+ "test.java.lang.invoke",
+ "test.java.lang.ref.SoftReference",
+ "test.java.lang.ref.BasicTest",
+ "test.java.lang.ref.EnqueueNullRefTest",
+ "test.java.lang.ref.EnqueuePollRaceTest",
+ "test.java.lang.ref.ReferenceCloneTest",
+ "test.java.lang.ref.ReferenceEnqueuePendingTest",
+ "test.java.math.BigDecimal",
+ "test.java.math.BigInteger#testArithmetic",
+ "test.java.math.BigInteger#testBitCount",
+ "test.java.math.BigInteger#testBitLength",
+ "test.java.math.BigInteger#testbitOps",
+ "test.java.math.BigInteger#testBitwise",
+ "test.java.math.BigInteger#testByteArrayConv",
+ "test.java.math.BigInteger#testConstructor",
+ "test.java.math.BigInteger#testDivideAndReminder",
+ "test.java.math.BigInteger#testDivideLarge",
+ "test.java.math.BigInteger#testModExp",
+ "test.java.math.BigInteger#testMultiplyLarge",
+ "test.java.math.BigInteger#testNextProbablePrime",
+ "test.java.math.BigInteger#testPow",
+ "test.java.math.BigInteger#testSerialize",
+ "test.java.math.BigInteger#testShift",
+ "test.java.math.BigInteger#testSquare",
+ "test.java.math.BigInteger#testSquareLarge",
+ "test.java.math.BigInteger#testSquareRootAndReminder",
+ "test.java.math.BigInteger#testStringConv_generic",
+ "test.java.math.RoundingMode",
+ "test.java.net.DatagramSocket",
+ "test.java.net.Socket",
+ "test.java.net.SocketOptions",
+ "test.java.net.URLDecoder",
+ "test.java.net.URLEncoder",
+ "test.java.nio.channels.Channels",
+ "test.java.nio.channels.SelectionKey",
+ "test.java.nio.channels.Selector",
+ "test.java.nio.file",
+ "test.java.security.cert",
+ "test.java.security.KeyAgreement.KeyAgreementTest",
+ "test.java.security.KeyAgreement.KeySizeTest#testECDHKeySize",
+ "test.java.security.KeyAgreement.KeySpecTest",
+ "test.java.security.KeyAgreement.MultiThreadTest",
+ "test.java.security.KeyAgreement.NegativeTest",
+ "test.java.security.KeyStore",
+ "test.java.security.Provider",
+ "test.java.util.Arrays",
+ "test.java.util.Collection",
+ "test.java.util.Collections",
+ "test.java.util.Date",
+ "test.java.util.EnumMap",
+ "test.java.util.EnumSet",
+ "test.java.util.GregorianCalendar",
+ "test.java.util.LinkedHashMap",
+ "test.java.util.LinkedHashSet",
+ "test.java.util.List",
+ "test.java.util.Map",
+ "test.java.util.Optional",
+ "test.java.util.TimeZone",
+ "test.java.util.concurrent",
+ "test.java.util.function",
+ "test.java.util.stream",
+ "test.java.util.zip.ZipFile"
+ ]
}
]
diff --git a/tools/libcore_gcstress_debug_failures.txt b/tools/libcore_gcstress_debug_failures.txt
index 21931893b5..c9316106c1 100644
--- a/tools/libcore_gcstress_debug_failures.txt
+++ b/tools/libcore_gcstress_debug_failures.txt
@@ -50,7 +50,6 @@
"org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest#testConsequentProxyConnection",
"org.apache.harmony.tests.java.lang.ref.ReferenceQueueTest#test_removeJ",
"org.apache.harmony.tests.java.lang.ProcessManagerTest#testSleep",
- "org.apache.harmony.tests.java.math.BigIntegerConstructorsTest#testConstructorPrime",
"org.apache.harmony.tests.java.util.TimerTest#testOverdueTaskExecutesImmediately",
"org.apache.harmony.tests.java.util.WeakHashMapTest#test_keySet_hasNext"
]
@@ -71,5 +70,11 @@
names: ["jsr166.CompletableFutureTest#testCompleteOnTimeout_completed",
"jsr166.CompletableFutureTest#testDelayedExecutor"
]
+},
+{
+ description: "SocketTimeout test gcstress and debug.",
+ result: EXEC_FAILED,
+ bug: 259530489,
+ names: ["org.apache.harmony.luni.tests.java.net.URLConnectionTest#test_setReadTimeoutI_SocketTimeoutException"]
}
]
diff --git a/tools/libcore_gcstress_failures.txt b/tools/libcore_gcstress_failures.txt
index 55bba72005..81d6ca09da 100644
--- a/tools/libcore_gcstress_failures.txt
+++ b/tools/libcore_gcstress_failures.txt
@@ -36,7 +36,6 @@
"libcore.java.util.stream.CollectorsTest#counting_largeStream",
"org.apache.harmony.tests.java.lang.ref.ReferenceQueueTest#test_remove",
"org.apache.harmony.tests.java.lang.String2Test#test_getBytes",
- "org.apache.harmony.tests.java.math.BigIntegerConstructorsTest#testConstructorPrime",
"org.apache.harmony.tests.java.text.DateFormatTest#test_getAvailableLocales",
"org.apache.harmony.tests.java.util.TimerTest#testOverdueTaskExecutesImmediately",
"org.apache.harmony.tests.java.util.WeakHashMapTest#test_keySet_hasNext"]
diff --git a/tools/luci/config/generated/cr-buildbucket.cfg b/tools/luci/config/generated/cr-buildbucket.cfg
index e4a5923986..1da398c550 100644
--- a/tools/luci/config/generated/cr-buildbucket.cfg
+++ b/tools/luci/config/generated/cr-buildbucket.cfg
@@ -17,7 +17,8 @@ buckets {
builders {
name: "angler-armv7-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:angler-armv7-debug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -35,13 +36,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "angler-armv7-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:angler-armv7-ndebug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -59,13 +61,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "angler-armv7-non-gen-cc"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:angler-armv7-non-gen-cc"
+ dimensions: "device_type:oriole"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -83,13 +86,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "angler-armv8-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:angler-armv8-debug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -107,13 +111,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "angler-armv8-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:angler-armv8-ndebug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -131,13 +136,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "angler-armv8-non-gen-cc"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:angler-armv8-non-gen-cc"
+ dimensions: "device_type:oriole"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -155,13 +161,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "bullhead-armv7-gcstress-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:bullhead-armv7-gcstress-ndebug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -179,13 +186,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "bullhead-armv8-gcstress-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:bullhead-armv8-gcstress-debug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -203,13 +211,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "bullhead-armv8-gcstress-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:bullhead-armv8-gcstress-ndebug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -227,13 +236,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "fugu-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:fugu-debug"
+ dimensions: "device_type:fugu"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -251,13 +261,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "fugu-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:fugu-ndebug"
+ dimensions: "device_type:fugu"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -275,13 +286,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86-cms"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86-cms"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -299,13 +310,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86-debug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -323,13 +334,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86-gcstress-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86-gcstress-debug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -347,13 +358,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86-ndebug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -371,13 +382,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86-poison-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86-poison-debug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -395,13 +406,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86_64-cdex-fast"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86_64-cdex-fast"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -419,13 +430,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86_64-cms"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86_64-cms"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -443,13 +454,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86_64-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86_64-debug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -467,13 +478,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86_64-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86_64-ndebug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -491,13 +502,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86_64-non-gen-cc"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86_64-non-gen-cc"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -515,13 +526,13 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "host-x86_64-poison-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:host-x86_64-poison-debug"
+ dimensions: "os:Linux"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -539,13 +550,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "walleye-armv7-poison-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:walleye-armv7-poison-debug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -563,13 +575,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "walleye-armv8-poison-debug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:walleye-armv8-poison-debug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -587,13 +600,14 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
builders {
name: "walleye-armv8-poison-ndebug"
swarming_host: "chromium-swarm.appspot.com"
- dimensions: "builder:walleye-armv8-poison-ndebug"
+ dimensions: "device_type:bonito|oriole|walleye"
+ dimensions: "os:Android"
dimensions: "pool:luci.art.ci"
recipe {
name: "art"
@@ -611,7 +625,7 @@ buckets {
service_account: "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
experiments {
key: "luci.recipes.use_python3"
- value: 10
+ value: 100
}
}
}
diff --git a/tools/luci/config/generated/luci-scheduler.cfg b/tools/luci/config/generated/luci-scheduler.cfg
index d6c6ab58ab..ba7bceeae5 100644
--- a/tools/luci/config/generated/luci-scheduler.cfg
+++ b/tools/luci/config/generated/luci-scheduler.cfg
@@ -356,6 +356,40 @@ trigger {
refs: "regexp:refs/heads/master-art"
}
}
+trigger {
+ id: "vogar"
+ realm: "ci"
+ acl_sets: "ci"
+ triggers: "angler-armv7-debug"
+ triggers: "angler-armv7-ndebug"
+ triggers: "angler-armv7-non-gen-cc"
+ triggers: "angler-armv8-debug"
+ triggers: "angler-armv8-ndebug"
+ triggers: "angler-armv8-non-gen-cc"
+ triggers: "bullhead-armv7-gcstress-ndebug"
+ triggers: "bullhead-armv8-gcstress-debug"
+ triggers: "bullhead-armv8-gcstress-ndebug"
+ triggers: "fugu-debug"
+ triggers: "fugu-ndebug"
+ triggers: "host-x86-cms"
+ triggers: "host-x86-debug"
+ triggers: "host-x86-gcstress-debug"
+ triggers: "host-x86-ndebug"
+ triggers: "host-x86-poison-debug"
+ triggers: "host-x86_64-cdex-fast"
+ triggers: "host-x86_64-cms"
+ triggers: "host-x86_64-debug"
+ triggers: "host-x86_64-ndebug"
+ triggers: "host-x86_64-non-gen-cc"
+ triggers: "host-x86_64-poison-debug"
+ triggers: "walleye-armv7-poison-debug"
+ triggers: "walleye-armv8-poison-debug"
+ triggers: "walleye-armv8-poison-ndebug"
+ gitiles {
+ repo: "https://android.googlesource.com/platform/external/vogar"
+ refs: "regexp:refs/heads/master"
+ }
+}
acl_sets {
name: "ci"
acls {
diff --git a/tools/luci/config/generated/project.cfg b/tools/luci/config/generated/project.cfg
index 4844ab4987..f9f78772a8 100644
--- a/tools/luci/config/generated/project.cfg
+++ b/tools/luci/config/generated/project.cfg
@@ -7,7 +7,7 @@
name: "art"
access: "group:all"
lucicfg {
- version: "1.30.11"
+ version: "1.33.7"
package_dir: ".."
config_dir: "generated"
entry_point: "main.star"
diff --git a/tools/luci/config/main.star b/tools/luci/config/main.star
index f4ad488020..b1ecde1ec9 100755
--- a/tools/luci/config/main.star
+++ b/tools/luci/config/main.star
@@ -23,7 +23,7 @@ After modifying this file execute it ('./main.star') to regenerate the configs.
lucicfg.check_version("1.30.9", "Please update depot_tools")
luci.builder.defaults.experiments.set({
- "luci.recipes.use_python3": 10,
+ "luci.recipes.use_python3": 100,
})
# Use LUCI Scheduler BBv2 names and add Scheduler realms configs.
@@ -141,13 +141,20 @@ luci.gitiles_poller(
)
luci.gitiles_poller(
+ name = "vogar",
+ bucket = "ci",
+ repo = "https://android.googlesource.com/platform/external/vogar",
+ refs = ["refs/heads/master"],
+)
+
+luci.gitiles_poller(
name = "manifest",
bucket = "ci",
repo = "https://android.googlesource.com/platform/manifest",
refs = ["refs/heads/master-art"],
)
-def ci_builder(name, category, short_name):
+def ci_builder(name, category, short_name, dimensions):
luci.builder(
name = name,
bucket = "ci",
@@ -156,11 +163,8 @@ def ci_builder(name, category, short_name):
cipd_version = "refs/heads/main",
name = "art",
),
- dimensions = {
+ dimensions = dimensions | {
"pool": "luci.art.ci",
-
- # Some builders require specific hardware, so we make the assignment in bots.cfg
- "builder": name,
},
service_account = "art-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
@@ -185,6 +189,7 @@ def ci_builder(name, category, short_name):
"art",
"libcore",
"manifest",
+ "vogar",
],
)
luci.console_view_entry(
@@ -194,28 +199,37 @@ def ci_builder(name, category, short_name):
short_name = short_name,
)
-ci_builder("angler-armv7-debug", "angler|armv7", "dbg")
-ci_builder("angler-armv7-non-gen-cc", "angler|armv7", "ngen")
-ci_builder("angler-armv7-ndebug", "angler|armv7", "ndbg")
-ci_builder("angler-armv8-debug", "angler|armv8", "dbg")
-ci_builder("angler-armv8-non-gen-cc", "angler|armv8", "ngen")
-ci_builder("angler-armv8-ndebug", "angler|armv8", "ndbg")
-ci_builder("bullhead-armv7-gcstress-ndebug", "bullhead|armv7|gcstress", "dbg")
-ci_builder("bullhead-armv8-gcstress-debug", "bullhead|armv8|gcstress", "dbg")
-ci_builder("bullhead-armv8-gcstress-ndebug", "bullhead|armv8|gcstress", "ndbg")
-ci_builder("fugu-debug", "fugu", "dbg")
-ci_builder("fugu-ndebug", "fugu", "ndbg")
-ci_builder("host-x86-cms", "host|x86", "cms")
-ci_builder("host-x86-debug", "host|x86", "dbg")
-ci_builder("host-x86-ndebug", "host|x86", "ndbg")
-ci_builder("host-x86-gcstress-debug", "host|x86", "gcs")
-ci_builder("host-x86-poison-debug", "host|x86", "psn")
-ci_builder("host-x86_64-cdex-fast", "host|x64", "cdx")
-ci_builder("host-x86_64-cms", "host|x64", "cms")
-ci_builder("host-x86_64-debug", "host|x64", "dbg")
-ci_builder("host-x86_64-non-gen-cc", "host|x64", "ngen")
-ci_builder("host-x86_64-ndebug", "host|x64", "ndbg")
-ci_builder("host-x86_64-poison-debug", "host|x64", "psn")
-ci_builder("walleye-armv7-poison-debug", "walleye|armv7|poison", "dbg")
-ci_builder("walleye-armv8-poison-debug", "walleye|armv8|poison", "dbg")
-ci_builder("walleye-armv8-poison-ndebug", "walleye|armv8|poison", "ndbg")
+# Dimensions specify which bots we can run on.
+host_dims = {"os": "Linux"}
+target_dims = {"os": "Android"}
+arm_target_dims = target_dims | {"device_type": "bonito|oriole|walleye"}
+x86_target_dims = target_dims | {"device_type": "fugu"}
+
+# userfault-GC configurations must be run on Pixel 6.
+userfault_gc_target_dims = target_dims | {"device_type": "oriole"}
+
+ci_builder("angler-armv7-debug", "angler|armv7", "dbg", arm_target_dims)
+ci_builder("angler-armv7-non-gen-cc", "angler|armv7", "ngen", userfault_gc_target_dims)
+ci_builder("angler-armv7-ndebug", "angler|armv7", "ndbg", arm_target_dims)
+ci_builder("angler-armv8-debug", "angler|armv8", "dbg", arm_target_dims)
+ci_builder("angler-armv8-non-gen-cc", "angler|armv8", "ngen", userfault_gc_target_dims)
+ci_builder("angler-armv8-ndebug", "angler|armv8", "ndbg", arm_target_dims)
+ci_builder("bullhead-armv7-gcstress-ndebug", "bullhead|armv7|gcstress", "dbg", arm_target_dims)
+ci_builder("bullhead-armv8-gcstress-debug", "bullhead|armv8|gcstress", "dbg", arm_target_dims)
+ci_builder("bullhead-armv8-gcstress-ndebug", "bullhead|armv8|gcstress", "ndbg", arm_target_dims)
+ci_builder("fugu-debug", "fugu", "dbg", x86_target_dims)
+ci_builder("fugu-ndebug", "fugu", "ndbg", x86_target_dims)
+ci_builder("host-x86-cms", "host|x86", "cms", host_dims)
+ci_builder("host-x86-debug", "host|x86", "dbg", host_dims)
+ci_builder("host-x86-ndebug", "host|x86", "ndbg", host_dims)
+ci_builder("host-x86-gcstress-debug", "host|x86", "gcs", host_dims)
+ci_builder("host-x86-poison-debug", "host|x86", "psn", host_dims)
+ci_builder("host-x86_64-cdex-fast", "host|x64", "cdx", host_dims)
+ci_builder("host-x86_64-cms", "host|x64", "cms", host_dims)
+ci_builder("host-x86_64-debug", "host|x64", "dbg", host_dims)
+ci_builder("host-x86_64-non-gen-cc", "host|x64", "ngen", host_dims)
+ci_builder("host-x86_64-ndebug", "host|x64", "ndbg", host_dims)
+ci_builder("host-x86_64-poison-debug", "host|x64", "psn", host_dims)
+ci_builder("walleye-armv7-poison-debug", "walleye|armv7|poison", "dbg", arm_target_dims)
+ci_builder("walleye-armv8-poison-debug", "walleye|armv8|poison", "dbg", arm_target_dims)
+ci_builder("walleye-armv8-poison-ndebug", "walleye|armv8|poison", "ndbg", arm_target_dims)
diff --git a/tools/prebuilt_libjdwp_art_failures.txt b/tools/prebuilt_libjdwp_art_failures.txt
index ee59315ccb..4ded7d56ed 100644
--- a/tools/prebuilt_libjdwp_art_failures.txt
+++ b/tools/prebuilt_libjdwp_art_failures.txt
@@ -106,5 +106,5 @@
result: EXEC_FAILED,
bug: 69169846,
name: "org.apache.harmony.jpda.tests.jdwp.DDM_DDMTest#testChunk001"
-},
+}
]
diff --git a/tools/public.libraries.buildbot.txt b/tools/public.libraries.buildbot.txt
index e23cf2cfb4..9b0dc6858a 100644
--- a/tools/public.libraries.buildbot.txt
+++ b/tools/public.libraries.buildbot.txt
@@ -1,6 +1,6 @@
-libbacktrace.so
libc.so
libc++.so
libdl.so
libm.so
libnativehelper.so
+libunwindstack.so
diff --git a/tools/run-gtests.sh b/tools/run-gtests.sh
index 21064c1739..da61c7e3cc 100755
--- a/tools/run-gtests.sh
+++ b/tools/run-gtests.sh
@@ -59,20 +59,47 @@ done
options="$@"
+run_in_chroot() {
+ if [ -n "$ART_TEST_ON_VM" ]; then
+ $ART_SSH_CMD $ART_CHROOT_CMD $@
+ else
+ "$adb" shell chroot "$ART_TEST_CHROOT" $@
+ fi
+}
+
if [[ ${#tests[@]} -eq 0 ]]; then
# Search for executables under the `bin/art` directory of the ART APEX.
- readarray -t tests <<<$("$adb" shell chroot "$ART_TEST_CHROOT" \
+ readarray -t tests <<<$(run_in_chroot \
find "$android_art_root/bin/art" -type f -perm /ugo+x | sort)
fi
+maybe_get_fake_dex2oatbootclasspath() {
+ if [ -n "$ART_TEST_ON_VM" ]; then
+ return
+ fi
+ dex2oatbootclasspath=$("$adb" shell echo \$DEX2OATBOOTCLASSPATH)
+ if [ -n "$dex2oatbootclasspath" ]; then
+ # The device has a real DEX2OATBOOTCLASSPATH.
+ # This is the usual case.
+ return
+ fi
+ bootclasspath=$("$adb" shell echo \$BOOTCLASSPATH)
+ # Construct a fake DEX2OATBOOTCLASSPATH from the elements in BOOTCLASSPATH except the last one.
+ # BOOTCLASSPATH cannot be used by the runtime in chroot anyway, so it doesn't hurt to construct a
+ # fake DEX2OATBOOTCLASSPATH just to make the runtime happy.
+ # This is only needed on old Android platforms such as Android P.
+ echo "DEX2OATBOOTCLASSPATH=${bootclasspath%:*}"
+}
+
failing_tests=()
for t in ${tests[@]}; do
echo "$t"
- "$adb" shell chroot "$ART_TEST_CHROOT" \
+ run_in_chroot \
env ANDROID_ART_ROOT="$android_art_root" \
ANDROID_I18N_ROOT="$android_i18n_root" \
ANDROID_TZDATA_ROOT="$android_tzdata_root" \
+ $(maybe_get_fake_dex2oatbootclasspath) \
$t $options \
|| failing_tests+=("$t")
done
diff --git a/tools/run-libcore-tests.py b/tools/run-libcore-tests.py
index 1e6070a51e..c6958f1b6c 100755
--- a/tools/run-libcore-tests.py
+++ b/tools/run-libcore-tests.py
@@ -42,6 +42,7 @@ def parse_args():
help='Enable GC stress configuration (device|host only).')
parser.add_argument('tests', nargs="*",
help='Name(s) of the test(s) to run')
+ parser.add_argument('--verbose', action='store_true', help='Print verbose output from vogar.')
return parser.parse_args()
ART_TEST_ANDROID_ROOT = os.environ.get("ART_TEST_ANDROID_ROOT", "/system")
@@ -91,7 +92,10 @@ LIBCORE_TEST_NAMES = [
"libcore.sun.util",
"libcore.xml",
"org.apache.harmony.annotation",
- "org.apache.harmony.luni",
+ "org.apache.harmony.luni.tests.internal.net.www.protocol.http.HttpURLConnection",
+ "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnection",
+ "org.apache.harmony.luni.tests.java.io",
+ "org.apache.harmony.luni.tests.java.net",
"org.apache.harmony.nio",
"org.apache.harmony.regex",
"org.apache.harmony.testframework",
@@ -122,7 +126,8 @@ LIBCORE_TEST_NAMES = [
"test.java.lang.Long",
# Sharded test.java.lang.StrictMath
"test.java.lang.StrictMath.CubeRootTests",
- "test.java.lang.StrictMath.ExactArithTests",
+ # TODO: disable the test until b/248208762 is fixed.
+ # "test.java.lang.StrictMath.ExactArithTests",
"test.java.lang.StrictMath.Expm1Tests",
"test.java.lang.StrictMath.ExpTests",
"test.java.lang.StrictMath.HyperbolicTests",
@@ -159,21 +164,15 @@ LIBCORE_TEST_NAMES = [
"test.java.math.BigInteger#testDivideAndReminder",
"test.java.math.BigInteger#testDivideLarge",
"test.java.math.BigInteger#testModExp",
- "test.java.math.BigInteger#testModInv",
"test.java.math.BigInteger#testMultiplyLarge",
"test.java.math.BigInteger#testNextProbablePrime",
"test.java.math.BigInteger#testPow",
- "test.java.math.BigInteger#testPrime",
"test.java.math.BigInteger#testSerialize",
"test.java.math.BigInteger#testShift",
"test.java.math.BigInteger#testSquare",
"test.java.math.BigInteger#testSquareLarge",
- "test.java.math.BigInteger#testSquareRoot",
"test.java.math.BigInteger#testSquareRootAndReminder",
"test.java.math.BigInteger#testStringConv_generic",
- "test.java.math.BigInteger#testStringConv_schoenhage_threshold_pow0",
- "test.java.math.BigInteger#testStringConv_schoenhage_threshold_pow1",
- "test.java.math.BigInteger#testStringConv_schoenhage_threshold_pow2",
"test.java.math.RoundingMode",
# test.java.net
"test.java.net.DatagramSocket",
@@ -190,7 +189,6 @@ LIBCORE_TEST_NAMES = [
"test.java.security.cert",
# Sharded test.java.security.KeyAgreement
"test.java.security.KeyAgreement.KeyAgreementTest",
- "test.java.security.KeyAgreement.KeySizeTest#testDHKeySize",
"test.java.security.KeyAgreement.KeySizeTest#testECDHKeySize",
"test.java.security.KeyAgreement.KeySpecTest",
"test.java.security.KeyAgreement.MultiThreadTest",
@@ -242,6 +240,130 @@ BOOT_CLASSPATH = [
CLASSPATH = ["core-tests", "core-ojtests", "jsr166-tests", "mockito-target"]
+SLOW_OJLUNI_TESTS = {
+ "test.java.awt",
+ "test.java.lang.String",
+ "test.java.lang.invoke",
+ "test.java.nio.channels.Selector",
+ "test.java.time",
+ "test.java.util.Arrays",
+ "test.java.util.Map",
+ "test.java.util.concurrent",
+ "test.java.util.stream",
+ "test.java.util.zip.ZipFile",
+ "tck.java.time",
+}
+
+# Disabled to unblock art-buildbot
+# These tests fail with "java.io.IOException: Stream closed", tracked in
+# http://b/235566533 and http://b/208639267
+DISABLED_GCSTRESS_DEBUG_TESTS = {
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard1",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard2",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard3",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard4",
+ "test.java.math.BigDecimal",
+ "test.java.math.BigInteger#testConstructor",
+}
+
+DISABLED_FUGU_TESTS = {
+ "org.apache.harmony.luni.tests.internal.net.www.protocol.http.HttpURLConnection",
+ "org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnection",
+ "test.java.awt",
+ "test.java.io.ByteArrayInputStream",
+ "test.java.io.ByteArrayOutputStream",
+ "test.java.io.InputStream",
+ "test.java.io.OutputStream",
+ "test.java.io.PrintStream",
+ "test.java.io.PrintWriter",
+ "test.java.io.Reader",
+ "test.java.io.Writer",
+ "test.java.lang.Boolean",
+ "test.java.lang.ClassLoader",
+ "test.java.lang.Double",
+ "test.java.lang.Float",
+ "test.java.lang.Integer",
+ "test.java.lang.Long",
+ "test.java.lang.StrictMath.CubeRootTests",
+ "test.java.lang.StrictMath.Expm1Tests",
+ "test.java.lang.StrictMath.ExpTests",
+ "test.java.lang.StrictMath.HyperbolicTests",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard1",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard2",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard3",
+ "test.java.lang.StrictMath.HypotTests#testAgainstTranslit_shard4",
+ "test.java.lang.StrictMath.HypotTests#testHypot",
+ "test.java.lang.StrictMath.Log1pTests",
+ "test.java.lang.StrictMath.Log10Tests",
+ "test.java.lang.StrictMath.MultiplicationTests",
+ "test.java.lang.StrictMath.PowTests",
+ "test.java.lang.String",
+ "test.java.lang.Thread",
+ "test.java.lang.invoke",
+ "test.java.lang.ref.SoftReference",
+ "test.java.lang.ref.BasicTest",
+ "test.java.lang.ref.EnqueueNullRefTest",
+ "test.java.lang.ref.EnqueuePollRaceTest",
+ "test.java.lang.ref.ReferenceCloneTest",
+ "test.java.lang.ref.ReferenceEnqueuePendingTest",
+ "test.java.math.BigDecimal",
+ "test.java.math.BigInteger#testArithmetic",
+ "test.java.math.BigInteger#testBitCount",
+ "test.java.math.BigInteger#testBitLength",
+ "test.java.math.BigInteger#testbitOps",
+ "test.java.math.BigInteger#testBitwise",
+ "test.java.math.BigInteger#testByteArrayConv",
+ "test.java.math.BigInteger#testConstructor",
+ "test.java.math.BigInteger#testDivideAndReminder",
+ "test.java.math.BigInteger#testDivideLarge",
+ "test.java.math.BigInteger#testModExp",
+ "test.java.math.BigInteger#testMultiplyLarge",
+ "test.java.math.BigInteger#testNextProbablePrime",
+ "test.java.math.BigInteger#testPow",
+ "test.java.math.BigInteger#testSerialize",
+ "test.java.math.BigInteger#testShift",
+ "test.java.math.BigInteger#testSquare",
+ "test.java.math.BigInteger#testSquareLarge",
+ "test.java.math.BigInteger#testSquareRootAndReminder",
+ "test.java.math.BigInteger#testStringConv_generic",
+ "test.java.math.RoundingMode",
+ "test.java.net.DatagramSocket",
+ "test.java.net.Socket",
+ "test.java.net.SocketOptions",
+ "test.java.net.URLDecoder",
+ "test.java.net.URLEncoder",
+ "test.java.nio.channels.Channels",
+ "test.java.nio.channels.SelectionKey",
+ "test.java.nio.channels.Selector",
+ "test.java.nio.file",
+ "test.java.security.cert",
+ "test.java.security.KeyAgreement.KeyAgreementTest",
+ "test.java.security.KeyAgreement.KeySizeTest#testECDHKeySize",
+ "test.java.security.KeyAgreement.KeySpecTest",
+ "test.java.security.KeyAgreement.MultiThreadTest",
+ "test.java.security.KeyAgreement.NegativeTest",
+ "test.java.security.KeyStore",
+ "test.java.security.Provider",
+ "test.java.time",
+ "test.java.util.Arrays",
+ "test.java.util.Collection",
+ "test.java.util.Collections",
+ "test.java.util.Date",
+ "test.java.util.EnumMap",
+ "test.java.util.EnumSet",
+ "test.java.util.GregorianCalendar",
+ "test.java.util.LinkedHashMap",
+ "test.java.util.LinkedHashSet",
+ "test.java.util.List",
+ "test.java.util.Map",
+ "test.java.util.Optional",
+ "test.java.util.TestFormatter",
+ "test.java.util.TimeZone",
+ "test.java.util.function",
+ "test.java.util.stream",
+ "tck.java.time",
+}
+
def get_jar_filename(classpath):
base_path = (ANDROID_PRODUCT_OUT + "/../..") if ANDROID_PRODUCT_OUT else "out/target"
base_path = os.path.normpath(base_path) # Normalize ".." components for readability.
@@ -275,6 +397,13 @@ def get_test_names():
# See b/78228743 and b/178351808.
if args.gcstress or args.debug or args.mode == "jvm":
test_names = list(t for t in test_names if not t.startswith("libcore.highmemorytest"))
+ test_names = list(filter(lambda x: x not in SLOW_OJLUNI_TESTS, test_names))
+ if args.gcstress and args.debug:
+ test_names = list(filter(lambda x: x not in DISABLED_GCSTRESS_DEBUG_TESTS, test_names))
+ if not args.getrandom:
+ # Disable libcore.highmemorytest due to limited ram on fugu. http://b/258173036
+ test_names = list(filter(lambda x: x not in DISABLED_FUGU_TESTS and
+ not x.startswith("libcore.highmemorytest"), test_names))
return test_names
def get_vogar_command(test_name):
@@ -282,6 +411,7 @@ def get_vogar_command(test_name):
if args.mode == "device":
cmd.append("--mode=device --vm-arg -Ximage:/system/framework/art_boot_images/boot.art")
cmd.append("--vm-arg -Xbootclasspath:" + ":".join(BOOT_CLASSPATH))
+
if args.mode == "host":
# We explicitly give a wrong path for the image, to ensure vogar
# will create a boot image with the default compiler. Note that
@@ -298,11 +428,16 @@ def get_vogar_command(test_name):
if args.debug:
cmd.append("--vm-arg -XXlib:libartd.so --vm-arg -XX:SlowDebug=true")
+ # The only device in go/art-buildbot without getrandom is fugu. We limit the amount of memory
+ # per runtime for fugu to avoid low memory killer, fugu has 4-cores 1GB RAM (b/258171768).
+ if not args.getrandom:
+ cmd.append("--vm-arg -Xmx128M")
+
if args.mode == "device":
if ART_TEST_CHROOT:
cmd.append(f"--chroot {ART_TEST_CHROOT} --device-dir=/tmp/vogar/test-{test_name}")
else:
- cmd.append("--device-dir=/data/local/tmp/vogar/test-{test_name}")
+ cmd.append(f"--device-dir=/data/local/tmp/vogar/test-{test_name}")
cmd.append(f"--vm-command={ART_TEST_ANDROID_ROOT}/bin/art")
else:
cmd.append(f"--device-dir=/tmp/vogar/test-{test_name}")
@@ -314,6 +449,9 @@ def get_vogar_command(test_name):
cmd.append("--vm-arg -Xcompiler-option --vm-arg --compiler-filter=quicken")
cmd.append("--vm-arg -Xusejit:{}".format(str(args.jit).lower()))
+ if args.verbose:
+ cmd.append("--verbose")
+
# Suppress color codes if not attached to a terminal
if not sys.stdout.isatty():
cmd.append("--no-color")
@@ -370,7 +508,7 @@ def main():
print(f"Running {len(futures)} tasks on {args.jobs} core(s)...\n")
for i, future in enumerate(concurrent.futures.as_completed(futures)):
test_name, cmd, stdout, exit_code = future.result()
- if exit_code != 0 or args.dry_run:
+ if exit_code != 0 or args.dry_run or args.verbose:
print(cmd)
print(stdout.strip())
else:
diff --git a/tools/run-libjdwp-tests.sh b/tools/run-libjdwp-tests.sh
index efb2737cad..06e34f9c3d 100755
--- a/tools/run-libjdwp-tests.sh
+++ b/tools/run-libjdwp-tests.sh
@@ -138,6 +138,10 @@ if [[ "$debug" = "yes" && "$has_gcstress" = "yes" ]]; then
expectations="$expectations --expectations $PWD/art/tools/external_oj_libjdwp_art_gcstress_debug_failures.txt"
fi
+if [[ "${ART_USE_READ_BARRIER}" = "false" ]]; then
+ expectations="$expectations --expectations $PWD/art/tools/external_oj_libjdwp_art_no_read_barrier_failures.txt"
+fi
+
function verbose_run() {
echo "$@"
env "$@"
diff --git a/tools/signal_dumper/Android.bp b/tools/signal_dumper/Android.bp
index 33450d1301..00948b8aad 100644
--- a/tools/signal_dumper/Android.bp
+++ b/tools/signal_dumper/Android.bp
@@ -48,18 +48,6 @@ cc_defaults {
},
}
-cc_defaults {
- name: "signal_dumper_libbacktrace_static_deps",
- defaults: [
- "signal_dumper_libbase_static_deps",
- "signal_dumper_libunwindstack_static_deps",
- ],
- static_libs: [
- "libbase",
- "libunwindstack",
- ],
-}
-
art_cc_binary {
name: "signal_dumper",
@@ -73,14 +61,14 @@ art_cc_binary {
defaults: [
"art_defaults",
- "signal_dumper_libbacktrace_static_deps",
"signal_dumper_libbase_static_deps",
+ "signal_dumper_libunwindstack_static_deps",
],
srcs: ["signal_dumper.cc"],
static_libs: [
- "libbacktrace",
"libbase",
+ "libunwindstack",
],
}
diff --git a/tools/signal_dumper/signal_dumper.cc b/tools/signal_dumper/signal_dumper.cc
index e9a589e699..bedb8dc6fc 100644
--- a/tools/signal_dumper/signal_dumper.cc
+++ b/tools/signal_dumper/signal_dumper.cc
@@ -15,6 +15,7 @@
*/
#include <dirent.h>
+#include <inttypes.h>
#include <poll.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
@@ -38,8 +39,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
+#include <unwindstack/AndroidUnwinder.h>
namespace art {
namespace {
@@ -368,11 +368,13 @@ std::set<pid_t> PtraceSiblings(pid_t pid) {
}
void DumpABI(pid_t forked_pid) {
- enum class ABI { kArm, kArm64, kX86, kX86_64 };
+ enum class ABI { kArm, kArm64, kRiscv64, kX86, kX86_64 };
#if defined(__arm__)
constexpr ABI kDumperABI = ABI::kArm;
#elif defined(__aarch64__)
constexpr ABI kDumperABI = ABI::kArm64;
+#elif defined(__riscv)
+ constexpr ABI kDumperABI = ABI::kRiscv64;
#elif defined(__i386__)
constexpr ABI kDumperABI = ABI::kX86;
#elif defined(__x86_64__)
@@ -394,6 +396,9 @@ void DumpABI(pid_t forked_pid) {
case ABI::kArm64:
to_print = ABI::kArm64;
break;
+ case ABI::kRiscv64:
+ to_print = ABI::kRiscv64;
+ break;
case ABI::kX86:
case ABI::kX86_64:
to_print = ABI::kX86_64;
@@ -408,6 +413,9 @@ void DumpABI(pid_t forked_pid) {
case ABI::kArm64:
to_print = io_vec.iov_len == 18 * sizeof(uint32_t) ? ABI::kArm : ABI::kArm64;
break;
+ case ABI::kRiscv64:
+ to_print = ABI::kRiscv64;
+ break;
case ABI::kX86:
case ABI::kX86_64:
to_print = io_vec.iov_len == 17 * sizeof(uint32_t) ? ABI::kX86 : ABI::kX86_64;
@@ -424,6 +432,9 @@ void DumpABI(pid_t forked_pid) {
case ABI::kArm64:
abi_str = "arm64";
break;
+ case ABI::kRiscv64:
+ abi_str = "riscv64";
+ break;
case ABI::kX86:
abi_str = "x86";
break;
@@ -492,11 +503,10 @@ constexpr bool kIs64Bit = true;
constexpr bool kIs64Bit = false;
#endif
-void DumpThread(pid_t pid,
+void DumpThread(unwindstack::AndroidRemoteUnwinder& unwinder, pid_t pid,
pid_t tid,
const std::string* addr2line_path,
- const char* prefix,
- BacktraceMap* map) {
+ const char* prefix) {
LOG(ERROR) << std::endl << "=== pid: " << pid << " tid: " << tid << " ===" << std::endl;
constexpr uint32_t kMaxWaitMicros = 1000 * 1000; // 1s.
@@ -504,50 +514,41 @@ void DumpThread(pid_t pid,
LOG(ERROR) << "Failed to wait for sigstop on " << tid;
}
- std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
- if (backtrace == nullptr) {
- LOG(ERROR) << prefix << "(failed to create Backtrace for thread " << tid << ")";
- return;
- }
- backtrace->SetSkipFrames(false);
- if (!backtrace->Unwind(0, nullptr)) {
- LOG(ERROR) << prefix << "(backtrace::Unwind failed for thread " << tid
- << ": " << backtrace->GetErrorString(backtrace->GetError()) << ")";
- return;
- }
- if (backtrace->NumFrames() == 0) {
- LOG(ERROR) << prefix << "(no native stack frames for thread " << tid << ")";
+ unwindstack::AndroidUnwinderData data;
+ if (!unwinder.Unwind(tid, data)) {
+ LOG(ERROR) << prefix << "(Unwind failed for thread " << tid << ": "
+ << data.GetErrorString() << ")";
return;
}
std::unique_ptr<addr2line::Addr2linePipe> addr2line_state;
-
- for (Backtrace::const_iterator it = backtrace->begin();
- it != backtrace->end(); ++it) {
+ data.DemangleFunctionNames();
+ for (const unwindstack::FrameData& frame : data.frames) {
std::ostringstream oss;
- oss << prefix << StringPrintf("#%02zu pc ", it->num);
+ oss << prefix << StringPrintf("#%02zu pc ", frame.num);
bool try_addr2line = false;
- if (!BacktraceMap::IsValid(it->map)) {
- oss << StringPrintf(kIs64Bit ? "%016" PRIx64 " ???" : "%08" PRIx64 " ???", it->pc);
+ if (frame.map_info == nullptr) {
+ oss << StringPrintf(kIs64Bit ? "%016" PRIx64 " ???" : "%08" PRIx64 " ???", frame.pc);
} else {
- oss << StringPrintf(kIs64Bit ? "%016" PRIx64 " " : "%08" PRIx64 " ", it->rel_pc);
- if (it->map.name.empty()) {
- oss << StringPrintf("<anonymous:%" PRIx64 ">", it->map.start);
+ oss << StringPrintf(kIs64Bit ? "%016" PRIx64 " " : "%08" PRIx64 " ", frame.rel_pc);
+ if (frame.map_info->name().empty()) {
+ oss << StringPrintf("<anonymous:%" PRIx64 ">", frame.map_info->start());
} else {
- oss << it->map.name;
+ oss << frame.map_info->name().c_str();
}
- if (it->map.offset != 0) {
- oss << StringPrintf(" (offset %" PRIx64 ")", it->map.offset);
+ if (frame.map_info->offset() != 0) {
+ oss << StringPrintf(" (offset %" PRIx64 ")", frame.map_info->offset());
}
oss << " (";
- if (!it->func_name.empty()) {
- oss << it->func_name;
- if (it->func_offset != 0) {
- oss << "+" << it->func_offset;
+ const std::string& function_name = frame.function_name;
+ if (!function_name.empty()) {
+ oss << function_name;
+ if (frame.function_offset != 0) {
+ oss << "+" << frame.function_offset;
}
// Functions found using the gdb jit interface will be in an empty
// map that cannot be found using addr2line.
- if (!it->map.name.empty()) {
+ if (!frame.map_info->name().empty()) {
try_addr2line = true;
}
} else {
@@ -558,8 +559,8 @@ void DumpThread(pid_t pid,
LOG(ERROR) << oss.str() << std::endl;
if (try_addr2line && addr2line_path != nullptr) {
addr2line::Addr2line(*addr2line_path,
- it->map.name,
- it->rel_pc,
+ frame.map_info->name(),
+ frame.rel_pc,
LOG_STREAM(ERROR),
prefix,
&addr2line_state);
@@ -593,14 +594,9 @@ void DumpProcess(pid_t forked_pid, const std::atomic<bool>& saw_wif_stopped_for_
LOG(ERROR) << "Did not receive SIGSTOP for pid " << forked_pid;
}
- std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(forked_pid));
- if (backtrace_map == nullptr) {
- LOG(ERROR) << "Could not create BacktraceMap";
- return;
- }
-
+ unwindstack::AndroidRemoteUnwinder unwinder(forked_pid);
for (pid_t tid : tids) {
- DumpThread(forked_pid, tid, addr2line_path.get(), " ", backtrace_map.get());
+ DumpThread(unwinder, forked_pid, tid, addr2line_path.get(), " ");
}
}
diff --git a/tools/tracefast-plugin/tracefast.cc b/tools/tracefast-plugin/tracefast.cc
index 618742de9a..abc871d9b3 100644
--- a/tools/tracefast-plugin/tracefast.cc
+++ b/tools/tracefast-plugin/tracefast.cc
@@ -60,7 +60,6 @@ class Tracer final : public art::instrumentation::InstrumentationListener {
override REQUIRES_SHARED(art::Locks::mutator_lock_) { }
void MethodUnwind(art::Thread* thread ATTRIBUTE_UNUSED,
- art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED,
art::ArtMethod* method ATTRIBUTE_UNUSED,
uint32_t dex_pc ATTRIBUTE_UNUSED)
override REQUIRES_SHARED(art::Locks::mutator_lock_) { }
@@ -131,7 +130,8 @@ static void StartTracing() REQUIRES(!art::Locks::mutator_lock_,
art::instrumentation::Instrumentation::kMethodEntered |
art::instrumentation::Instrumentation::kMethodExited |
art::instrumentation::Instrumentation::kMethodUnwind);
- runtime->GetInstrumentation()->EnableMethodTracing(kTracerInstrumentationKey, kNeedsInterpreter);
+ runtime->GetInstrumentation()->EnableMethodTracing(
+ kTracerInstrumentationKey, &gEmptyTracer, kNeedsInterpreter);
}
class TraceFastPhaseCB : public art::RuntimePhaseCallback {
diff --git a/tools/veridex/Android.bp b/tools/veridex/Android.bp
index d5f5162419..7b120cfcc4 100644
--- a/tools/veridex/Android.bp
+++ b/tools/veridex/Android.bp
@@ -40,6 +40,7 @@ cc_binary {
static_libs: [
"libdexfile",
"libartbase",
+ "libartpalette",
"libbase",
"liblog",
"libz",
diff --git a/tools/veridex/Android.mk b/tools/veridex/Android.mk
index f7c8d5084e..9ea9b3a5be 100644
--- a/tools/veridex/Android.mk
+++ b/tools/veridex/Android.mk
@@ -23,14 +23,14 @@ LOCAL_PATH := $(call my-dir)
system_stub_dex := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/core_dex_intermediates/classes.dex
$(system_stub_dex): PRIVATE_MIN_SDK_VERSION := 1000
-$(system_stub_dex): $(call resolve-prebuilt-sdk-jar-path,system_current) | $(ZIP2ZIP) $(DX)
+$(system_stub_dex): $(call resolve-prebuilt-sdk-jar-path,system_current) | $(ZIP2ZIP) $(D8)
$(transform-classes.jar-to-dex)
$(call declare-1p-target,$(system_stub_dex),art)
oahl_stub_dex := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/oahl_dex_intermediates/classes.dex
$(oahl_stub_dex): PRIVATE_MIN_SDK_VERSION := 1000
-$(oahl_stub_dex): $(call get-prebuilt-sdk-dir,current)/org.apache.http.legacy.jar | $(ZIP2ZIP) $(DX)
+$(oahl_stub_dex): $(call get-prebuilt-sdk-dir,current)/org.apache.http.legacy.jar | $(ZIP2ZIP) $(D8)
$(transform-classes.jar-to-dex)
$(call declare-1p-target,$(oahl_stub_dex),art)
diff --git a/tools/veridex/flow_analysis.cc b/tools/veridex/flow_analysis.cc
index 2a8b8a0522..6a4d3514d3 100644
--- a/tools/veridex/flow_analysis.cc
+++ b/tools/veridex/flow_analysis.cc
@@ -540,7 +540,7 @@ void VeriFlowAnalysis::ProcessDexInstruction(const Instruction& instruction) {
case Instruction::FILLED_NEW_ARRAY: {
dex::TypeIndex type_index(instruction.VRegB_35c());
VeriClass* cls = resolver_->GetVeriClass(type_index);
- UpdateRegister(instruction.VRegA_22c(), cls);
+ UpdateRegister(instruction.VRegA_35c(), cls);
break;
}
@@ -602,7 +602,7 @@ void VeriFlowAnalysis::ProcessDexInstruction(const Instruction& instruction) {
if (VeriClass::sdkInt_ != nullptr && resolver_->GetField(field_index) == VeriClass::sdkInt_) {
UpdateRegister(dest_reg, gTargetSdkVersion, VeriClass::integer_);
} else {
- UpdateRegister(dest_reg, GetFieldType(instruction.VRegC_22c()));
+ UpdateRegister(dest_reg, GetFieldType(field_index));
}
break;
}
diff --git a/tools/veridex/hidden_api.cc b/tools/veridex/hidden_api.cc
index 71ea56b56f..69e6fe403f 100644
--- a/tools/veridex/hidden_api.cc
+++ b/tools/veridex/hidden_api.cc
@@ -29,14 +29,22 @@ HiddenApi::HiddenApi(const char* filename, const ApiListFilter& api_list_filter)
CHECK(filename != nullptr);
std::ifstream in(filename);
+ bool errors = false;
for (std::string str; std::getline(in, str);) {
std::vector<std::string> values = android::base::Split(str, ",");
const std::string& signature = values[0];
hiddenapi::ApiList membership;
bool success = hiddenapi::ApiList::FromNames(values.begin() + 1, values.end(), &membership);
- CHECK(success) << "Unknown ApiList flag: " << str;
- CHECK(membership.IsValid()) << "Invalid ApiList: " << membership;
+ if (!success) {
+ LOG(ERROR) << "Unknown ApiList flag: " << str;
+ errors = true;
+ continue;
+ } else if (!membership.IsValid()) {
+ LOG(ERROR) << "Invalid ApiList: " << membership;
+ errors = true;
+ continue;
+ }
AddSignatureToApiList(signature, membership);
size_t pos = signature.find("->");
@@ -55,6 +63,7 @@ HiddenApi::HiddenApi(const char* filename, const ApiListFilter& api_list_filter)
}
}
}
+ CHECK(!errors) << "Errors encountered while parsing file " << filename;
}
void HiddenApi::AddSignatureToApiList(const std::string& signature, hiddenapi::ApiList membership) {
diff --git a/tools/veridex/veridex.cc b/tools/veridex/veridex.cc
index ae1c33e1d2..d2a32e6db1 100644
--- a/tools/veridex/veridex.cc
+++ b/tools/veridex/veridex.cc
@@ -19,6 +19,10 @@
#include <android-base/file.h>
#include <android-base/strings.h>
+#include <cstdlib>
+#include <sstream>
+
+#include "base/mem_map.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "hidden_api.h"
@@ -26,9 +30,6 @@
#include "precise_hidden_api_finder.h"
#include "resolver.h"
-#include <cstdlib>
-#include <sstream>
-
namespace art {
static VeriClass z_(Primitive::Type::kPrimBoolean, 0, nullptr);
@@ -296,23 +297,18 @@ class Veridex {
}
// TODO: once added, use an api to android::base to read a std::vector<uint8_t>.
- if (!android::base::ReadFileToString(filename.c_str(), &content)) {
+ if (!android::base::ReadFileToString(filename, &content)) {
*error_msg = "ReadFileToString failed for " + filename;
return false;
}
- const DexFileLoader dex_file_loader;
DexFileLoaderErrorCode error_code;
static constexpr bool kVerifyChecksum = true;
static constexpr bool kRunDexFileVerifier = true;
- if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
- content.size(),
- filename.c_str(),
- kRunDexFileVerifier,
- kVerifyChecksum,
- &error_code,
- error_msg,
- dex_files)) {
+ DexFileLoader dex_file_loader(
+ reinterpret_cast<const uint8_t*>(content.data()), content.size(), filename);
+ if (!dex_file_loader.Open(
+ kRunDexFileVerifier, kVerifyChecksum, &error_code, error_msg, dex_files)) {
if (error_code == DexFileLoaderErrorCode::kEntryNotFound) {
LOG(INFO) << "No .dex found, skipping analysis.";
return true;
@@ -343,5 +339,6 @@ class Veridex {
} // namespace art
int main(int argc, char** argv) {
+ art::MemMap::Init();
return art::Veridex::Run(argc, argv);
}