Don't use sigsegv handler for jvmti.
Disable kEnableOnDemandDexDequicken and return either:
1) Directly the dex file for non-cdex
2) The dex file from the APK/jar for cdex.
Test: test.py
Bug: 196414062
Change-Id: Ia63abe0f761e0842567a51ad1437d221a604a80c
diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc
index 3345883..fc573e1 100644
--- a/openjdkjvmti/ti_class.cc
+++ b/openjdkjvmti/ti_class.cc
@@ -185,14 +185,18 @@
// mirror classes have been initialized and loaded. The runtime relies on these classes having
// specific fields and methods present. Since PreDefine hooks don't need to abide by this
// restriction we will simply not send the event for these classes.
- LOG(WARNING) << "Ignoring load of class <" << descriptor << "> as it is being loaded during "
- << "runtime initialization.";
+ LOG(WARNING) << "Ignoring load of class <" << std::string(descriptor)
+ << "> as it is being loaded during runtime initialization.";
return;
}
art::Thread* self = art::Thread::Current();
ArtClassDefinition def;
- def.InitFirstLoad(descriptor, class_loader, initial_dex_file);
+ if (def.InitFirstLoad(descriptor, class_loader, initial_dex_file) != OK) {
+ LOG(WARNING) << "Failed to initialize class definition in jvmti for "
+ << std::string(descriptor);
+ return;
+ }
// Call all non-retransformable agents.
Transformer::TransformSingleClassDirect<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>(
diff --git a/openjdkjvmti/ti_class_definition.cc b/openjdkjvmti/ti_class_definition.cc
index a480ac0..5e47634 100644
--- a/openjdkjvmti/ti_class_definition.cc
+++ b/openjdkjvmti/ti_class_definition.cc
@@ -35,6 +35,7 @@
#include "base/logging.h"
#include "class_linker-inl.h"
#include "class_root-inl.h"
+#include "dex/art_dex_file_loader.h"
#include "dex/dex_file.h"
#include "fixed_up_dex_file.h"
#include "handle.h"
@@ -132,18 +133,42 @@
return OK;
}
-static void DequickenDexFile(const art::DexFile* dex_file,
- const char* descriptor,
- /*out*/std::vector<unsigned char>* dex_data)
+static jvmtiError DequickenDexFile(const art::DexFile* dex_file,
+ const char* descriptor ATTRIBUTE_UNUSED,
+ /*out*/std::vector<unsigned char>* dex_data)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
- std::unique_ptr<FixedUpDexFile> fixed_dex_file(
- FixedUpDexFile::Create(*dex_file, descriptor));
- dex_data->resize(fixed_dex_file->Size());
- memcpy(dex_data->data(), fixed_dex_file->Begin(), fixed_dex_file->Size());
+ if (dex_file->IsCompactDexFile()) {
+ std::string error_msg;
+ std::vector<std::unique_ptr<const art::DexFile>> dex_files;
+ const art::ArtDexFileLoader dex_file_loader;
+ if (!dex_file_loader.Open(dex_file->GetLocation().c_str(),
+ dex_file->GetLocation().c_str(),
+ /* verify= */ false,
+ /* verify_checksum= */ false,
+ &error_msg,
+ &dex_files)) {
+ return ERR(INTERNAL);
+ }
+ const std::vector<const art::OatDexFile*>& oat_dex_files =
+ dex_file->GetOatDexFile()->GetOatFile()->GetOatDexFiles();
+ const art::DexFile* original_dex_file = nullptr;
+ for (uint32_t i = 0; i < oat_dex_files.size(); ++i) {
+ if (dex_file->GetOatDexFile() == oat_dex_files[i]) {
+ original_dex_file = dex_files[i].get();
+ break;
+ }
+ }
+ dex_data->resize(original_dex_file->Size());
+ memcpy(dex_data->data(), original_dex_file->Begin(), original_dex_file->Size());
+ return OK;
+ }
+ dex_data->resize(dex_file->Size());
+ memcpy(dex_data->data(), dex_file->Begin(), dex_file->Size());
+ return OK;
}
// Gets the data surrounding the given class.
-static void GetDexDataForRetransformation(art::Handle<art::mirror::Class> klass,
+static jvmtiError GetDexDataForRetransformation(art::Handle<art::mirror::Class> klass,
/*out*/std::vector<unsigned char>* dex_data)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
art::StackHandleScope<3> hs(art::Thread::Current());
@@ -157,7 +182,7 @@
art::Handle<art::mirror::ByteArray> orig_dex_bytes(hs.NewHandle(orig_dex->AsByteArray()));
dex_data->resize(orig_dex_bytes->GetLength());
memcpy(dex_data->data(), orig_dex_bytes->GetData(), dex_data->size());
- return;
+ return OK;
} else if (orig_dex->IsDexCache()) {
dex_file = orig_dex->AsDexCache()->GetDexFile();
} else {
@@ -179,7 +204,7 @@
dex_file = &klass->GetDexFile();
}
std::string storage;
- DequickenDexFile(dex_file, klass->GetDescriptor(&storage), dex_data);
+ return DequickenDexFile(dex_file, klass->GetDescriptor(&storage), dex_data);
}
static bool DexNeedsDequickening(art::Handle<art::mirror::Class> klass,
@@ -237,8 +262,8 @@
}
template<typename GetOriginalDexFile>
-void ArtClassDefinition::InitWithDex(GetOriginalDexFile get_original,
- const art::DexFile* quick_dex) {
+jvmtiError ArtClassDefinition::InitWithDex(GetOriginalDexFile get_original,
+ const art::DexFile* quick_dex) {
art::Thread* self = art::Thread::Current();
DCHECK(quick_dex != nullptr);
if (art::MemMap::kCanReplaceMapping && kEnableOnDemandDexDequicken) {
@@ -276,7 +301,7 @@
current_dex_file_ = art::ArrayRef<const unsigned char>(dex_data_mmap_.Begin(),
dequick_size);
}
- return;
+ return OK;
}
}
dex_data_mmap_.Reset();
@@ -284,7 +309,10 @@
// Failed to mmap a large enough area (or on-demand dequickening was disabled). This is
// unfortunate. Since currently the size is just a guess though we might as well try to do it
// manually.
- get_original(/*out*/&dex_data_memory_);
+ jvmtiError error = get_original(/*out*/&dex_data_memory_);
+ if (error != OK) {
+ return error;
+ }
dex_data_ = art::ArrayRef<const unsigned char>(dex_data_memory_);
if (from_class_ext_) {
// We got initial from class_ext so the current one must have undergone redefinition so no
@@ -301,6 +329,7 @@
memcpy(current_dex_memory_.data(), dex_data_.data(), current_dex_memory_.size());
current_dex_file_ = art::ArrayRef<const unsigned char>(current_dex_memory_);
}
+ return OK;
}
jvmtiError ArtClassDefinition::Init(art::Thread* self, jclass klass) {
@@ -332,10 +361,9 @@
const art::DexFile* quick_dex = GetQuickenedDexFile(m_klass);
auto get_original = [&](/*out*/std::vector<unsigned char>* dex_data)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
- GetDexDataForRetransformation(m_klass, dex_data);
+ return GetDexDataForRetransformation(m_klass, dex_data);
};
- InitWithDex(get_original, quick_dex);
- return OK;
+ return InitWithDex(get_original, quick_dex);
}
jvmtiError ArtClassDefinition::Init(art::Thread* self, const jvmtiClassDefinition& def) {
@@ -350,9 +378,9 @@
return OK;
}
-void ArtClassDefinition::InitFirstLoad(const char* descriptor,
- art::Handle<art::mirror::ClassLoader> klass_loader,
- const art::DexFile& dex_file) {
+jvmtiError ArtClassDefinition::InitFirstLoad(const char* descriptor,
+ art::Handle<art::mirror::ClassLoader> klass_loader,
+ const art::DexFile& dex_file) {
art::Thread* self = art::Thread::Current();
art::ScopedObjectAccess soa(self);
initialized_ = true;
@@ -365,9 +393,9 @@
protection_domain_ = nullptr;
auto get_original = [&](/*out*/std::vector<unsigned char>* dex_data)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
- DequickenDexFile(&dex_file, descriptor, dex_data);
+ return DequickenDexFile(&dex_file, descriptor, dex_data);
};
- InitWithDex(get_original, &dex_file);
+ return InitWithDex(get_original, &dex_file);
}
} // namespace openjdkjvmti
diff --git a/openjdkjvmti/ti_class_definition.h b/openjdkjvmti/ti_class_definition.h
index cb0853b..807a595 100644
--- a/openjdkjvmti/ti_class_definition.h
+++ b/openjdkjvmti/ti_class_definition.h
@@ -50,7 +50,7 @@
class ArtClassDefinition {
public:
// If we support doing a on-demand dex-dequickening using signal handlers.
- static constexpr bool kEnableOnDemandDexDequicken = true;
+ static constexpr bool kEnableOnDemandDexDequicken = false;
ArtClassDefinition()
: klass_(nullptr),
@@ -69,9 +69,9 @@
initialized_(false),
structural_transform_update_(false) {}
- void InitFirstLoad(const char* descriptor,
- art::Handle<art::mirror::ClassLoader> klass_loader,
- const art::DexFile& dex_file);
+ jvmtiError InitFirstLoad(const char* descriptor,
+ art::Handle<art::mirror::ClassLoader> klass_loader,
+ const art::DexFile& dex_file);
jvmtiError Init(art::Thread* self, jclass klass);
jvmtiError Init(art::Thread* self, const jvmtiClassDefinition& def);
@@ -158,7 +158,7 @@
jvmtiError InitCommon(art::Thread* self, jclass klass);
template<typename GetOriginalDexFile>
- void InitWithDex(GetOriginalDexFile get_original, const art::DexFile* quick_dex)
+ jvmtiError InitWithDex(GetOriginalDexFile get_original, const art::DexFile* quick_dex)
REQUIRES_SHARED(art::Locks::mutator_lock_);
jclass klass_;