8272096: Exceptions::new_exception can return wrong exception

Reviewed-by: hseigel, dholmes
This commit is contained in:
Coleen Phillimore 2022-07-19 14:41:58 +00:00
parent a41b12f430
commit bbc57483ce
4 changed files with 24 additions and 23 deletions

View File

@ -644,13 +644,13 @@ static char* get_user_name_slow(int vmid, int nspid, TRAPS) {
// return the name of the user that owns the JVM indicated by the given vmid. // return the name of the user that owns the JVM indicated by the given vmid.
// //
static char* get_user_name(int vmid, int *nspid, TRAPS) { static char* get_user_name(int vmid, int *nspid, TRAPS) {
char *result = get_user_name_slow(vmid, *nspid, THREAD); char *result = get_user_name_slow(vmid, *nspid, CHECK_NULL);
#if defined(LINUX) #if defined(LINUX)
// If we are examining a container process without PID namespaces enabled // If we are examining a container process without PID namespaces enabled
// we need to use /proc/{pid}/root/tmp to find hsperfdata files. // we need to use /proc/{pid}/root/tmp to find hsperfdata files.
if (result == NULL) { if (result == NULL) {
result = get_user_name_slow(vmid, vmid, THREAD); result = get_user_name_slow(vmid, vmid, CHECK_NULL);
// Enable nspid logic going forward // Enable nspid logic going forward
if (result != NULL) *nspid = vmid; if (result != NULL) *nspid = vmid;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -173,13 +173,15 @@ int32_t StackMapReader::chop(
return pos+1; return pos+1;
} }
#define CHECK_NT CHECK_(VerificationType::bogus_type())
VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) { VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
u1 tag = _stream->get_u1(THREAD); u1 tag = _stream->get_u1(CHECK_NT);
if (tag < (u1)ITEM_UninitializedThis) { if (tag < (u1)ITEM_UninitializedThis) {
return VerificationType::from_tag(tag); return VerificationType::from_tag(tag);
} }
if (tag == ITEM_Object) { if (tag == ITEM_Object) {
u2 class_index = _stream->get_u2(THREAD); u2 class_index = _stream->get_u2(CHECK_NT);
int nconstants = _cp->length(); int nconstants = _cp->length();
if ((class_index <= 0 || class_index >= nconstants) || if ((class_index <= 0 || class_index >= nconstants) ||
(!_cp->tag_at(class_index).is_klass() && (!_cp->tag_at(class_index).is_klass() &&
@ -196,7 +198,7 @@ VerificationType StackMapReader::parse_verification_type(u1* flags, TRAPS) {
return VerificationType::uninitialized_this_type(); return VerificationType::uninitialized_this_type();
} }
if (tag == ITEM_Uninitialized) { if (tag == ITEM_Uninitialized) {
u2 offset = _stream->get_u2(THREAD); u2 offset = _stream->get_u2(CHECK_NT);
if (offset >= _code_length || if (offset >= _code_length ||
_code_data[offset] != ClassVerifier::NEW_OFFSET) { _code_data[offset] != ClassVerifier::NEW_OFFSET) {
_verifier->class_format_error( _verifier->class_format_error(
@ -214,7 +216,7 @@ StackMapFrame* StackMapReader::next(
StackMapFrame* frame; StackMapFrame* frame;
int offset; int offset;
VerificationType* locals = NULL; VerificationType* locals = NULL;
u1 frame_type = _stream->get_u1(THREAD); u1 frame_type = _stream->get_u1(CHECK_NULL);
if (frame_type < 64) { if (frame_type < 64) {
// same_frame // same_frame
if (first) { if (first) {
@ -268,7 +270,7 @@ StackMapFrame* StackMapReader::next(
return frame; return frame;
} }
u2 offset_delta = _stream->get_u2(THREAD); u2 offset_delta = _stream->get_u2(CHECK_NULL);
if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) { if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
// reserved frame types // reserved frame types
@ -360,7 +362,7 @@ StackMapFrame* StackMapReader::next(
} }
u1 flags = pre_frame->flags(); u1 flags = pre_frame->flags();
for (i=0; i<appends; i++) { for (i=0; i<appends; i++) {
locals[real_length] = parse_verification_type(&flags, THREAD); locals[real_length] = parse_verification_type(&flags, CHECK_NULL);
if (locals[real_length].is_category2()) { if (locals[real_length].is_category2()) {
locals[real_length + 1] = locals[real_length].to_category2_2nd(); locals[real_length + 1] = locals[real_length].to_category2_2nd();
++real_length; ++real_length;
@ -382,7 +384,7 @@ StackMapFrame* StackMapReader::next(
if (frame_type == FULL) { if (frame_type == FULL) {
// full_frame // full_frame
u1 flags = 0; u1 flags = 0;
u2 locals_size = _stream->get_u2(THREAD); u2 locals_size = _stream->get_u2(CHECK_NULL);
int real_locals_size = 0; int real_locals_size = 0;
if (locals_size > 0) { if (locals_size > 0) {
locals = NEW_RESOURCE_ARRAY_IN_THREAD( locals = NEW_RESOURCE_ARRAY_IN_THREAD(
@ -390,7 +392,7 @@ StackMapFrame* StackMapReader::next(
} }
int i; int i;
for (i=0; i<locals_size; i++) { for (i=0; i<locals_size; i++) {
locals[real_locals_size] = parse_verification_type(&flags, THREAD); locals[real_locals_size] = parse_verification_type(&flags, CHECK_NULL);
if (locals[real_locals_size].is_category2()) { if (locals[real_locals_size].is_category2()) {
locals[real_locals_size + 1] = locals[real_locals_size + 1] =
locals[real_locals_size].to_category2_2nd(); locals[real_locals_size].to_category2_2nd();
@ -400,7 +402,7 @@ StackMapFrame* StackMapReader::next(
} }
check_verification_type_array_size( check_verification_type_array_size(
real_locals_size, max_locals, CHECK_VERIFY_(_verifier, NULL)); real_locals_size, max_locals, CHECK_VERIFY_(_verifier, NULL));
u2 stack_size = _stream->get_u2(THREAD); u2 stack_size = _stream->get_u2(CHECK_NULL);
int real_stack_size = 0; int real_stack_size = 0;
VerificationType* stack = NULL; VerificationType* stack = NULL;
if (stack_size > 0) { if (stack_size > 0) {
@ -408,7 +410,7 @@ StackMapFrame* StackMapReader::next(
THREAD, VerificationType, stack_size*2); THREAD, VerificationType, stack_size*2);
} }
for (i=0; i<stack_size; i++) { for (i=0; i<stack_size; i++) {
stack[real_stack_size] = parse_verification_type(NULL, THREAD); stack[real_stack_size] = parse_verification_type(NULL, CHECK_NULL);
if (stack[real_stack_size].is_category2()) { if (stack[real_stack_size].is_category2()) {
stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd(); stack[real_stack_size + 1] = stack[real_stack_size].to_category2_2nd();
++real_stack_size; ++real_stack_size;

View File

@ -416,12 +416,12 @@ address NativeLookup::lookup_base(const methodHandle& method, TRAPS) {
address entry = NULL; address entry = NULL;
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
entry = lookup_entry(method, THREAD); entry = lookup_entry(method, CHECK_NULL);
if (entry != NULL) return entry; if (entry != NULL) return entry;
// standard native method resolution has failed. Check if there are any // standard native method resolution has failed. Check if there are any
// JVM TI prefixes which have been applied to the native method name. // JVM TI prefixes which have been applied to the native method name.
entry = lookup_entry_prefixed(method, THREAD); entry = lookup_entry_prefixed(method, CHECK_NULL);
if (entry != NULL) return entry; if (entry != NULL) return entry;
// Native function not found, throw UnsatisfiedLinkError // Native function not found, throw UnsatisfiedLinkError

View File

@ -351,17 +351,14 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name,
if (message == NULL) { if (message == NULL) {
signature = vmSymbols::void_method_signature(); signature = vmSymbols::void_method_signature();
} else { } else {
// We want to allocate storage, but we can't do that if there's // There should be no pending exception. The caller is responsible for not calling
// a pending exception, so we preserve any pending exception // this with a pending exception.
// around the allocation. Handle incoming_exception;
// If we get an exception from the allocation, prefer that to
// the exception we are trying to build, or the pending exception.
// This is sort of like what PreserveExceptionMark does, except
// for the preferencing and the early returns.
Handle incoming_exception(thread, NULL);
if (thread->has_pending_exception()) { if (thread->has_pending_exception()) {
incoming_exception = Handle(thread, thread->pending_exception()); incoming_exception = Handle(thread, thread->pending_exception());
thread->clear_pending_exception(); thread->clear_pending_exception();
ResourceMark rm(thread);
assert(incoming_exception.is_null(), "Pending exception while throwing %s %s", name->as_C_string(), message);
} }
Handle msg; Handle msg;
if (to_utf8_safe == safe_to_utf8) { if (to_utf8_safe == safe_to_utf8) {
@ -371,6 +368,8 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name,
// Make a java string keeping the encoding scheme of the original string. // Make a java string keeping the encoding scheme of the original string.
msg = java_lang_String::create_from_platform_dependent_str(message, thread); msg = java_lang_String::create_from_platform_dependent_str(message, thread);
} }
// If we get an exception from the allocation, prefer that to
// the exception we are trying to build, or the pending exception (in product mode)
if (thread->has_pending_exception()) { if (thread->has_pending_exception()) {
Handle exception(thread, thread->pending_exception()); Handle exception(thread, thread->pending_exception());
thread->clear_pending_exception(); thread->clear_pending_exception();