diff options
38 files changed, 818 insertions, 390 deletions
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc index f4760d661f..2e31d35584 100644 --- a/compiler/optimizing/code_sinking.cc +++ b/compiler/optimizing/code_sinking.cc @@ -214,6 +214,11 @@ static HInstruction* FindIdealPosition(HInstruction* instruction, DCHECK(target_block != nullptr); } + // Bail if the instruction can throw and we are about to move into a catch block. + if (instruction->CanThrow() && target_block->GetTryCatchInformation() != nullptr) { + return nullptr; + } + // Find insertion position. No need to filter anymore, as we have found a // target block. HInstruction* insert_pos = nullptr; diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index 5e9782aadf..0cd39ac11b 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -2046,4 +2046,51 @@ TEST_F(Dex2oatTest, CompactDexInvalidSource) { ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_; } +// Test that dex2oat with a CompactDex file in the APK fails. +TEST_F(Dex2oatTest, CompactDexInZip) { + CompactDexFile::Header header = {}; + CompactDexFile::WriteMagic(header.magic_); + CompactDexFile::WriteCurrentVersion(header.magic_); + header.file_size_ = sizeof(CompactDexFile::Header); + header.data_off_ = 10 * MB; + header.map_off_ = 10 * MB; + header.class_defs_off_ = 10 * MB; + header.class_defs_size_ = 10000; + // Create a zip containing the invalid dex. + ScratchFile invalid_dex_zip; + { + FILE* file = fdopen(invalid_dex_zip.GetFd(), "w+b"); + ZipWriter writer(file); + writer.StartEntry("classes.dex", ZipWriter::kCompress); + ASSERT_GE(writer.WriteBytes(&header, sizeof(header)), 0); + writer.FinishEntry(); + writer.Finish(); + ASSERT_EQ(invalid_dex_zip.GetFile()->Flush(), 0); + } + // Create the dex file directly. + ScratchFile invalid_dex; + { + ASSERT_GE(invalid_dex.GetFile()->WriteFully(&header, sizeof(header)), 0); + ASSERT_EQ(invalid_dex.GetFile()->Flush(), 0); + } + std::string error_msg; + int status = 0u; + + status = GenerateOdexForTestWithStatus( + { invalid_dex_zip.GetFilename() }, + GetOdexDir() + "/output_apk.odex", + CompilerFilter::kQuicken, + &error_msg, + { "--compact-dex-level=fast" }); + ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_; + + status = GenerateOdexForTestWithStatus( + { invalid_dex.GetFilename() }, + GetOdexDir() + "/output.odex", + CompilerFilter::kQuicken, + &error_msg, + { "--compact-dex-level=fast" }); + ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) != 0) << status << " " << output_; +} + } // namespace art diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc index 373944f179..b96374d43a 100644 --- a/openjdkjvmti/ti_stack.cc +++ b/openjdkjvmti/ti_stack.cc @@ -484,7 +484,7 @@ jvmtiError StackUtil::GetThreadListStackTraces(jvmtiEnv* env, *stack_info_ptr = nullptr; return ERR(NONE); } - if (stack_info_ptr == nullptr || stack_info_ptr == nullptr) { + if (thread_list == nullptr || stack_info_ptr == nullptr) { return ERR(NULL_POINTER); } @@ -971,7 +971,7 @@ jvmtiError StackUtil::GetOwnedMonitorInfo(jvmtiEnv* env, jthread thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) { - if (owned_monitors_ptr == nullptr || owned_monitors_ptr == nullptr) { + if (owned_monitor_count_ptr == nullptr || owned_monitors_ptr == nullptr) { return ERR(NULL_POINTER); } auto handle_fun = [&] (art::ScopedObjectAccess& soa, MonitorVisitor& visitor) diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 8a29ff33b7..1d72b46f6c 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -5863,14 +5863,6 @@ bool ClassLinker::LinkVirtualMethods( // smaller as we go on. uint32_t hash_index = hash_table.FindAndRemove(&super_method_name_comparator); if (hash_index != hash_table.GetNotFoundIndex()) { - // Run a check whether we are going to override a method which is hidden - // to `klass`, but ignore the result as we only warn at the moment. - // We cannot do this test earlier because we need to establish that - // a method is being overridden first. ShouldBlockAccessToMember would - // print bogus warnings otherwise. - hiddenapi::ShouldBlockAccessToMember( - super_method, klass->GetClassLoader(), hiddenapi::kOverride); - ArtMethod* virtual_method = klass->GetVirtualMethodDuringLinking( hash_index, image_pointer_size_); if (super_method->IsFinal()) { diff --git a/runtime/dex/art_dex_file_loader.cc b/runtime/dex/art_dex_file_loader.cc index c456764834..9802c6904b 100644 --- a/runtime/dex/art_dex_file_loader.cc +++ b/runtime/dex/art_dex_file_loader.cc @@ -205,6 +205,12 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& locatio error_msg, std::make_unique<MemMapContainer>(std::move(map)), /*verify_result*/ nullptr); + // Opening CompactDex is only supported from vdex files. + if (dex_file != nullptr && dex_file->IsCompactDexFile()) { + *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files", + location.c_str()); + return nullptr; + } return dex_file; } @@ -329,6 +335,12 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd, std::make_unique<MemMapContainer>(std::move(map)), /*verify_result*/ nullptr); + // Opening CompactDex is only supported from vdex files. + if (dex_file != nullptr && dex_file->IsCompactDexFile()) { + *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files", + location.c_str()); + return nullptr; + } return dex_file; } @@ -397,6 +409,11 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenOneDexFileFromZip( error_msg, std::make_unique<MemMapContainer>(std::move(map)), &verify_result); + if (dex_file != nullptr && dex_file->IsCompactDexFile()) { + *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files", + location.c_str()); + return nullptr; + } if (dex_file == nullptr) { if (verify_result == VerifyResult::kVerifyNotAttempted) { *error_code = ZipOpenErrorCode::kDexFileError; diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h index f2ea2fdaaa..5c6b4b56bc 100644 --- a/runtime/hidden_api.h +++ b/runtime/hidden_api.h @@ -27,6 +27,23 @@ namespace art { namespace hiddenapi { +// Hidden API enforcement policy +// This must be kept in sync with ApplicationInfo.ApiEnforcementPolicy in +// frameworks/base/core/java/android/content/pm/ApplicationInfo.java +enum class EnforcementPolicy { + kNoChecks = 0, + kAllLists = 1, // ban anything but whitelist + kDarkGreyAndBlackList = 2, // ban dark grey & blacklist + kBlacklistOnly = 3, // ban blacklist violations only + kMax = kBlacklistOnly, +}; + +inline EnforcementPolicy EnforcementPolicyFromInt(int api_policy_int) { + DCHECK_GE(api_policy_int, 0); + DCHECK_LE(api_policy_int, static_cast<int>(EnforcementPolicy::kMax)); + return static_cast<EnforcementPolicy>(api_policy_int); +} + enum Action { kAllow, kAllowButWarn, @@ -38,7 +55,6 @@ enum AccessMethod { kReflection, kJNI, kLinking, - kOverride, }; inline std::ostream& operator<<(std::ostream& os, AccessMethod value) { @@ -52,23 +68,42 @@ inline std::ostream& operator<<(std::ostream& os, AccessMethod value) { case kLinking: os << "linking"; break; - case kOverride: - os << "override"; - break; } return os; } +static constexpr bool EnumsEqual(EnforcementPolicy policy, HiddenApiAccessFlags::ApiList apiList) { + return static_cast<int>(policy) == static_cast<int>(apiList); +} + inline Action GetMemberAction(uint32_t access_flags) { - switch (HiddenApiAccessFlags::DecodeFromRuntime(access_flags)) { - case HiddenApiAccessFlags::kWhitelist: - return kAllow; - case HiddenApiAccessFlags::kLightGreylist: - return kAllowButWarn; - case HiddenApiAccessFlags::kDarkGreylist: - return kAllowButWarnAndToast; - case HiddenApiAccessFlags::kBlacklist: - return kDeny; + EnforcementPolicy policy = Runtime::Current()->GetHiddenApiEnforcementPolicy(); + if (policy == EnforcementPolicy::kNoChecks) { + // Exit early. Nothing to enforce. + return kAllow; + } + + HiddenApiAccessFlags::ApiList api_list = HiddenApiAccessFlags::DecodeFromRuntime(access_flags); + if (api_list == HiddenApiAccessFlags::kWhitelist) { + return kAllow; + } + // The logic below relies on equality of values in the enums EnforcementPolicy and + // HiddenApiAccessFlags::ApiList, and their ordering. Assert that this is as expected. + static_assert( + EnumsEqual(EnforcementPolicy::kAllLists, HiddenApiAccessFlags::kLightGreylist) && + EnumsEqual(EnforcementPolicy::kDarkGreyAndBlackList, HiddenApiAccessFlags::kDarkGreylist) && + EnumsEqual(EnforcementPolicy::kBlacklistOnly, HiddenApiAccessFlags::kBlacklist), + "Mismatch between EnforcementPolicy and ApiList enums"); + static_assert( + EnforcementPolicy::kAllLists < EnforcementPolicy::kDarkGreyAndBlackList && + EnforcementPolicy::kDarkGreyAndBlackList < EnforcementPolicy::kBlacklistOnly, + "EnforcementPolicy values ordering not correct"); + if (static_cast<int>(policy) > static_cast<int>(api_list)) { + return api_list == HiddenApiAccessFlags::kDarkGreylist + ? kAllowButWarnAndToast + : kAllowButWarn; + } else { + return kDeny; } } @@ -107,12 +142,6 @@ inline bool ShouldBlockAccessToMember(T* member, AccessMethod access_method) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(member != nullptr); - Runtime* runtime = Runtime::Current(); - - if (!runtime->AreHiddenApiChecksEnabled()) { - // Exit early. Nothing to enforce. - return false; - } Action action = GetMemberAction(member->GetAccessFlags()); if (action == kAllow) { @@ -133,14 +162,16 @@ inline bool ShouldBlockAccessToMember(T* member, // We do this regardless of whether we block the access or not. WarnAboutMemberAccess(member, access_method); - // Block access if on blacklist. if (action == kDeny) { + // Block access return true; } // Allow access to this member but print a warning. DCHECK(action == kAllowButWarn || action == kAllowButWarnAndToast); + Runtime* runtime = Runtime::Current(); + // Depending on a runtime flag, we might move the member into whitelist and // skip the warning the next time the member is accessed. if (runtime->ShouldDedupeHiddenApiWarnings()) { @@ -150,7 +181,7 @@ inline bool ShouldBlockAccessToMember(T* member, // If this action requires a UI warning, set the appropriate flag. if (action == kAllowButWarnAndToast || runtime->ShouldAlwaysSetHiddenApiWarningFlag()) { - Runtime::Current()->SetPendingHiddenApiWarning(true); + runtime->SetPendingHiddenApiWarning(true); } return false; diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc index fc9426650e..3692a308d8 100644 --- a/runtime/native/dalvik_system_VMDebug.cc +++ b/runtime/native/dalvik_system_VMDebug.cc @@ -89,17 +89,27 @@ static void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) { static void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags, jboolean samplingEnabled, jint intervalUs) { - Trace::Start("[DDMS]", -1, bufferSize, flags, Trace::TraceOutputMode::kDDMS, - samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, - intervalUs); -} - -static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, - jint javaFd, jint bufferSize, jint flags, - jboolean samplingEnabled, jint intervalUs, + Trace::StartDDMS(bufferSize, + flags, + samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, + intervalUs); +} + +static void VMDebug_startMethodTracingFd(JNIEnv* env, + jclass, + jstring javaTraceFilename ATTRIBUTE_UNUSED, + jint javaFd, + jint bufferSize, + jint flags, + jboolean samplingEnabled, + jint intervalUs, jboolean streamingOutput) { int originalFd = javaFd; if (originalFd < 0) { + ScopedObjectAccess soa(env); + soa.Self()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", + "Trace fd is invalid: %d", + originalFd); return; } @@ -107,18 +117,20 @@ static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceF if (fd < 0) { ScopedObjectAccess soa(env); soa.Self()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", - "dup(%d) failed: %s", originalFd, strerror(errno)); + "dup(%d) failed: %s", + originalFd, + strerror(errno)); return; } - ScopedUtfChars traceFilename(env, javaTraceFilename); - if (traceFilename.c_str() == nullptr) { - return; - } + // Ignore the traceFilename. Trace::TraceOutputMode outputMode = streamingOutput ? Trace::TraceOutputMode::kStreaming : Trace::TraceOutputMode::kFile; - Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, outputMode, + Trace::Start(fd, + bufferSize, + flags, + outputMode, samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, intervalUs); } @@ -130,7 +142,10 @@ static void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring java if (traceFilename.c_str() == nullptr) { return; } - Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, Trace::TraceOutputMode::kFile, + Trace::Start(traceFilename.c_str(), + bufferSize, + flags, + Trace::TraceOutputMode::kFile, samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, intervalUs); } diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index 89135698e3..d9a5096331 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -162,19 +162,24 @@ static void CollectNonDebuggableClasses() REQUIRES(!Locks::mutator_lock_) { // Must match values in com.android.internal.os.Zygote. enum { - DEBUG_ENABLE_JDWP = 1, - DEBUG_ENABLE_CHECKJNI = 1 << 1, - DEBUG_ENABLE_ASSERT = 1 << 2, - DEBUG_ENABLE_SAFEMODE = 1 << 3, - DEBUG_ENABLE_JNI_LOGGING = 1 << 4, - DEBUG_GENERATE_DEBUG_INFO = 1 << 5, - DEBUG_ALWAYS_JIT = 1 << 6, - DEBUG_NATIVE_DEBUGGABLE = 1 << 7, - DEBUG_JAVA_DEBUGGABLE = 1 << 8, - DISABLE_VERIFIER = 1 << 9, - ONLY_USE_SYSTEM_OAT_FILES = 1 << 10, - ENABLE_HIDDEN_API_CHECKS = 1 << 11, - DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 12, + DEBUG_ENABLE_JDWP = 1, + DEBUG_ENABLE_CHECKJNI = 1 << 1, + DEBUG_ENABLE_ASSERT = 1 << 2, + DEBUG_ENABLE_SAFEMODE = 1 << 3, + DEBUG_ENABLE_JNI_LOGGING = 1 << 4, + DEBUG_GENERATE_DEBUG_INFO = 1 << 5, + DEBUG_ALWAYS_JIT = 1 << 6, + DEBUG_NATIVE_DEBUGGABLE = 1 << 7, + DEBUG_JAVA_DEBUGGABLE = 1 << 8, + DISABLE_VERIFIER = 1 << 9, + ONLY_USE_SYSTEM_OAT_FILES = 1 << 10, + DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 11, + HIDDEN_API_ENFORCEMENT_POLICY_MASK = (1 << 12) + | (1 << 13), + + // bits to shift (flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) by to get a value + // corresponding to hiddenapi::EnforcementPolicy + API_ENFORCEMENT_POLICY_SHIFT = CTZ(HIDDEN_API_ENFORCEMENT_POLICY_MASK), }; static uint32_t EnableDebugFeatures(uint32_t runtime_flags) { @@ -285,7 +290,8 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, // Our system thread ID, etc, has changed so reset Thread state. thread->InitAfterFork(); runtime_flags = EnableDebugFeatures(runtime_flags); - bool do_hidden_api_checks = false; + hiddenapi::EnforcementPolicy api_enforcement_policy = hiddenapi::EnforcementPolicy::kNoChecks; + bool dedupe_hidden_api_warnings = true; if ((runtime_flags & DISABLE_VERIFIER) != 0) { Runtime::Current()->DisableVerifier(); @@ -297,10 +303,9 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, runtime_flags &= ~ONLY_USE_SYSTEM_OAT_FILES; } - if ((runtime_flags & ENABLE_HIDDEN_API_CHECKS) != 0) { - do_hidden_api_checks = true; - runtime_flags &= ~ENABLE_HIDDEN_API_CHECKS; - } + api_enforcement_policy = hiddenapi::EnforcementPolicyFromInt( + (runtime_flags & HIDDEN_API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT); + runtime_flags &= ~HIDDEN_API_ENFORCEMENT_POLICY_MASK; if (runtime_flags != 0) { LOG(ERROR) << StringPrintf("Unknown bits set in runtime_flags: %#x", runtime_flags); @@ -338,7 +343,6 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, std::string trace_file = StringPrintf("/data/misc/trace/%s.trace.bin", proc_name.c_str()); Trace::Start(trace_file.c_str(), - -1, buffer_size, 0, // TODO: Expose flags. output_mode, @@ -351,11 +355,13 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, } } + bool do_hidden_api_checks = api_enforcement_policy != hiddenapi::EnforcementPolicy::kNoChecks; DCHECK(!(is_system_server && do_hidden_api_checks)) - << "SystemServer should be forked with ENABLE_HIDDEN_API_CHECKS"; + << "SystemServer should be forked with EnforcementPolicy::kDisable"; DCHECK(!(is_zygote && do_hidden_api_checks)) - << "Child zygote processes should be forked with ENABLE_HIDDEN_API_CHECKS"; - Runtime::Current()->SetHiddenApiChecksEnabled(do_hidden_api_checks); + << "Child zygote processes should be forked with EnforcementPolicy::kDisable"; + Runtime::Current()->SetHiddenApiEnforcementPolicy(api_enforcement_policy); + Runtime::Current()->SetDedupeHiddenApiWarnings(dedupe_hidden_api_warnings); // Clear the hidden API warning flag, in case it was set. Runtime::Current()->SetPendingHiddenApiWarning(false); diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 25d50376de..fc61c9597e 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -89,8 +89,8 @@ static bool IsCallerInBootClassPath(Thread* self) REQUIRES_SHARED(Locks::mutator // access hidden APIs. This can be *very* expensive. Never call this in a loop. ALWAYS_INLINE static bool ShouldEnforceHiddenApi(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - return Runtime::Current()->AreHiddenApiChecksEnabled() && - !IsCallerInBootClassPath(self); + hiddenapi::EnforcementPolicy policy = Runtime::Current()->GetHiddenApiEnforcementPolicy(); + return policy != hiddenapi::EnforcementPolicy::kNoChecks && !IsCallerInBootClassPath(self); } // Returns true if the first non-ClassClass caller up the stack should not be diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 7d9d3426fc..9a626bab00 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -267,7 +267,7 @@ Runtime::Runtime() oat_file_manager_(nullptr), is_low_memory_mode_(false), safe_mode_(false), - do_hidden_api_checks_(false), + hidden_api_policy_(hiddenapi::EnforcementPolicy::kNoChecks), pending_hidden_api_warning_(false), dedupe_hidden_api_warnings_(true), always_set_hidden_api_warning_flag_(false), @@ -839,7 +839,6 @@ bool Runtime::Start() { if (trace_config_.get() != nullptr && trace_config_->trace_file != "") { ScopedThreadStateChange tsc(self, kWaitingForMethodTracingStart); Trace::Start(trace_config_->trace_file.c_str(), - -1, static_cast<int>(trace_config_->trace_file_size), 0, trace_config_->trace_output_mode, @@ -1196,9 +1195,14 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { // by default and we only enable them if: // (a) runtime was started with a flag that enables the checks, or // (b) Zygote forked a new process that is not exempt (see ZygoteHooks). - do_hidden_api_checks_ = runtime_options.Exists(Opt::HiddenApiChecks); - DCHECK(!is_zygote_ || !do_hidden_api_checks_) - << "Zygote should not be started with hidden API checks"; + bool do_hidden_api_checks = runtime_options.Exists(Opt::HiddenApiChecks); + DCHECK(!is_zygote_ || !do_hidden_api_checks); + // TODO pass the actual enforcement policy in, rather than just a single bit. + // As is, we're encoding some logic here about which specific policy to use, which would be better + // controlled by the framework. + hidden_api_policy_ = do_hidden_api_checks + ? hiddenapi::EnforcementPolicy::kBlacklistOnly + : hiddenapi::EnforcementPolicy::kNoChecks; no_sig_chain_ = runtime_options.Exists(Opt::NoSigChain); force_native_bridge_ = runtime_options.Exists(Opt::ForceNativeBridge); diff --git a/runtime/runtime.h b/runtime/runtime.h index c7f650ea3f..dba31b2939 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -49,6 +49,10 @@ class AbstractSystemWeakHolder; class Heap; } // namespace gc +namespace hiddenapi { +enum class EnforcementPolicy; +} // namespace hiddenapi + namespace jit { class Jit; class JitOptions; @@ -520,12 +524,12 @@ class Runtime { bool IsVerificationEnabled() const; bool IsVerificationSoftFail() const; - void SetHiddenApiChecksEnabled(bool value) { - do_hidden_api_checks_ = value; + void SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy policy) { + hidden_api_policy_ = policy; } - bool AreHiddenApiChecksEnabled() const { - return do_hidden_api_checks_; + hiddenapi::EnforcementPolicy GetHiddenApiEnforcementPolicy() const { + return hidden_api_policy_; } void SetPendingHiddenApiWarning(bool value) { @@ -990,7 +994,7 @@ class Runtime { bool safe_mode_; // Whether access checks on hidden API should be performed. - bool do_hidden_api_checks_; + hiddenapi::EnforcementPolicy hidden_api_policy_; // Whether the application has used an API which is not restricted but we // should issue a warning about it. diff --git a/runtime/trace.cc b/runtime/trace.cc index 0f321b6591..91d2b3779e 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -319,8 +319,74 @@ void* Trace::RunSamplingThread(void* arg) { return nullptr; } -void Trace::Start(const char* trace_filename, int trace_fd, size_t buffer_size, int flags, - TraceOutputMode output_mode, TraceMode trace_mode, int interval_us) { +void Trace::Start(const char* trace_filename, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode, + int interval_us) { + std::unique_ptr<File> file(OS::CreateEmptyFileWriteOnly(trace_filename)); + if (file == nullptr) { + std::string msg = android::base::StringPrintf("Unable to open trace file '%s'", trace_filename); + PLOG(ERROR) << msg; + ScopedObjectAccess soa(Thread::Current()); + Thread::Current()->ThrowNewException("Ljava/lang/RuntimeException;", msg.c_str()); + return; + } + Start(std::move(file), buffer_size, flags, output_mode, trace_mode, interval_us); +} + +void Trace::Start(int trace_fd, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode, + int interval_us) { + if (trace_fd < 0) { + std::string msg = android::base::StringPrintf("Unable to start tracing with invalid fd %d", + trace_fd); + LOG(ERROR) << msg; + ScopedObjectAccess soa(Thread::Current()); + Thread::Current()->ThrowNewException("Ljava/lang/RuntimeException;", msg.c_str()); + return; + } + std::unique_ptr<File> file(new File(trace_fd, "tracefile")); + Start(std::move(file), buffer_size, flags, output_mode, trace_mode, interval_us); +} + +void Trace::StartDDMS(size_t buffer_size, + int flags, + TraceMode trace_mode, + int interval_us) { + Start(std::unique_ptr<File>(), + buffer_size, + flags, + TraceOutputMode::kDDMS, + trace_mode, + interval_us); +} + +void Trace::Start(std::unique_ptr<File>&& trace_file_in, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode, + int interval_us) { + // We own trace_file now and are responsible for closing it. To account for error situations, use + // a specialized unique_ptr to ensure we close it on the way out (if it hasn't been passed to a + // Trace instance). + auto deleter = [](File* file) { + if (file != nullptr) { + file->MarkUnchecked(); // Don't deal with flushing requirements. + int result ATTRIBUTE_UNUSED = file->Close(); + delete file; + } + }; + std::unique_ptr<File, decltype(deleter)> trace_file(trace_file_in.release(), deleter); + if (trace_file != nullptr) { + trace_file->DisableAutoClose(); + } + Thread* self = Thread::Current(); { MutexLock mu(self, *Locks::trace_lock_); @@ -338,23 +404,6 @@ void Trace::Start(const char* trace_filename, int trace_fd, size_t buffer_size, return; } - // Open trace file if not going directly to ddms. - std::unique_ptr<File> trace_file; - if (output_mode != TraceOutputMode::kDDMS) { - if (trace_fd < 0) { - trace_file.reset(OS::CreateEmptyFileWriteOnly(trace_filename)); - } else { - trace_file.reset(new File(trace_fd, "tracefile")); - trace_file->DisableAutoClose(); - } - if (trace_file.get() == nullptr) { - PLOG(ERROR) << "Unable to open trace file '" << trace_filename << "'"; - ScopedObjectAccess soa(self); - ThrowRuntimeException("Unable to open trace file '%s'", trace_filename); - return; - } - } - Runtime* runtime = Runtime::Current(); // Enable count of allocs if specified in the flags. @@ -372,8 +421,7 @@ void Trace::Start(const char* trace_filename, int trace_fd, size_t buffer_size, LOG(ERROR) << "Trace already in progress, ignoring this request"; } else { enable_stats = (flags && kTraceCountAllocs) != 0; - the_trace_ = new Trace(trace_file.release(), trace_filename, buffer_size, flags, output_mode, - trace_mode); + the_trace_ = new Trace(trace_file.release(), buffer_size, flags, output_mode, trace_mode); if (trace_mode == TraceMode::kSampling) { CHECK_PTHREAD_CALL(pthread_create, (&sampling_pthread_, nullptr, &RunSamplingThread, reinterpret_cast<void*>(interval_us)), @@ -595,8 +643,11 @@ TracingMode Trace::GetMethodTracingMode() { static constexpr size_t kMinBufSize = 18U; // Trace header is up to 18B. -Trace::Trace(File* trace_file, const char* trace_name, size_t buffer_size, int flags, - TraceOutputMode output_mode, TraceMode trace_mode) +Trace::Trace(File* trace_file, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode) : trace_file_(trace_file), buf_(new uint8_t[std::max(kMinBufSize, buffer_size)]()), flags_(flags), trace_output_mode_(output_mode), trace_mode_(trace_mode), @@ -605,6 +656,8 @@ Trace::Trace(File* trace_file, const char* trace_name, size_t buffer_size, int f start_time_(MicroTime()), clock_overhead_ns_(GetClockOverheadNanoSeconds()), cur_offset_(0), overflow_(false), interval_us_(0), streaming_lock_(nullptr), unique_methods_lock_(new Mutex("unique methods lock", kTracingUniqueMethodsLock)) { + CHECK(trace_file != nullptr || output_mode == TraceOutputMode::kDDMS); + uint16_t trace_version = GetTraceVersion(clock_source_); if (output_mode == TraceOutputMode::kStreaming) { trace_version |= 0xF0U; @@ -625,7 +678,6 @@ Trace::Trace(File* trace_file, const char* trace_name, size_t buffer_size, int f cur_offset_.StoreRelaxed(kTraceHeaderLength); if (output_mode == TraceOutputMode::kStreaming) { - streaming_file_name_ = trace_name; streaming_lock_ = new Mutex("tracing lock", LockLevel::kTracingStreamingLock); seen_threads_.reset(new ThreadIDBitSet()); } diff --git a/runtime/trace.h b/runtime/trace.h index 86b8d00d51..7171f759c9 100644 --- a/runtime/trace.h +++ b/runtime/trace.h @@ -33,6 +33,10 @@ #include "globals.h" #include "instrumentation.h" +namespace unix_file { +class FdFile; +} // namespace unix_file + namespace art { class ArtField; @@ -115,10 +119,37 @@ class Trace FINAL : public instrumentation::InstrumentationListener { static void SetDefaultClockSource(TraceClockSource clock_source); - static void Start(const char* trace_filename, int trace_fd, size_t buffer_size, int flags, - TraceOutputMode output_mode, TraceMode trace_mode, int interval_us) + static void Start(const char* trace_filename, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode, + int interval_us) + REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, + !Locks::trace_lock_); + static void Start(int trace_fd, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode, + int interval_us) + REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, + !Locks::trace_lock_); + static void Start(std::unique_ptr<unix_file::FdFile>&& file, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode, + int interval_us) + REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, + !Locks::trace_lock_); + static void StartDDMS(size_t buffer_size, + int flags, + TraceMode trace_mode, + int interval_us) REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, !Locks::trace_lock_); + static void Pause() REQUIRES(!Locks::trace_lock_, !Locks::thread_list_lock_); static void Resume() REQUIRES(!Locks::trace_lock_); @@ -212,8 +243,11 @@ class Trace FINAL : public instrumentation::InstrumentationListener { static bool IsTracingEnabled() REQUIRES(!Locks::trace_lock_); private: - Trace(File* trace_file, const char* trace_name, size_t buffer_size, int flags, - TraceOutputMode output_mode, TraceMode trace_mode); + Trace(File* trace_file, + size_t buffer_size, + int flags, + TraceOutputMode output_mode, + TraceMode trace_mode); // The sampling interval in microseconds is passed as an argument. static void* RunSamplingThread(void* arg) REQUIRES(!Locks::trace_lock_); @@ -318,7 +352,6 @@ class Trace FINAL : public instrumentation::InstrumentationListener { int interval_us_; // Streaming mode data. - std::string streaming_file_name_; Mutex* streaming_lock_; std::map<const DexFile*, DexIndexBitSet*> seen_methods_; std::unique_ptr<ThreadIDBitSet> seen_threads_; diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 67ea64be74..bf36ccf0fa 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -24,6 +24,7 @@ #include <android-base/stringprintf.h> #include "entrypoints/quick/quick_entrypoints_enum.h" +#include "hidden_api.h" #include "jni_internal.h" #include "mirror/class.h" #include "mirror/throwable.h" @@ -287,17 +288,17 @@ class ScopedHiddenApiExemption { public: explicit ScopedHiddenApiExemption(Runtime* runtime) : runtime_(runtime), - initially_enabled_(runtime_->AreHiddenApiChecksEnabled()) { - runtime_->SetHiddenApiChecksEnabled(false); + initial_policy_(runtime_->GetHiddenApiEnforcementPolicy()) { + runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kNoChecks); } ~ScopedHiddenApiExemption() { - runtime_->SetHiddenApiChecksEnabled(initially_enabled_); + runtime_->SetHiddenApiEnforcementPolicy(initial_policy_); } private: Runtime* runtime_; - const bool initially_enabled_; + const hiddenapi::EnforcementPolicy initial_policy_; DISALLOW_COPY_AND_ASSIGN(ScopedHiddenApiExemption); }; diff --git a/test/121-modifiers/classes/A$B.class b/test/121-modifiers/classes/A$B.class Binary files differdeleted file mode 100644 index bd7ebfe11d..0000000000 --- a/test/121-modifiers/classes/A$B.class +++ /dev/null diff --git a/test/121-modifiers/classes/A$C.class b/test/121-modifiers/classes/A$C.class Binary files differdeleted file mode 100644 index 3ae872e356..0000000000 --- a/test/121-modifiers/classes/A$C.class +++ /dev/null diff --git a/test/121-modifiers/classes/A.class b/test/121-modifiers/classes/A.class Binary files differdeleted file mode 100644 index d89d029796..0000000000 --- a/test/121-modifiers/classes/A.class +++ /dev/null diff --git a/test/121-modifiers/classes/Inf.class b/test/121-modifiers/classes/Inf.class Binary files differdeleted file mode 100644 index e8dd68029d..0000000000 --- a/test/121-modifiers/classes/Inf.class +++ /dev/null diff --git a/test/121-modifiers/classes/Main.class b/test/121-modifiers/classes/Main.class Binary files differdeleted file mode 100644 index e044074269..0000000000 --- a/test/121-modifiers/classes/Main.class +++ /dev/null diff --git a/test/121-modifiers/classes/NonInf.class b/test/121-modifiers/classes/NonInf.class Binary files differdeleted file mode 100644 index 0f1e826fb7..0000000000 --- a/test/121-modifiers/classes/NonInf.class +++ /dev/null diff --git a/test/121-modifiers/info.txt b/test/121-modifiers/info.txt index 335df53f3d..7dba1133d1 100644 --- a/test/121-modifiers/info.txt +++ b/test/121-modifiers/info.txt @@ -10,9 +10,9 @@ Finally, compile with jack/jill or dx, and run baksmali. javac Inf.java NonInf.java Main.java javac -cp asm.jar:asm-tree.jar:. Asm.java java -cp asm.jar:asm-tree.jar:. Asm -mv Inf.out classes/Inf.class -mv NonInf.out classes/NonInf.class -mv Main.class A.class A\$B.class A\$C.class classes/ +mv Inf.out classes_tmp/Inf.class +mv NonInf.out classes_tmp/NonInf.class +mv Main.class A.class A\$B.class A\$C.class classes_tmp/ dx --debug --dex --output=classes.dex classes baksmali disassemble classes.dex mv out/*.smali smali/ diff --git a/test/161-final-abstract-class/smali/Main.smali b/test/161-final-abstract-class/smali/Main.smali new file mode 100644 index 0000000000..588854cf52 --- /dev/null +++ b/test/161-final-abstract-class/smali/Main.smali @@ -0,0 +1,214 @@ +# Created with baksmali. + +# Java file for reference. + +# import java.lang.reflect.InvocationTargetException; +# import java.lang.reflect.Method; +# +# public class Main { +# public static void main(String[] args) { +# try { +# // Make sure that the abstract final class is marked as erroneous. +# Class.forName("AbstractFinal"); +# System.out.println("UNREACHABLE!"); +# } catch (VerifyError expected) { +# } catch (Throwable t) { +# t.printStackTrace(System.out); +# } +# try { +# // Verification of TestClass.test() used to crash when processing +# // the final abstract (erroneous) class. +# Class<?> tc = Class.forName("TestClass"); +# Method test = tc.getDeclaredMethod("test"); +# test.invoke(null); +# System.out.println("UNREACHABLE!"); +# } catch (InvocationTargetException ite) { +# if (ite.getCause() instanceof InstantiationError) { +# System.out.println( +# ite.getCause().getClass().getName() + ": " + ite.getCause().getMessage()); +# } else { +# ite.printStackTrace(System.out); +# } +# } catch (Throwable t) { +# t.printStackTrace(System.out); +# } +# } +# } + +.class public LMain; +.super Ljava/lang/Object; +.source "Main.java" + + +# direct methods +.method public constructor <init>()V + .registers 1 + + .line 20 + invoke-direct {p0}, Ljava/lang/Object;-><init>()V + + return-void +.end method + +.method public static main([Ljava/lang/String;)V + .registers 4 + + .line 24 + :try_start_0 + const-string p0, "AbstractFinal" + + invoke-static {p0}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class; + + .line 25 + sget-object p0, Ljava/lang/System;->out:Ljava/io/PrintStream; + + const-string v0, "UNREACHABLE!" + + invoke-virtual {p0, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + :try_end_c + .catch Ljava/lang/VerifyError; {:try_start_0 .. :try_end_c} :catch_14 + .catch Ljava/lang/Throwable; {:try_start_0 .. :try_end_c} :catch_d + + goto :goto_15 + + .line 27 + :catch_d + move-exception p0 + + .line 28 + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + + invoke-virtual {p0, v0}, Ljava/lang/Throwable;->printStackTrace(Ljava/io/PrintStream;)V + + goto :goto_16 + + .line 26 + :catch_14 + move-exception p0 + + .line 29 + :goto_15 + nop + + .line 33 + :goto_16 + :try_start_16 + const-string p0, "TestClass" + + invoke-static {p0}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class; + + move-result-object p0 + + .line 34 + const-string v0, "test" + + const/4 v1, 0x0 + + new-array v2, v1, [Ljava/lang/Class; + + invoke-virtual {p0, v0, v2}, Ljava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method; + + move-result-object p0 + + .line 35 + const/4 v0, 0x0 + + new-array v1, v1, [Ljava/lang/Object; + + invoke-virtual {p0, v0, v1}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; + + .line 36 + sget-object p0, Ljava/lang/System;->out:Ljava/io/PrintStream; + + const-string v0, "UNREACHABLE!" + + invoke-virtual {p0, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + :try_end_32 + .catch Ljava/lang/reflect/InvocationTargetException; {:try_start_16 .. :try_end_32} :catch_3a + .catch Ljava/lang/Throwable; {:try_start_16 .. :try_end_32} :catch_33 + + goto :goto_76 + + .line 44 + :catch_33 + move-exception p0 + + .line 45 + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + + invoke-virtual {p0, v0}, Ljava/lang/Throwable;->printStackTrace(Ljava/io/PrintStream;)V + + goto :goto_77 + + .line 37 + :catch_3a + move-exception p0 + + .line 38 + invoke-virtual {p0}, Ljava/lang/reflect/InvocationTargetException;->getCause()Ljava/lang/Throwable; + + move-result-object v0 + + instance-of v0, v0, Ljava/lang/InstantiationError; + + if-eqz v0, :cond_71 + + .line 39 + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + + new-instance v1, Ljava/lang/StringBuilder; + + invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V + + .line 40 + invoke-virtual {p0}, Ljava/lang/reflect/InvocationTargetException;->getCause()Ljava/lang/Throwable; + + move-result-object v2 + + invoke-virtual {v2}, Ljava/lang/Object;->getClass()Ljava/lang/Class; + + move-result-object v2 + + invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String; + + move-result-object v2 + + invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; + + const-string v2, ": " + + invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; + + invoke-virtual {p0}, Ljava/lang/reflect/InvocationTargetException;->getCause()Ljava/lang/Throwable; + + move-result-object p0 + + invoke-virtual {p0}, Ljava/lang/Throwable;->getMessage()Ljava/lang/String; + + move-result-object p0 + + invoke-virtual {v1, p0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; + + invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; + + move-result-object p0 + + .line 39 + invoke-virtual {v0, p0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + + goto :goto_76 + + .line 42 + :cond_71 + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + + invoke-virtual {p0, v0}, Ljava/lang/reflect/InvocationTargetException;->printStackTrace(Ljava/io/PrintStream;)V + + .line 46 + :goto_76 + nop + + .line 47 + :goto_77 + return-void +.end method diff --git a/test/161-final-abstract-class/src/Main.java b/test/161-final-abstract-class/src/Main.java deleted file mode 100644 index 2452490226..0000000000 --- a/test/161-final-abstract-class/src/Main.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 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 java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class Main { - public static void main(String[] args) { - try { - // Make sure that the abstract final class is marked as erroneous. - Class.forName("AbstractFinal"); - System.out.println("UNREACHABLE!"); - } catch (VerifyError expected) { - } catch (Throwable t) { - t.printStackTrace(System.out); - } - try { - // Verification of TestClass.test() used to crash when processing - // the final abstract (erroneous) class. - Class<?> tc = Class.forName("TestClass"); - Method test = tc.getDeclaredMethod("test"); - test.invoke(null); - System.out.println("UNREACHABLE!"); - } catch (InvocationTargetException ite) { - if (ite.getCause() instanceof InstantiationError) { - System.out.println( - ite.getCause().getClass().getName() + ": " + ite.getCause().getMessage()); - } else { - ite.printStackTrace(System.out); - } - } catch (Throwable t) { - t.printStackTrace(System.out); - } - } -} diff --git a/test/1929-exception-catch-exception/expected.txt b/test/1929-exception-catch-exception/expected.txt index bc5608ac4e..a82b732eda 100644 --- a/test/1929-exception-catch-exception/expected.txt +++ b/test/1929-exception-catch-exception/expected.txt @@ -1,11 +1,11 @@ Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$DoNothingHandler" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: doThrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$DoNothingHandler" @@ -17,71 +17,71 @@ main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Doing nothing! Caught art.Test1929$TestException: "throwCatchBaseTestException" Test "art.Test1929$DoThrowCatchBaseTestException": No error caught with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$DoNothingHandler" -main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 - public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197 - public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 + public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 203 + public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 210 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$DoNothingHandler" -main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException +main: public static void art.Test1929.throwCatchTestException() @ line = 216 caught class art.Test1929$TestException: throwCatchTestException Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.throwCatchTestException() @ line = 207 - public void art.Test1929$DoThrowCatchTestException.run() @ line = 216 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.throwCatchTestException() @ line = 216 + public void art.Test1929$DoThrowCatchTestException.run() @ line = 225 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Doing nothing! Caught art.Test1929$TestException: "throwCatchTestException" Test "art.Test1929$DoThrowCatchTestException": No error caught with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$DoNothingHandler" -main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 caught class art.Test1929$TestException: throwCatchTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 - public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222 - public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 + public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 234 + public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 241 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchTestExceptionTwice" Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$DoNothingHandler" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$DoNothingHandler" Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$ThrowCatchBase" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: doThrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$ThrowCatchBase" @@ -93,73 +93,73 @@ main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Throwing BaseTestException and catching it! Caught art.Test1929$BaseTestException: "ThrowBaseHandler during throw from public static void art.Test1929.throwCatchBaseTestException() @ line = 140" Caught art.Test1929$TestException: "throwCatchBaseTestException" Test "art.Test1929$DoThrowCatchBaseTestException": No error caught with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowCatchBase" -main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 - public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197 - public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 + public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 203 + public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 210 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$ThrowCatchBase" -main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException +main: public static void art.Test1929.throwCatchTestException() @ line = 216 caught class art.Test1929$TestException: throwCatchTestException Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.throwCatchTestException() @ line = 207 - public void art.Test1929$DoThrowCatchTestException.run() @ line = 216 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.throwCatchTestException() @ line = 216 + public void art.Test1929$DoThrowCatchTestException.run() @ line = 225 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Throwing BaseTestException and catching it! -Caught art.Test1929$BaseTestException: "ThrowBaseHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 207" +Caught art.Test1929$BaseTestException: "ThrowBaseHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 216" Caught art.Test1929$TestException: "throwCatchTestException" Test "art.Test1929$DoThrowCatchTestException": No error caught with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowCatchBase" -main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 caught class art.Test1929$TestException: throwCatchTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 - public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222 - public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 + public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 234 + public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 241 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchTestExceptionTwice" Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$ThrowCatchBase" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$ThrowCatchBase" Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: doThrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler" @@ -171,69 +171,69 @@ main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Throwing BaseTestException! Test "art.Test1929$DoThrowCatchBaseTestException": Caught error art.Test1929$BaseTestException:"ThrowBaseHandler during throw from public static void art.Test1929.throwCatchBaseTestException() @ line = 140" with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler" -main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 - public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197 - public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 + public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 203 + public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 210 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler" -main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException +main: public static void art.Test1929.throwCatchTestException() @ line = 216 caught class art.Test1929$TestException: throwCatchTestException Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.throwCatchTestException() @ line = 207 - public void art.Test1929$DoThrowCatchTestException.run() @ line = 216 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.throwCatchTestException() @ line = 216 + public void art.Test1929$DoThrowCatchTestException.run() @ line = 225 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Throwing BaseTestException! -Test "art.Test1929$DoThrowCatchTestException": Caught error art.Test1929$BaseTestException:"ThrowBaseHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 207" with handler "art.Test1929$ThrowBaseTestExceptionHandler" +Test "art.Test1929$DoThrowCatchTestException": Caught error art.Test1929$BaseTestException:"ThrowBaseHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 216" with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler" -main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 caught class art.Test1929$TestException: throwCatchTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 - public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222 - public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 + public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 234 + public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 241 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchTestExceptionTwice" Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler" Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: doThrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" @@ -245,58 +245,58 @@ main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 public static void art.Test1929.throwCatchBaseTestException() @ line = 140 public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Throwing TestExceptionNoRethrow! Test "art.Test1929$DoThrowCatchBaseTestException": Caught error art.Test1929$TestExceptionNoRethrow:"ThrowTestExceptionNoRethrowHandler during throw from public static void art.Test1929.throwCatchBaseTestException() @ line = 140" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" -main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 - public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197 - public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 157 + public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 203 + public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 210 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" -main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException +main: public static void art.Test1929.throwCatchTestException() @ line = 216 caught class art.Test1929$TestException: throwCatchTestException Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.throwCatchTestException() @ line = 207 - public void art.Test1929$DoThrowCatchTestException.run() @ line = 216 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929.throwCatchTestException() @ line = 216 + public void art.Test1929$DoThrowCatchTestException.run() @ line = 225 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Throwing TestExceptionNoRethrow! -Test "art.Test1929$DoThrowCatchTestException": Caught error art.Test1929$TestExceptionNoRethrow:"ThrowTestExceptionNoRethrowHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 207" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" +Test "art.Test1929$DoThrowCatchTestException": Caught error art.Test1929$TestExceptionNoRethrow:"ThrowTestExceptionNoRethrowHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 216" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" -main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice +main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 caught class art.Test1929$TestException: throwCatchTestExceptionTwice Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 - public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222 - public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226 - public static void art.Test1929.run() throws java.lang.Exception @ line = 280 + public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 175 + public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 234 + public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 241 + public static void art.Test1929.run() throws java.lang.Exception @ line = 295 Caught art.Test1929$TestException: "throwCatchTestExceptionTwice" Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" -main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow +main: public static void art.Test1929.run() throws java.lang.Exception @ line = 298 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow Current Stack: private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1 public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 61 private static void art.Test1929.PrintStack() @ line = 52 public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65 - public static void art.Test1929.run() throws java.lang.Exception @ line = 283 + public static void art.Test1929.run() throws java.lang.Exception @ line = 298 Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler" diff --git a/test/1929-exception-catch-exception/src/art/Test1929.java b/test/1929-exception-catch-exception/src/art/Test1929.java index 07d2087a0f..e2deb3f85f 100644 --- a/test/1929-exception-catch-exception/src/art/Test1929.java +++ b/test/1929-exception-catch-exception/src/art/Test1929.java @@ -152,49 +152,58 @@ public class Test1929 { // dx/d8/jack all do an optimization around catch blocks that (while legal) breaks assumptions // this test relies on so we have the actual implementation be corrected smali. This does work // for RI however. - public static final class Impl { - private Impl() {} - public static void throwCatchBaseTestExceptionTwiceImpl() { - try { - try { - throw new TestException("throwCatchBaseTestExceptionTwice"); - } catch (BaseTestException t) { - System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); - if (PRINT_FULL_EXCEPTION) { - t.printStackTrace(System.out); - } - } - } catch (BaseTestException t) { - System.out.println("2nd Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); - if (PRINT_FULL_EXCEPTION) { - t.printStackTrace(System.out); - } - } - } - public static void throwCatchTestExceptionTwiceImpl() { - try { - try { - throw new TestException("throwCatchTestExceptionTwice"); - } catch (TestException t) { - System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); - if (PRINT_FULL_EXCEPTION) { - t.printStackTrace(System.out); - } - } - } catch (TestException t) { - System.out.println("2nd Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); - if (PRINT_FULL_EXCEPTION) { - t.printStackTrace(System.out); - } - } - } - } + // For reference: + + // public static final class Impl { + // private Impl() {} + // public static void throwCatchBaseTestExceptionTwiceImpl() { + // try { + // try { + // throw new TestException("throwCatchBaseTestExceptionTwice"); + // } catch (BaseTestException t) { + // System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); + // if (PRINT_FULL_EXCEPTION) { + // t.printStackTrace(System.out); + // } + // } + // } catch (BaseTestException t) { + // System.out.println("2nd Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); + // if (PRINT_FULL_EXCEPTION) { + // t.printStackTrace(System.out); + // } + // } + // } + + // public static void throwCatchTestExceptionTwiceImpl() { + // try { + // try { + // throw new TestException("throwCatchTestExceptionTwice"); + // } catch (TestException t) { + // System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); + // if (PRINT_FULL_EXCEPTION) { + // t.printStackTrace(System.out); + // } + // } + // } catch (TestException t) { + // System.out.println("2nd Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); + // if (PRINT_FULL_EXCEPTION) { + // t.printStackTrace(System.out); + // } + // } + // } + // } public static void throwCatchBaseTestExceptionTwice() { // The implementation of this has to change depending upon the runtime slightly due to compiler // optimizations present in DX/D8/Jack. - Impl.throwCatchBaseTestExceptionTwiceImpl(); + try { + Class<?> Impl = Class.forName("art.Test1929$Impl"); + Method m = Impl.getMethod("throwCatchBaseTestExceptionTwiceImpl"); + m.invoke(null); + } catch (Exception e) { + e.printStackTrace(System.out); + } } public static class DoThrowCatchBaseTestExceptionTwice implements Runnable { @@ -219,7 +228,13 @@ public class Test1929 { public static void throwCatchTestExceptionTwice() { // The implementation of this has to change depending upon the runtime slightly due to compiler // optimizations present in DX/D8/Jack. - Impl.throwCatchTestExceptionTwiceImpl(); + try { + Class<?> Impl = Class.forName("art.Test1929$Impl"); + Method m = Impl.getMethod("throwCatchTestExceptionTwiceImpl"); + m.invoke(null); + } catch (Exception e) { + e.printStackTrace(System.out); + } } public static class DoThrowCatchTestExceptionTwice implements Runnable { diff --git a/test/674-hiddenapi/hiddenapi.cc b/test/674-hiddenapi/hiddenapi.cc index effa37ade4..04c3fbf03a 100644 --- a/test/674-hiddenapi/hiddenapi.cc +++ b/test/674-hiddenapi/hiddenapi.cc @@ -16,6 +16,7 @@ #include "class_linker.h" #include "dex/art_dex_file_loader.h" +#include "hidden_api.h" #include "jni.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" @@ -27,7 +28,7 @@ namespace Test674HiddenApi { extern "C" JNIEXPORT void JNICALL Java_Main_init(JNIEnv*, jclass) { Runtime* runtime = Runtime::Current(); - runtime->SetHiddenApiChecksEnabled(true); + runtime->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kBlacklistOnly); runtime->SetDedupeHiddenApiWarnings(false); runtime->AlwaysSetHiddenApiWarningFlag(); } diff --git a/test/674-hiddenapi/src-ex/ChildClass.java b/test/674-hiddenapi/src-ex/ChildClass.java index 8cd237ab6f..582e907ca3 100644 --- a/test/674-hiddenapi/src-ex/ChildClass.java +++ b/test/674-hiddenapi/src-ex/ChildClass.java @@ -123,9 +123,6 @@ public class ChildClass { // Check whether one can use an interface default method. String name = "method" + visibility.name() + "Default" + hiddenness.name(); checkMethod(ParentInterface.class, name, /*isStatic*/ false, visibility, expected); - - // Check whether one can override this method. - checkOverriding(suffix, isStatic, visibility, expected); } // Test whether static linking succeeds. @@ -406,37 +403,6 @@ public class ChildClass { } } - private static void checkOverriding(String suffix, - boolean isStatic, - Visibility visibility, - Behaviour behaviour) throws Exception { - if (isStatic || visibility == Visibility.Private) { - // Does not make sense to override a static or private method. - return; - } - - // The classes are in the same package, but will be able to access each - // other only if loaded with the same class loader, here the boot class loader. - boolean canAccess = (visibility != Visibility.Package) || (isParentInBoot && isChildInBoot); - boolean setsWarning = false; // warnings may be set during vtable linking - - String methodName = "callMethod" + visibility.name() + suffix; - - // Force the test class to link its vtable, which may cause warnings, before - // the actual test. - new OverrideClass().methodPublicWhitelist(); - - clearWarning(); - if (Linking.canOverride(methodName) != canAccess) { - throw new RuntimeException("Expected to " + (canAccess ? "" : "not ") + - "be able to override " + methodName + "." + - "isParentInBoot = " + isParentInBoot + ", " + "isChildInBoot = " + isChildInBoot); - } - if (canAccess && hasPendingWarning() != setsWarning) { - throwWarningException(ParentClass.class, methodName, false, "static linking", setsWarning); - } - } - private static void throwDiscoveryException(Class<?> klass, String name, boolean isField, String fn, boolean canAccess) { throw new RuntimeException("Expected " + (isField ? "field " : "method ") + klass.getName() + diff --git a/test/674-hiddenapi/src-ex/Linking.java b/test/674-hiddenapi/src-ex/Linking.java index b416250953..a89b92b2b9 100644 --- a/test/674-hiddenapi/src-ex/Linking.java +++ b/test/674-hiddenapi/src-ex/Linking.java @@ -14,7 +14,6 @@ * limitations under the License. */ -import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; public class Linking { @@ -35,16 +34,6 @@ public class Linking { } } } - - public static boolean canOverride(String methodName) throws Exception { - // ParentClass returns only positive numbers, OverrideClass only negative. - // This way we can tell if OverrideClass managed to override the original - // method or not. - Method method = ParentClass.class.getDeclaredMethod(methodName); - int result1 = (int) method.invoke(new ParentClass()); - int result2 = (int) method.invoke(new OverrideClass()); - return (result1 > 0) && (result2 < 0); - } } // INSTANCE FIELD GET diff --git a/test/674-hiddenapi/src-ex/OverrideClass.java b/test/674-hiddenapi/src-ex/OverrideClass.java deleted file mode 100644 index 1f1f4d6aac..0000000000 --- a/test/674-hiddenapi/src-ex/OverrideClass.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -public class OverrideClass extends ParentClass { - - @Override public int methodPublicWhitelist() { return -411; } - @Override int methodPackageWhitelist() { return -412; } - @Override protected int methodProtectedWhitelist() { return -413; } - - @Override public int methodPublicLightGreylist() { return -421; } - @Override int methodPackageLightGreylist() { return -422; } - @Override protected int methodProtectedLightGreylist() { return -423; } - - @Override public int methodPublicDarkGreylist() { return -431; } - @Override int methodPackageDarkGreylist() { return -432; } - @Override protected int methodProtectedDarkGreylist() { return -433; } - - @Override public int methodPublicBlacklist() { return -441; } - @Override int methodPackageBlacklist() { return -442; } - @Override protected int methodProtectedBlacklist() { return -443; } - -} diff --git a/test/680-sink-regression/expected.txt b/test/680-sink-regression/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/680-sink-regression/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/680-sink-regression/info.txt b/test/680-sink-regression/info.txt new file mode 100644 index 0000000000..547e3b801a --- /dev/null +++ b/test/680-sink-regression/info.txt @@ -0,0 +1 @@ +Regression test for code sinking with exceptions (b/75971227). diff --git a/test/680-sink-regression/src/Main.java b/test/680-sink-regression/src/Main.java new file mode 100644 index 0000000000..642c3abdf4 --- /dev/null +++ b/test/680-sink-regression/src/Main.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 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 java.io.*; + +/** + * Regression test for b/75971227 (code sinking with exceptions). + */ +public class Main { + + public static class N { + int x; + } + + private int f; + + public int doit(N n1) throws FileNotFoundException { + int x = 1; + N n3 = new N(); + try { + if (n1.x == 0) { + f = 11; + x = 3; + } else { + f = x; + } + throw new FileNotFoundException("n3" + n3.x); + } catch (NullPointerException e) { + } + return x; + } + + + public static void main(String[] args) { + N n = new N(); + Main t = new Main(); + int x = 0; + + // Main 1, null pointer argument. + t.f = 0; + try { + x = t.doit(null); + } catch (FileNotFoundException e) { + x = -1; + } + if (x != 1 || t.f != 0) { + throw new Error("Main 1: x=" + x + " f=" + t.f); + } + + // Main 2, n.x is 0. + n.x = 0; + try { + x = t.doit(n); + } catch (FileNotFoundException e) { + x = -1; + } + if (x != -1 || t.f != 11) { + throw new Error("Main 2: x=" + x + " f=" + t.f); + } + + // Main 3, n.x is not 0. + n.x = 1; + try { + x = t.doit(n); + } catch (FileNotFoundException e) { + x = -1; + } + if (x != -1 || t.f != 1) { + throw new Error("Main 3: x=" + x + " f=" + t.f); + } + + System.out.println("passed"); + } +} diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index cf781d7f2b..6633958140 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -24,7 +24,6 @@ TEST_ART_RUN_TEST_DEPENDENCIES := \ $(HOST_OUT_EXECUTABLES)/hiddenapi \ $(HOST_OUT_EXECUTABLES)/jasmin \ $(HOST_OUT_EXECUTABLES)/smali \ - $(HOST_OUT_EXECUTABLES)/dexmerger \ $(HOST_OUT_JAVA_LIBRARIES)/desugar.jar # Add d8 dependency, if enabled. @@ -103,7 +102,7 @@ endif # Host executables. host_prereq_rules := $(ART_TEST_HOST_RUN_TEST_DEPENDENCIES) -# Required for dx, jasmin, smali, dexmerger. +# Required for dx, jasmin, smali. host_prereq_rules += $(TEST_ART_RUN_TEST_DEPENDENCIES) # Sync test files to the target, depends upon all things that must be pushed diff --git a/test/etc/default-build b/test/etc/default-build index 3e6577cfda..9de7294a59 100755 --- a/test/etc/default-build +++ b/test/etc/default-build @@ -341,8 +341,26 @@ function make_dexmerge() { shift done - # Should have at least 1 dex_files_to_merge here, otherwise dxmerger will print the help. - ${DXMERGER} "$dst_file" "${dex_files_to_merge[@]}" + # Skip merge if we are not merging anything. IE: input = output. + if [[ "${#dex_files_to_merge[@]}" -eq "1" ]]; then + local single_input=${dex_files_to_merge[0]} + if [[ "$dst_file" != "$single_input" ]]; then + mv "$single_input" "$dst_file"; + return + fi + fi + + # We assume the dexer did all the API level checks and just merge away. + mkdir d8_merge_out + ${DXMERGER} --min-api 1000 --output ./d8_merge_out "${dex_files_to_merge[@]}" + + if [[ -e "./d8_merge_out/classes2.dex" ]]; then + echo "Cannot merge all dex files into a single dex" + exit 1 + fi + + mv ./d8_merge_out/classes.dex "$dst_file"; + rmdir d8_merge_out } function make_hiddenapi() { diff --git a/test/run-test b/test/run-test index 260a65a056..5b43b52b41 100755 --- a/test/run-test +++ b/test/run-test @@ -50,11 +50,18 @@ export USE_JACK="false" export USE_DESUGAR="true" export SMALI_ARGS="" +# If d8 was not set by the environment variable, assume it is in the path. +if [ -z "$D8" ]; then + export D8="d8" +fi + # If dx was not set by the environment variable, assume it is in the path. if [ -z "$DX" ]; then export DX="dx" fi +export DXMERGER="$D8" + # If jasmin was not set by the environment variable, assume it is in the path. if [ -z "$JASMIN" ]; then export JASMIN="jasmin" @@ -65,11 +72,6 @@ if [ -z "$SMALI" ]; then export SMALI="smali" fi -# If dexmerger was not set by the environment variable, assume it is in the path. -if [ -z "$DXMERGER" ]; then - export DXMERGER="dexmerger" -fi - # If jack was not set by the environment variable, assume it is in the path. if [ -z "$JACK" ]; then export JACK="jack" diff --git a/test/testrunner/env.py b/test/testrunner/env.py index 70efce51ee..539499173c 100644 --- a/test/testrunner/env.py +++ b/test/testrunner/env.py @@ -136,9 +136,8 @@ HOST_OUT_EXECUTABLES = os.path.join(ANDROID_BUILD_TOP, _get_build_var("HOST_OUT_EXECUTABLES")) # Set up default values for $JACK, $DX, $SMALI, etc to the $HOST_OUT_EXECUTABLES/$name path. -for tool in ['jack', 'dx', 'smali', 'jasmin', 'dxmerger']: - binary = tool if tool != 'dxmerger' else 'dexmerger' - os.environ.setdefault(tool.upper(), HOST_OUT_EXECUTABLES + '/' + binary) +for tool in ['jack', 'dx', 'smali', 'jasmin', 'd8']: + os.environ.setdefault(tool.upper(), HOST_OUT_EXECUTABLES + '/' + tool) ANDROID_JAVA_TOOLCHAIN = os.path.join(ANDROID_BUILD_TOP, _get_build_var('ANDROID_JAVA_TOOLCHAIN')) diff --git a/tools/ahat/Android.bp b/tools/ahat/Android.bp new file mode 100644 index 0000000000..dc9f098ff3 --- /dev/null +++ b/tools/ahat/Android.bp @@ -0,0 +1,25 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// 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. + +droiddoc_host { + name: "ahat-docs", + srcs: [ + "src/main/**/*.java", + ], + custom_template: "droiddoc-templates-sdk", + args: "-stubpackages com.android.ahat:com.android.ahat.*", + api_tag_name: "AHAT", + api_filename: "ahat_api.txt", + removed_api_filename: "ahat_removed_api.txt", +} diff --git a/tools/ahat/Android.mk b/tools/ahat/Android.mk index bf79751659..ad33233159 100644 --- a/tools/ahat/Android.mk +++ b/tools/ahat/Android.mk @@ -37,23 +37,10 @@ LOCAL_COMPATIBILITY_SUITE := general-tests include $(BUILD_HOST_JAVA_LIBRARY) AHAT_JAR := $(LOCAL_BUILT_MODULE) -AHAT_API := $(intermediates.COMMON)/ahat_api.txt -AHAT_REMOVED_API := $(intermediates.COMMON)/ahat_removed_api.txt # --- api check for ahat.jar ---------- -include $(CLEAR_VARS) -LOCAL_SRC_FILES := $(call all-java-files-under, src/main) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_CLASS := JAVA_LIBRARIES -LOCAL_MODULE := ahat -LOCAL_DROIDDOC_OPTIONS := \ - -stubpackages com.android.ahat:com.android.ahat.* \ - -api $(AHAT_API) \ - -removedApi $(AHAT_REMOVED_API) -LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := external/doclava/res/assets/templates-sdk -include $(BUILD_DROIDDOC) -$(AHAT_API): $(full_target) +AHAT_API := $(INTERNAL_PLATFORM_AHAT_API_FILE) +AHAT_REMOVED_API := $(INTERNAL_PLATFORM_AHAT_REMOVED_API_FILE) $(eval $(call check-api, \ ahat-check-api, \ |