diff options
| -rw-r--r-- | build/Android.bp | 6 | ||||
| -rw-r--r-- | dalvikvm/Android.bp | 3 | ||||
| -rw-r--r-- | dexlayout/dex_ir.cc | 24 | ||||
| -rw-r--r-- | dexlayout/dex_ir.h | 39 | ||||
| -rw-r--r-- | dexlayout/dex_verify.cc | 109 | ||||
| -rw-r--r-- | dexlayout/dex_verify.h | 8 | ||||
| -rw-r--r-- | dexlayout/dexlayout.cc | 133 | ||||
| -rw-r--r-- | dexlayout/dexlayout.h | 8 | ||||
| -rw-r--r-- | runtime/dex_file-inl.h | 275 | ||||
| -rw-r--r-- | runtime/dex_file.cc | 222 | ||||
| -rw-r--r-- | runtime/dex_file.h | 35 | ||||
| -rw-r--r-- | runtime/gc/heap.cc | 9 | ||||
| -rw-r--r-- | runtime/parsed_options.cc | 2 | ||||
| -rw-r--r-- | runtime/plugin.cc | 6 | ||||
| -rw-r--r-- | runtime/runtime.cc | 16 | ||||
| -rw-r--r-- | runtime/signal_catcher.cc | 2 | ||||
| -rw-r--r-- | runtime/ti/agent.cc | 3 | ||||
| -rw-r--r-- | test/Android.bp | 33 | ||||
| -rw-r--r-- | tools/libjdwp_art_failures.txt | 28 | ||||
| -rw-r--r-- | tools/wrapagentproperties/wrapagentproperties.cc | 4 |
20 files changed, 453 insertions, 512 deletions
diff --git a/build/Android.bp b/build/Android.bp index ff762dd703..2c959d46f5 100644 --- a/build/Android.bp +++ b/build/Android.bp @@ -67,10 +67,6 @@ art_global_defaults { cflags: [ "-DART_TARGET", - // Enable missing-noreturn only on non-Mac. As lots of things are not implemented - // for Apple, it's a pain. - "-Wmissing-noreturn", - // To use oprofile_android --callgraph, uncomment this and recompile with // mmma -j art // "-fno-omit-frame-pointer", @@ -83,7 +79,7 @@ art_global_defaults { "bionic/libc/private", ], }, - linux_glibc: { + linux: { cflags: [ // Enable missing-noreturn only on non-Mac. As lots of things are not implemented for // Apple, it's a pain. diff --git a/dalvikvm/Android.bp b/dalvikvm/Android.bp index cca9ac4dbe..c1944fbe59 100644 --- a/dalvikvm/Android.bp +++ b/dalvikvm/Android.bp @@ -34,9 +34,8 @@ art_cc_binary { shared_libs: [ "liblog", ], - ldflags: ["-Wl,--export-dynamic"], }, - linux_glibc: { + linux: { ldflags: ["-Wl,--export-dynamic"], }, }, diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc index 0c944cee2c..f75eacc2d3 100644 --- a/dexlayout/dex_ir.cc +++ b/dexlayout/dex_ir.cc @@ -39,24 +39,6 @@ static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_ext return value; } -static bool GetPositionsCb(void* context, const DexFile::PositionInfo& entry) { - DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context); - PositionInfoVector& positions = debug_info->GetPositionInfo(); - positions.push_back(std::unique_ptr<PositionInfo>(new PositionInfo(entry.address_, entry.line_))); - return false; -} - -static void GetLocalsCb(void* context, const DexFile::LocalInfo& entry) { - DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context); - LocalInfoVector& locals = debug_info->GetLocalInfo(); - const char* name = entry.name_ != nullptr ? entry.name_ : "(null)"; - const char* descriptor = entry.descriptor_ != nullptr ? entry.descriptor_ : ""; - const char* signature = entry.signature_ != nullptr ? entry.signature_ : ""; - locals.push_back(std::unique_ptr<LocalInfo>( - new LocalInfo(name, descriptor, signature, entry.start_address_, entry.end_address_, - entry.reg_))); -} - static uint32_t GetDebugInfoStreamSize(const uint8_t* debug_info_stream) { const uint8_t* stream = debug_info_stream; DecodeUnsignedLeb128(&stream); // line_start @@ -694,12 +676,6 @@ MethodItem* Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataIt } debug_info = code_item->DebugInfo(); } - if (debug_info != nullptr) { - bool is_static = (access_flags & kAccStatic) != 0; - dex_file.DecodeDebugLocalInfo( - disk_code_item, is_static, cdii.GetMemberIndex(), GetLocalsCb, debug_info); - dex_file.DecodeDebugPositionInfo(disk_code_item, GetPositionsCb, debug_info); - } return new MethodItem(access_flags, method_id, code_item); } diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h index 5dcc87dd2e..df3484c012 100644 --- a/dexlayout/dex_ir.h +++ b/dexlayout/dex_ir.h @@ -966,39 +966,6 @@ class CodeItem : public Item { DISALLOW_COPY_AND_ASSIGN(CodeItem); }; -struct PositionInfo { - PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { } - - uint32_t address_; - uint32_t line_; -}; - -using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>; - -struct LocalInfo { - LocalInfo(const char* name, - const char* descriptor, - const char* signature, - uint32_t start_address, - uint32_t end_address, - uint16_t reg) - : name_(name), - descriptor_(descriptor), - signature_(signature), - start_address_(start_address), - end_address_(end_address), - reg_(reg) { } - - std::string name_; - std::string descriptor_; - std::string signature_; - uint32_t start_address_; - uint32_t end_address_; - uint16_t reg_; -}; - -using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>; - class DebugInfoItem : public Item { public: DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info) @@ -1007,16 +974,10 @@ class DebugInfoItem : public Item { uint32_t GetDebugInfoSize() const { return debug_info_size_; } uint8_t* GetDebugInfo() const { return debug_info_.get(); } - PositionInfoVector& GetPositionInfo() { return positions_; } - LocalInfoVector& GetLocalInfo() { return locals_; } - private: uint32_t debug_info_size_; std::unique_ptr<uint8_t[]> debug_info_; - PositionInfoVector positions_; - LocalInfoVector locals_; - DISALLOW_COPY_AND_ASSIGN(DebugInfoItem); }; diff --git a/dexlayout/dex_verify.cc b/dexlayout/dex_verify.cc index 54581292ff..18ddc86e0c 100644 --- a/dexlayout/dex_verify.cc +++ b/dexlayout/dex_verify.cc @@ -893,109 +893,24 @@ bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig, } return true; } - if (!VerifyPositionInfo(orig->GetPositionInfo(), - output->GetPositionInfo(), - orig->GetOffset(), - error_msg)) { + // TODO: Test for debug equivalence rather than byte array equality. + uint32_t orig_size = orig->GetDebugInfoSize(); + uint32_t output_size = output->GetDebugInfoSize(); + if (orig_size != output_size) { + *error_msg = "DebugInfoSize disagreed."; return false; } - return VerifyLocalInfo(orig->GetLocalInfo(), - output->GetLocalInfo(), - orig->GetOffset(), - error_msg); -} - -bool VerifyPositionInfo(dex_ir::PositionInfoVector& orig, - dex_ir::PositionInfoVector& output, - uint32_t orig_offset, - std::string* error_msg) { - if (orig.size() != output.size()) { - *error_msg = StringPrintf( - "Mismatched number of positions for debug info at offset %x: %zu vs %zu.", - orig_offset, - orig.size(), - output.size()); + uint8_t* orig_data = orig->GetDebugInfo(); + uint8_t* output_data = output->GetDebugInfo(); + if ((orig_data == nullptr && output_data != nullptr) || + (orig_data != nullptr && output_data == nullptr)) { + *error_msg = "DebugInfo null/non-null mismatch."; return false; } - for (size_t i = 0; i < orig.size(); ++i) { - if (orig[i]->address_ != output[i]->address_) { - *error_msg = StringPrintf( - "Mismatched position address for debug info at offset %x: %u vs %u.", - orig_offset, - orig[i]->address_, - output[i]->address_); - return false; - } - if (orig[i]->line_ != output[i]->line_) { - *error_msg = StringPrintf("Mismatched position line for debug info at offset %x: %u vs %u.", - orig_offset, - orig[i]->line_, - output[i]->line_); - return false; - } - } - return true; -} - -bool VerifyLocalInfo(dex_ir::LocalInfoVector& orig, - dex_ir::LocalInfoVector& output, - uint32_t orig_offset, - std::string* error_msg) { - if (orig.size() != output.size()) { - *error_msg = StringPrintf( - "Mismatched number of locals for debug info at offset %x: %zu vs %zu.", - orig_offset, - orig.size(), - output.size()); + if (memcmp(orig_data, output_data, orig_size) != 0) { + *error_msg = "DebugInfo bytes mismatch."; return false; } - for (size_t i = 0; i < orig.size(); ++i) { - if (orig[i]->name_ != output[i]->name_) { - *error_msg = StringPrintf("Mismatched local name for debug info at offset %x: %s vs %s.", - orig_offset, - orig[i]->name_.c_str(), - output[i]->name_.c_str()); - return false; - } - if (orig[i]->descriptor_ != output[i]->descriptor_) { - *error_msg = StringPrintf( - "Mismatched local descriptor for debug info at offset %x: %s vs %s.", - orig_offset, - orig[i]->descriptor_.c_str(), - output[i]->descriptor_.c_str()); - return false; - } - if (orig[i]->signature_ != output[i]->signature_) { - *error_msg = StringPrintf("Mismatched local signature for debug info at offset %x: %s vs %s.", - orig_offset, - orig[i]->signature_.c_str(), - output[i]->signature_.c_str()); - return false; - } - if (orig[i]->start_address_ != output[i]->start_address_) { - *error_msg = StringPrintf( - "Mismatched local start address for debug info at offset %x: %u vs %u.", - orig_offset, - orig[i]->start_address_, - output[i]->start_address_); - return false; - } - if (orig[i]->end_address_ != output[i]->end_address_) { - *error_msg = StringPrintf( - "Mismatched local end address for debug info at offset %x: %u vs %u.", - orig_offset, - orig[i]->end_address_, - output[i]->end_address_); - return false; - } - if (orig[i]->reg_ != output[i]->reg_) { - *error_msg = StringPrintf("Mismatched local reg for debug info at offset %x: %u vs %u.", - orig_offset, - orig[i]->reg_, - output[i]->reg_); - return false; - } - } return true; } diff --git a/dexlayout/dex_verify.h b/dexlayout/dex_verify.h index 58c95d6947..998939bbce 100644 --- a/dexlayout/dex_verify.h +++ b/dexlayout/dex_verify.h @@ -100,14 +100,6 @@ bool VerifyCode(dex_ir::CodeItem* orig, dex_ir::CodeItem* output, std::string* e bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig, dex_ir::DebugInfoItem* output, std::string* error_msg); -bool VerifyPositionInfo(dex_ir::PositionInfoVector& orig, - dex_ir::PositionInfoVector& output, - uint32_t orig_offset, - std::string* error_msg); -bool VerifyLocalInfo(dex_ir::LocalInfoVector& orig, - dex_ir::LocalInfoVector& output, - uint32_t orig_offset, - std::string* error_msg); bool VerifyTries(dex_ir::TryItemVector* orig, dex_ir::TryItemVector* output, uint32_t orig_offset, diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc index ade00723fd..40449ae8bd 100644 --- a/dexlayout/dexlayout.cc +++ b/dexlayout/dexlayout.cc @@ -820,37 +820,6 @@ void DexLayout::DumpCatches(const dex_ir::CodeItem* code) { } /* - * Dumps all positions table entries associated with the code. - */ -void DexLayout::DumpPositionInfo(const dex_ir::CodeItem* code) { - dex_ir::DebugInfoItem* debug_info = code->DebugInfo(); - if (debug_info == nullptr) { - return; - } - std::vector<std::unique_ptr<dex_ir::PositionInfo>>& positions = debug_info->GetPositionInfo(); - for (size_t i = 0; i < positions.size(); ++i) { - fprintf(out_file_, " 0x%04x line=%d\n", positions[i]->address_, positions[i]->line_); - } -} - -/* - * Dumps all locals table entries associated with the code. - */ -void DexLayout::DumpLocalInfo(const dex_ir::CodeItem* code) { - dex_ir::DebugInfoItem* debug_info = code->DebugInfo(); - if (debug_info == nullptr) { - return; - } - std::vector<std::unique_ptr<dex_ir::LocalInfo>>& locals = debug_info->GetLocalInfo(); - for (size_t i = 0; i < locals.size(); ++i) { - dex_ir::LocalInfo* entry = locals[i].get(); - fprintf(out_file_, " 0x%04x - 0x%04x reg=%d %s %s %s\n", - entry->start_address_, entry->end_address_, entry->reg_, - entry->name_.c_str(), entry->descriptor_.c_str(), entry->signature_.c_str()); - } -} - -/* * Dumps a single instruction. */ void DexLayout::DumpInstruction(const dex_ir::CodeItem* code, @@ -1093,9 +1062,59 @@ void DexLayout::DumpBytecodes(uint32_t idx, const dex_ir::CodeItem* code, uint32 } /* + * Callback for dumping each positions table entry. + */ +static bool DumpPositionsCb(void* context, const DexFile::PositionInfo& entry) { + FILE* out_file = reinterpret_cast<FILE*>(context); + fprintf(out_file, " 0x%04x line=%d\n", entry.address_, entry.line_); + return false; +} + +/* + * Callback for dumping locals table entry. + */ +static void DumpLocalsCb(void* context, const DexFile::LocalInfo& entry) { + const char* signature = entry.signature_ != nullptr ? entry.signature_ : ""; + FILE* out_file = reinterpret_cast<FILE*>(context); + fprintf(out_file, " 0x%04x - 0x%04x reg=%d %s %s %s\n", + entry.start_address_, entry.end_address_, entry.reg_, + entry.name_, entry.descriptor_, signature); +} + +/* + * Lookup functions. + */ +static const char* StringDataByIdx(uint32_t idx, dex_ir::Collections& collections) { + dex_ir::StringId* string_id = collections.GetStringIdOrNullPtr(idx); + if (string_id == nullptr) { + return nullptr; + } + return string_id->Data(); +} + +static const char* StringDataByTypeIdx(uint16_t idx, dex_ir::Collections& collections) { + dex_ir::TypeId* type_id = collections.GetTypeIdOrNullPtr(idx); + if (type_id == nullptr) { + return nullptr; + } + dex_ir::StringId* string_id = type_id->GetStringId(); + if (string_id == nullptr) { + return nullptr; + } + return string_id->Data(); +} + + +/* * Dumps code of a method. */ -void DexLayout::DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset) { +void DexLayout::DumpCode(uint32_t idx, + const dex_ir::CodeItem* code, + uint32_t code_offset, + const char* declaring_class_descriptor, + const char* method_name, + bool is_static, + const dex_ir::ProtoId* proto) { fprintf(out_file_, " registers : %d\n", code->RegistersSize()); fprintf(out_file_, " ins : %d\n", code->InsSize()); fprintf(out_file_, " outs : %d\n", code->OutsSize()); @@ -1111,10 +1130,48 @@ void DexLayout::DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t co DumpCatches(code); // Positions and locals table in the debug info. + dex_ir::DebugInfoItem* debug_info = code->DebugInfo(); fprintf(out_file_, " positions : \n"); - DumpPositionInfo(code); + if (debug_info != nullptr) { + DexFile::DecodeDebugPositionInfo(debug_info->GetDebugInfo(), + [this](uint32_t idx) { + return StringDataByIdx(idx, this->header_->GetCollections()); + }, + DumpPositionsCb, + out_file_); + } fprintf(out_file_, " locals : \n"); - DumpLocalInfo(code); + if (debug_info != nullptr) { + std::vector<const char*> arg_descriptors; + const dex_ir::TypeList* parameters = proto->Parameters(); + if (parameters != nullptr) { + const dex_ir::TypeIdVector* parameter_type_vector = parameters->GetTypeList(); + if (parameter_type_vector != nullptr) { + for (const dex_ir::TypeId* type_id : *parameter_type_vector) { + arg_descriptors.push_back(type_id->GetStringId()->Data()); + } + } + } + DexFile::DecodeDebugLocalInfo(debug_info->GetDebugInfo(), + "DexLayout in-memory", + declaring_class_descriptor, + arg_descriptors, + method_name, + is_static, + code->RegistersSize(), + code->InsSize(), + code->InsnsSize(), + [this](uint32_t idx) { + return StringDataByIdx(idx, this->header_->GetCollections()); + }, + [this](uint32_t idx) { + return + StringDataByTypeIdx(dchecked_integral_cast<uint16_t>(idx), + this->header_->GetCollections()); + }, + DumpLocalsCb, + out_file_); + } } /* @@ -1141,7 +1198,13 @@ void DexLayout::DumpMethod(uint32_t idx, uint32_t flags, const dex_ir::CodeItem* fprintf(out_file_, " code : (none)\n"); } else { fprintf(out_file_, " code -\n"); - DumpCode(idx, code, code->GetOffset()); + DumpCode(idx, + code, + code->GetOffset(), + back_descriptor, + name, + (flags & kAccStatic) != 0, + method_id->Proto()); } if (options_.disassemble_) { fputc('\n', out_file_); diff --git a/dexlayout/dexlayout.h b/dexlayout/dexlayout.h index 9f6e8a4122..180d9bc87c 100644 --- a/dexlayout/dexlayout.h +++ b/dexlayout/dexlayout.h @@ -96,7 +96,13 @@ class DexLayout { void DumpClass(int idx, char** last_package); void DumpClassAnnotations(int idx); void DumpClassDef(int idx); - void DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset); + void DumpCode(uint32_t idx, + const dex_ir::CodeItem* code, + uint32_t code_offset, + const char* declaring_class_descriptor, + const char* method_name, + bool is_static, + const dex_ir::ProtoId* proto); void DumpEncodedAnnotation(dex_ir::EncodedAnnotation* annotation); void DumpEncodedValue(const dex_ir::EncodedValue* data); void DumpFileHeader(); diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h index 1b7c31859c..5dfbd9b6a1 100644 --- a/runtime/dex_file-inl.h +++ b/runtime/dex_file-inl.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_DEX_FILE_INL_H_ #include "base/bit_utils.h" +#include "base/casts.h" #include "base/logging.h" #include "base/stringpiece.h" #include "dex_file.h" @@ -220,6 +221,280 @@ InvokeType ClassDataItemIterator::GetMethodInvokeType(const DexFile::ClassDef& c } } +template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData> +bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, + const std::string& location, + const char* declaring_class_descriptor, + const std::vector<const char*>& arg_descriptors, + const std::string& method_name, + bool is_static, + uint16_t registers_size, + uint16_t ins_size, + uint16_t insns_size_in_code_units, + IndexToStringData index_to_string_data, + TypeIndexToStringData type_index_to_string_data, + NewLocalCallback new_local_callback, + void* context) { + if (stream == nullptr) { + return false; + } + std::vector<LocalInfo> local_in_reg(registers_size); + + uint16_t arg_reg = registers_size - ins_size; + if (!is_static) { + const char* descriptor = declaring_class_descriptor; + local_in_reg[arg_reg].name_ = "this"; + local_in_reg[arg_reg].descriptor_ = descriptor; + local_in_reg[arg_reg].signature_ = nullptr; + local_in_reg[arg_reg].start_address_ = 0; + local_in_reg[arg_reg].reg_ = arg_reg; + local_in_reg[arg_reg].is_live_ = true; + arg_reg++; + } + + DecodeUnsignedLeb128(&stream); // Line. + uint32_t parameters_size = DecodeUnsignedLeb128(&stream); + uint32_t i; + if (parameters_size != arg_descriptors.size()) { + LOG(ERROR) << "invalid stream - problem with parameter iterator in " << location + << " for method " << method_name; + return false; + } + for (i = 0; i < parameters_size && i < arg_descriptors.size(); ++i) { + if (arg_reg >= registers_size) { + LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg + << " >= " << registers_size << ") in " << location; + return false; + } + uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); + const char* descriptor = arg_descriptors[i]; + local_in_reg[arg_reg].name_ = index_to_string_data(name_idx); + local_in_reg[arg_reg].descriptor_ = descriptor; + local_in_reg[arg_reg].signature_ = nullptr; + local_in_reg[arg_reg].start_address_ = 0; + local_in_reg[arg_reg].reg_ = arg_reg; + local_in_reg[arg_reg].is_live_ = true; + switch (*descriptor) { + case 'D': + case 'J': + arg_reg += 2; + break; + default: + arg_reg += 1; + break; + } + } + + uint32_t address = 0; + for (;;) { + uint8_t opcode = *stream++; + switch (opcode) { + case DBG_END_SEQUENCE: + // Emit all variables which are still alive at the end of the method. + for (uint16_t reg = 0; reg < registers_size; reg++) { + if (local_in_reg[reg].is_live_) { + local_in_reg[reg].end_address_ = insns_size_in_code_units; + new_local_callback(context, local_in_reg[reg]); + } + } + return true; + case DBG_ADVANCE_PC: + address += DecodeUnsignedLeb128(&stream); + break; + case DBG_ADVANCE_LINE: + DecodeSignedLeb128(&stream); // Line. + break; + case DBG_START_LOCAL: + case DBG_START_LOCAL_EXTENDED: { + uint16_t reg = DecodeUnsignedLeb128(&stream); + if (reg >= registers_size) { + LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " + << registers_size << ") in " << location; + return false; + } + + uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); + uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream); + uint32_t signature_idx = dex::kDexNoIndex; + if (opcode == DBG_START_LOCAL_EXTENDED) { + signature_idx = DecodeUnsignedLeb128P1(&stream); + } + + // Emit what was previously there, if anything + if (local_in_reg[reg].is_live_) { + local_in_reg[reg].end_address_ = address; + new_local_callback(context, local_in_reg[reg]); + } + + local_in_reg[reg].name_ = index_to_string_data(name_idx); + local_in_reg[reg].descriptor_ = type_index_to_string_data(descriptor_idx);; + local_in_reg[reg].signature_ = index_to_string_data(signature_idx); + local_in_reg[reg].start_address_ = address; + local_in_reg[reg].reg_ = reg; + local_in_reg[reg].is_live_ = true; + break; + } + case DBG_END_LOCAL: { + uint16_t reg = DecodeUnsignedLeb128(&stream); + if (reg >= registers_size) { + LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " + << registers_size << ") in " << location; + return false; + } + // If the register is live, close it properly. Otherwise, closing an already + // closed register is sloppy, but harmless if no further action is taken. + if (local_in_reg[reg].is_live_) { + local_in_reg[reg].end_address_ = address; + new_local_callback(context, local_in_reg[reg]); + local_in_reg[reg].is_live_ = false; + } + break; + } + case DBG_RESTART_LOCAL: { + uint16_t reg = DecodeUnsignedLeb128(&stream); + if (reg >= registers_size) { + LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " + << registers_size << ") in " << location; + return false; + } + // If the register is live, the "restart" is superfluous, + // and we don't want to mess with the existing start address. + if (!local_in_reg[reg].is_live_) { + local_in_reg[reg].start_address_ = address; + local_in_reg[reg].is_live_ = true; + } + break; + } + case DBG_SET_PROLOGUE_END: + case DBG_SET_EPILOGUE_BEGIN: + break; + case DBG_SET_FILE: + DecodeUnsignedLeb128P1(&stream); // name. + break; + default: + address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE; + break; + } + } +} + +template<typename NewLocalCallback> +bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, + bool is_static, + uint32_t method_idx, + NewLocalCallback new_local_callback, + void* context) const { + if (code_item == nullptr) { + return false; + } + std::vector<const char*> arg_descriptors; + DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx))); + for (; it.HasNext(); it.Next()) { + arg_descriptors.push_back(it.GetDescriptor()); + } + return DecodeDebugLocalInfo(GetDebugInfoStream(code_item), + GetLocation(), + GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)), + arg_descriptors, + this->PrettyMethod(method_idx), + is_static, + code_item->registers_size_, + code_item->ins_size_, + code_item->insns_size_in_code_units_, + [this](uint32_t idx) { + return StringDataByIdx(dex::StringIndex(idx)); + }, + [this](uint32_t idx) { + return StringByTypeIdx(dex::TypeIndex( + dchecked_integral_cast<uint16_t>(idx))); + }, + new_local_callback, + context); +} + +template<typename DexDebugNewPosition, typename IndexToStringData> +bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream, + IndexToStringData index_to_string_data, + DexDebugNewPosition position_functor, + void* context) { + if (stream == nullptr) { + return false; + } + + PositionInfo entry = PositionInfo(); + entry.line_ = DecodeUnsignedLeb128(&stream); + uint32_t parameters_size = DecodeUnsignedLeb128(&stream); + for (uint32_t i = 0; i < parameters_size; ++i) { + DecodeUnsignedLeb128P1(&stream); // Parameter name. + } + + for (;;) { + uint8_t opcode = *stream++; + switch (opcode) { + case DBG_END_SEQUENCE: + return true; // end of stream. + case DBG_ADVANCE_PC: + entry.address_ += DecodeUnsignedLeb128(&stream); + break; + case DBG_ADVANCE_LINE: + entry.line_ += DecodeSignedLeb128(&stream); + break; + case DBG_START_LOCAL: + DecodeUnsignedLeb128(&stream); // reg. + DecodeUnsignedLeb128P1(&stream); // name. + DecodeUnsignedLeb128P1(&stream); // descriptor. + break; + case DBG_START_LOCAL_EXTENDED: + DecodeUnsignedLeb128(&stream); // reg. + DecodeUnsignedLeb128P1(&stream); // name. + DecodeUnsignedLeb128P1(&stream); // descriptor. + DecodeUnsignedLeb128P1(&stream); // signature. + break; + case DBG_END_LOCAL: + case DBG_RESTART_LOCAL: + DecodeUnsignedLeb128(&stream); // reg. + break; + case DBG_SET_PROLOGUE_END: + entry.prologue_end_ = true; + break; + case DBG_SET_EPILOGUE_BEGIN: + entry.epilogue_begin_ = true; + break; + case DBG_SET_FILE: { + uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); + entry.source_file_ = index_to_string_data(name_idx); + break; + } + default: { + int adjopcode = opcode - DBG_FIRST_SPECIAL; + entry.address_ += adjopcode / DBG_LINE_RANGE; + entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE); + if (position_functor(context, entry)) { + return true; // early exit. + } + entry.prologue_end_ = false; + entry.epilogue_begin_ = false; + break; + } + } + } +} + +template<typename DexDebugNewPosition> +bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item, + DexDebugNewPosition position_functor, + void* context) const { + if (code_item == nullptr) { + return false; + } + return DecodeDebugPositionInfo(GetDebugInfoStream(code_item), + [this](uint32_t idx) { + return StringDataByIdx(dex::StringIndex(idx)); + }, + position_functor, + context); +} + } // namespace art #endif // ART_RUNTIME_DEX_FILE_INL_H_ diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 08c047d8e9..f2c43f7f87 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -537,228 +537,6 @@ int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t addr } } -bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx, - DexDebugNewLocalCb local_cb, void* context) const { - DCHECK(local_cb != nullptr); - if (code_item == nullptr) { - return false; - } - const uint8_t* stream = GetDebugInfoStream(code_item); - if (stream == nullptr) { - return false; - } - std::vector<LocalInfo> local_in_reg(code_item->registers_size_); - - uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_; - if (!is_static) { - const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)); - local_in_reg[arg_reg].name_ = "this"; - local_in_reg[arg_reg].descriptor_ = descriptor; - local_in_reg[arg_reg].signature_ = nullptr; - local_in_reg[arg_reg].start_address_ = 0; - local_in_reg[arg_reg].reg_ = arg_reg; - local_in_reg[arg_reg].is_live_ = true; - arg_reg++; - } - - DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx))); - DecodeUnsignedLeb128(&stream); // Line. - uint32_t parameters_size = DecodeUnsignedLeb128(&stream); - uint32_t i; - for (i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) { - if (arg_reg >= code_item->registers_size_) { - LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg - << " >= " << code_item->registers_size_ << ") in " << GetLocation(); - return false; - } - uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); - const char* descriptor = it.GetDescriptor(); - local_in_reg[arg_reg].name_ = StringDataByIdx(dex::StringIndex(name_idx)); - local_in_reg[arg_reg].descriptor_ = descriptor; - local_in_reg[arg_reg].signature_ = nullptr; - local_in_reg[arg_reg].start_address_ = 0; - local_in_reg[arg_reg].reg_ = arg_reg; - local_in_reg[arg_reg].is_live_ = true; - switch (*descriptor) { - case 'D': - case 'J': - arg_reg += 2; - break; - default: - arg_reg += 1; - break; - } - } - if (i != parameters_size || it.HasNext()) { - LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation() - << " for method " << this->PrettyMethod(method_idx); - return false; - } - - uint32_t address = 0; - for (;;) { - uint8_t opcode = *stream++; - switch (opcode) { - case DBG_END_SEQUENCE: - // Emit all variables which are still alive at the end of the method. - for (uint16_t reg = 0; reg < code_item->registers_size_; reg++) { - if (local_in_reg[reg].is_live_) { - local_in_reg[reg].end_address_ = code_item->insns_size_in_code_units_; - local_cb(context, local_in_reg[reg]); - } - } - return true; - case DBG_ADVANCE_PC: - address += DecodeUnsignedLeb128(&stream); - break; - case DBG_ADVANCE_LINE: - DecodeSignedLeb128(&stream); // Line. - break; - case DBG_START_LOCAL: - case DBG_START_LOCAL_EXTENDED: { - uint16_t reg = DecodeUnsignedLeb128(&stream); - if (reg >= code_item->registers_size_) { - LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " - << code_item->registers_size_ << ") in " << GetLocation(); - return false; - } - - uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); - uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream); - uint32_t signature_idx = dex::kDexNoIndex; - if (opcode == DBG_START_LOCAL_EXTENDED) { - signature_idx = DecodeUnsignedLeb128P1(&stream); - } - - // Emit what was previously there, if anything - if (local_in_reg[reg].is_live_) { - local_in_reg[reg].end_address_ = address; - local_cb(context, local_in_reg[reg]); - } - - local_in_reg[reg].name_ = StringDataByIdx(dex::StringIndex(name_idx)); - local_in_reg[reg].descriptor_ = - StringByTypeIdx(dex::TypeIndex(dchecked_integral_cast<uint16_t>(descriptor_idx)));; - local_in_reg[reg].signature_ = StringDataByIdx(dex::StringIndex(signature_idx)); - local_in_reg[reg].start_address_ = address; - local_in_reg[reg].reg_ = reg; - local_in_reg[reg].is_live_ = true; - break; - } - case DBG_END_LOCAL: { - uint16_t reg = DecodeUnsignedLeb128(&stream); - if (reg >= code_item->registers_size_) { - LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " - << code_item->registers_size_ << ") in " << GetLocation(); - return false; - } - // If the register is live, close it properly. Otherwise, closing an already - // closed register is sloppy, but harmless if no further action is taken. - if (local_in_reg[reg].is_live_) { - local_in_reg[reg].end_address_ = address; - local_cb(context, local_in_reg[reg]); - local_in_reg[reg].is_live_ = false; - } - break; - } - case DBG_RESTART_LOCAL: { - uint16_t reg = DecodeUnsignedLeb128(&stream); - if (reg >= code_item->registers_size_) { - LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= " - << code_item->registers_size_ << ") in " << GetLocation(); - return false; - } - // If the register is live, the "restart" is superfluous, - // and we don't want to mess with the existing start address. - if (!local_in_reg[reg].is_live_) { - local_in_reg[reg].start_address_ = address; - local_in_reg[reg].is_live_ = true; - } - break; - } - case DBG_SET_PROLOGUE_END: - case DBG_SET_EPILOGUE_BEGIN: - break; - case DBG_SET_FILE: - DecodeUnsignedLeb128P1(&stream); // name. - break; - default: - address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE; - break; - } - } -} - -bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item, DexDebugNewPositionCb position_cb, - void* context) const { - DCHECK(position_cb != nullptr); - if (code_item == nullptr) { - return false; - } - const uint8_t* stream = GetDebugInfoStream(code_item); - if (stream == nullptr) { - return false; - } - - PositionInfo entry = PositionInfo(); - entry.line_ = DecodeUnsignedLeb128(&stream); - uint32_t parameters_size = DecodeUnsignedLeb128(&stream); - for (uint32_t i = 0; i < parameters_size; ++i) { - DecodeUnsignedLeb128P1(&stream); // Parameter name. - } - - for (;;) { - uint8_t opcode = *stream++; - switch (opcode) { - case DBG_END_SEQUENCE: - return true; // end of stream. - case DBG_ADVANCE_PC: - entry.address_ += DecodeUnsignedLeb128(&stream); - break; - case DBG_ADVANCE_LINE: - entry.line_ += DecodeSignedLeb128(&stream); - break; - case DBG_START_LOCAL: - DecodeUnsignedLeb128(&stream); // reg. - DecodeUnsignedLeb128P1(&stream); // name. - DecodeUnsignedLeb128P1(&stream); // descriptor. - break; - case DBG_START_LOCAL_EXTENDED: - DecodeUnsignedLeb128(&stream); // reg. - DecodeUnsignedLeb128P1(&stream); // name. - DecodeUnsignedLeb128P1(&stream); // descriptor. - DecodeUnsignedLeb128P1(&stream); // signature. - break; - case DBG_END_LOCAL: - case DBG_RESTART_LOCAL: - DecodeUnsignedLeb128(&stream); // reg. - break; - case DBG_SET_PROLOGUE_END: - entry.prologue_end_ = true; - break; - case DBG_SET_EPILOGUE_BEGIN: - entry.epilogue_begin_ = true; - break; - case DBG_SET_FILE: { - uint32_t name_idx = DecodeUnsignedLeb128P1(&stream); - entry.source_file_ = StringDataByIdx(dex::StringIndex(name_idx)); - break; - } - default: { - int adjopcode = opcode - DBG_FIRST_SPECIAL; - entry.address_ += adjopcode / DBG_LINE_RANGE; - entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE); - if (position_cb(context, entry)) { - return true; // early exit. - } - entry.prologue_end_ = false; - entry.epilogue_begin_ = false; - break; - } - } - } -} - bool DexFile::LineNumForPcCb(void* raw_context, const PositionInfo& entry) { LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context); diff --git a/runtime/dex_file.h b/runtime/dex_file.h index 5759684c55..6868d525e2 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -772,10 +772,6 @@ class DexFile { bool epilogue_begin_ = false; }; - // Callback for "new position table entry". - // Returning true causes the decoder to stop early. - typedef bool (*DexDebugNewPositionCb)(void* context, const PositionInfo& entry); - struct LocalInfo { LocalInfo() = default; @@ -899,11 +895,36 @@ class DexFile { }; // Returns false if there is no debugging information or if it cannot be decoded. - bool DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx, - DexDebugNewLocalCb local_cb, void* context) const; + template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData> + static bool DecodeDebugLocalInfo(const uint8_t* stream, + const std::string& location, + const char* declaring_class_descriptor, + const std::vector<const char*>& arg_descriptors, + const std::string& method_name, + bool is_static, + uint16_t registers_size, + uint16_t ins_size, + uint16_t insns_size_in_code_units, + IndexToStringData index_to_string_data, + TypeIndexToStringData type_index_to_string_data, + NewLocalCallback new_local, + void* context); + template<typename NewLocalCallback> + bool DecodeDebugLocalInfo(const CodeItem* code_item, + bool is_static, + uint32_t method_idx, + NewLocalCallback new_local, + void* context) const; // Returns false if there is no debugging information or if it cannot be decoded. - bool DecodeDebugPositionInfo(const CodeItem* code_item, DexDebugNewPositionCb position_cb, + template<typename DexDebugNewPosition, typename IndexToStringData> + static bool DecodeDebugPositionInfo(const uint8_t* stream, + IndexToStringData index_to_string_data, + DexDebugNewPosition position_functor, + void* context); + template<typename DexDebugNewPosition> + bool DecodeDebugPositionInfo(const CodeItem* code_item, + DexDebugNewPosition position_functor, void* context) const; const char* GetSourceFile(const ClassDef& class_def) const { diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 4004af2875..67e8a0d02f 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -132,10 +132,6 @@ static constexpr uint32_t kAllocSpaceBeginForDeterministicAoT = 0x40000000; // Dump the rosalloc stats on SIGQUIT. static constexpr bool kDumpRosAllocStatsOnSigQuit = false; -// Extra added to the heap growth multiplier. Used to adjust the GC ergonomics for the read barrier -// config. -static constexpr double kExtraHeapGrowthMultiplier = kUseReadBarrier ? 1.0 : 0.0; - static const char* kRegionSpaceName = "main space (region space)"; // If true, we log all GCs in the both the foreground and background. Used for debugging. @@ -255,8 +251,7 @@ Heap::Heap(size_t initial_size, min_free_(min_free), max_free_(max_free), target_utilization_(target_utilization), - foreground_heap_growth_multiplier_( - foreground_heap_growth_multiplier + kExtraHeapGrowthMultiplier), + foreground_heap_growth_multiplier_(foreground_heap_growth_multiplier), total_wait_time_(0), verify_object_mode_(kVerifyObjectModeDisabled), disable_moving_gc_count_(0), @@ -3428,7 +3423,7 @@ collector::GarbageCollector* Heap::FindCollectorByGcType(collector::GcType gc_ty double Heap::HeapGrowthMultiplier() const { // If we don't care about pause times we are background, so return 1.0. - if (!CareAboutPauseTimes() || IsLowMemoryMode()) { + if (!CareAboutPauseTimes()) { return 1.0; } return foreground_heap_growth_multiplier_; diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index 9841a95746..71d7b6c34d 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -121,7 +121,7 @@ std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognize .WithType<double>().WithRange(0.1, 0.9) .IntoKey(M::HeapTargetUtilization) .Define("-XX:ForegroundHeapGrowthMultiplier=_") - .WithType<double>().WithRange(0.1, 1.0) + .WithType<double>().WithRange(0.1, 5.0) .IntoKey(M::ForegroundHeapGrowthMultiplier) .Define("-XX:ParallelGCThreads=_") .WithType<unsigned int>() diff --git a/runtime/plugin.cc b/runtime/plugin.cc index 731967c738..6aa078771b 100644 --- a/runtime/plugin.cc +++ b/runtime/plugin.cc @@ -74,10 +74,8 @@ bool Plugin::Unload() { LOG(WARNING) << this << " does not include a deinitialization function"; } dlopen_handle_ = nullptr; - if (dlclose(handle) != 0) { - LOG(ERROR) << this << " failed to dlclose: " << dlerror(); - ret = false; - } + // Don't bother to actually dlclose since we are shutting down anyway and there might be small + // amounts of processing still being done. return ret; } diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 8eb4a07b64..7f2f7895db 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -174,6 +174,11 @@ static constexpr double kLowMemoryMinLoadFactor = 0.5; static constexpr double kLowMemoryMaxLoadFactor = 0.8; static constexpr double kNormalMinLoadFactor = 0.4; static constexpr double kNormalMaxLoadFactor = 0.7; + +// Extra added to the default heap growth multiplier. Used to adjust the GC ergonomics for the read +// barrier config. +static constexpr double kExtraDefaultHeapGrowthMultiplier = kUseReadBarrier ? 1.0 : 0.0; + Runtime* Runtime::instance_ = nullptr; struct TraceConfig { @@ -1152,13 +1157,22 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { // agents_.push_back(lib); // } + float foreground_heap_growth_multiplier; + if (is_low_memory_mode_ && !runtime_options.Exists(Opt::ForegroundHeapGrowthMultiplier)) { + // If low memory mode, use 1.0 as the multiplier by default. + foreground_heap_growth_multiplier = 1.0f; + } else { + foreground_heap_growth_multiplier = + runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier) + + kExtraDefaultHeapGrowthMultiplier; + } XGcOption xgc_option = runtime_options.GetOrDefault(Opt::GcOption); heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize), runtime_options.GetOrDefault(Opt::HeapGrowthLimit), runtime_options.GetOrDefault(Opt::HeapMinFree), runtime_options.GetOrDefault(Opt::HeapMaxFree), runtime_options.GetOrDefault(Opt::HeapTargetUtilization), - runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier), + foreground_heap_growth_multiplier, runtime_options.GetOrDefault(Opt::MemoryMaximumSize), runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity), runtime_options.GetOrDefault(Opt::Image), diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc index b50879f0a9..a1f14be0f1 100644 --- a/runtime/signal_catcher.cc +++ b/runtime/signal_catcher.cc @@ -170,7 +170,7 @@ void SignalCatcher::Output(const std::string& s) { #if defined(ART_TARGET_ANDROID) if (use_tombstoned_stack_trace_fd_ && !tombstoned_notify_completion(tombstone_fd)) { - LOG(WARNING) << "Unable to notify tombstoned of dump completion."; + PLOG(WARNING) << "Unable to notify tombstoned of dump completion"; } #endif } diff --git a/runtime/ti/agent.cc b/runtime/ti/agent.cc index 6ff966678a..20e297c991 100644 --- a/runtime/ti/agent.cc +++ b/runtime/ti/agent.cc @@ -113,7 +113,8 @@ void Agent::Unload() { if (onunload_ != nullptr) { onunload_(Runtime::Current()->GetJavaVM()); } - dlclose(dlopen_handle_); + // Don't actually dlclose since some agents assume they will never get unloaded. Since this only + // happens when the runtime is shutting down anyway this isn't a big deal. dlopen_handle_ = nullptr; onload_ = nullptr; onattach_ = nullptr; diff --git a/test/Android.bp b/test/Android.bp index b737345729..16b30f988f 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -74,7 +74,7 @@ art_cc_defaults { ], target: { - linux_glibc: { + linux: { ldflags: [ // Allow jni_compiler_test to find Java_MyClassNatives_bar // within itself using dlopen(NULL, ...). @@ -83,9 +83,6 @@ art_cc_defaults { "-Wl,-u,Java_MyClassNatives_bar", "-Wl,-u,Java_MyClassNatives_sbar", ], - shared_libs: [ - "libziparchive", - ], cflags: [ // gtest issue "-Wno-used-but-marked-unused", @@ -93,23 +90,15 @@ art_cc_defaults { "-Wno-missing-noreturn", ], }, - android: { - ldflags: [ - // Allow jni_compiler_test to find Java_MyClassNatives_bar - // within itself using dlopen(NULL, ...). - "-Wl,--export-dynamic", - "-Wl,-u,Java_MyClassNatives_bar", - "-Wl,-u,Java_MyClassNatives_sbar", + host: { + shared_libs: [ + "libziparchive", ], + }, + android: { shared_libs: [ "liblog", ], - cflags: [ - // gtest issue - "-Wno-used-but-marked-unused", - "-Wno-deprecated", - "-Wno-missing-noreturn", - ], }, }, } @@ -135,15 +124,7 @@ art_cc_defaults { android64: { cflags: ["-DART_TARGET_NATIVETEST_DIR=/data/nativetest64/art"], }, - android: { - cflags: [ - // gtest issue - "-Wno-used-but-marked-unused", - "-Wno-deprecated", - "-Wno-missing-noreturn", - ], - }, - linux_glibc: { + linux: { cflags: [ // gtest issue "-Wno-used-but-marked-unused", diff --git a/tools/libjdwp_art_failures.txt b/tools/libjdwp_art_failures.txt index bd422e964e..1812177e2f 100644 --- a/tools/libjdwp_art_failures.txt +++ b/tools/libjdwp_art_failures.txt @@ -71,34 +71,6 @@ "org.apache.harmony.jpda.tests.jdwp.EventModifiers.InstanceOnlyModifierTest#testMethodExit", "org.apache.harmony.jpda.tests.jdwp.EventModifiers.InstanceOnlyModifierTest#testMethodExitWithReturnValue" ] }, -/* TODO Investigate these failures more closely */ -{ - description: "Tests that fail when run on the chromium buildbots against the prebuilt libjdwp.so in certain configurations", - result: EXEC_FAILED, - bug: 67497270, - names: [ - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEvents003Test#testCombinedEvents003_01", - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_01", - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_02", - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_03", - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_04", - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_05", - "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_06", - "org.apache.harmony.jpda.tests.jdwp.Events.VMDeathTest#testVMDeathEvent", - "org.apache.harmony.jpda.tests.jdwp.MultiSession.ClassPrepareTest#testClassPrepare001", - "org.apache.harmony.jpda.tests.jdwp.MultiSession.ExceptionTest#testException001", - "org.apache.harmony.jpda.tests.jdwp.MultiSession.FieldAccessTest#testFieldAccess001", - "org.apache.harmony.jpda.tests.jdwp.MultiSession.FieldModificationTest#testFieldModification001", - "org.apache.harmony.jpda.tests.jdwp.MultiSession.SingleStepTest#testSingleStep001", - "org.apache.harmony.jpda.tests.jdwp.MultiSession.VMDeathTest#testVMDeathRequest", - "org.apache.harmony.jpda.tests.jdwp.ReferenceType.SignatureWithGenericTest#testSignatureWithGeneric001", - "org.apache.harmony.jpda.tests.jdwp.StackFrame.GetValues002Test#testGetValues005_Int2", - "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.SetDefaultStratumTest#testSetDefaultStratum001", - "org.apache.harmony.jpda.tests.jdwp.ThreadReference.StatusTest#testStatus001", - "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.AllClassesTest#testAllClasses002", - "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.AllClassesWithGenericTest#testAllClassesWithGeneric001" - ] -}, /* TODO Categorize these failures more. */ { description: "Tests that fail on both ART and RI. These tests are likely incorrect", diff --git a/tools/wrapagentproperties/wrapagentproperties.cc b/tools/wrapagentproperties/wrapagentproperties.cc index dca627046e..67d5279672 100644 --- a/tools/wrapagentproperties/wrapagentproperties.cc +++ b/tools/wrapagentproperties/wrapagentproperties.cc @@ -45,7 +45,6 @@ static std::mutex unload_mutex; struct Unloader { AgentUnloadFunction unload; - void* dlclose_handle; }; static std::vector<Unloader> unload_functions; @@ -71,7 +70,6 @@ struct ProxyJavaVM { std::lock_guard<std::mutex> lk(unload_mutex); unload_functions.push_back({ reinterpret_cast<AgentUnloadFunction>(dlsym(dlopen_handle, kOnUnload)), - dlopen_handle }); } attach = reinterpret_cast<AgentLoadFunction>(dlsym(dlopen_handle, kOnAttach)); @@ -337,7 +335,7 @@ extern "C" JNIEXPORT void JNICALL Agent_OnUnload(JavaVM* jvm) { std::lock_guard<std::mutex> lk(unload_mutex); for (const Unloader& u : unload_functions) { u.unload(jvm); - dlclose(u.dlclose_handle); + // Don't dlclose since some agents expect to still have code loaded after this. } unload_functions.clear(); } |