Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8270491: SEGV at read_string_field(oopDesc*, char const*, JavaThread*…
…)+0x54

Reviewed-by: egahlin
  • Loading branch information
Markus Grönlund committed Jul 27, 2021
1 parent cea7bc2 commit f662127390eac6d44581ffca444556d236983314
Showing 2 changed files with 53 additions and 24 deletions.
@@ -154,19 +154,19 @@ static void print_message(outputStream* output, oop content, TRAPS) {
}

static void log(oop content, TRAPS) {
LogMessage(jfr,startup) msg;
objArrayOop lines = objArrayOop(content);
assert(lines != NULL, "invariant");
assert(lines->is_array(), "must be array");
const int length = lines->length();
for (int i = 0; i < length; ++i) {
const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
if (text == NULL) {
// An oome has been thrown and is pending.
break;
}
msg.info("%s", text);
LogMessage(jfr,startup) msg;
objArrayOop lines = objArrayOop(content);
assert(lines != NULL, "invariant");
assert(lines->is_array(), "must be array");
const int length = lines->length();
for (int i = 0; i < length; ++i) {
const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
if (text == NULL) {
// An oome has been thrown and is pending.
break;
}
msg.info("%s", text);
}
}

static void handle_dcmd_result(outputStream* output,
@@ -215,6 +215,8 @@ static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
return args->result()->get_oop();
}

JfrDCmd::JfrDCmd(outputStream* output, bool heap, int num_arguments) : DCmd(output, heap), _args(NULL), _num_arguments(num_arguments), _delimiter('\0') {}

void JfrDCmd::invoke(JfrJavaArguments& method, TRAPS) const {
JavaValue constructor_result(T_OBJECT);
JfrJavaArguments constructor_args(&constructor_result);
@@ -274,6 +276,20 @@ void JfrDCmd::print_help(const char* name) const {
handle_dcmd_result(output(), result.get_oop(), DCmd_Source_MBean, thread);
}

static void initialize_dummy_descriptors(GrowableArray<DCmdArgumentInfo*>* array) {
assert(array != NULL, "invariant");
DCmdArgumentInfo * const dummy = new DCmdArgumentInfo(NULL,
NULL,
NULL,
NULL,
false,
true, // a DcmdFramework "option"
false);
for (int i = 0; i < array->max_length(); ++i) {
array->append(dummy);
}
}

// Since the DcmdFramework does not support dynamically allocated strings,
// we keep them in a thread local arena. The arena is reset between invocations.
static THREAD_LOCAL Arena* dcmd_arena = NULL;
@@ -340,16 +356,29 @@ static DCmdArgumentInfo* create_info(oop argument, TRAPS) {
GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const {
static const char signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
JavaThread* thread = JavaThread::current();
GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
JavaValue result(T_OBJECT);
JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
invoke(getArgumentInfos, thread);
if (thread->has_pending_exception()) {
// Most likely an OOME, but the DCmdFramework is not the best place to handle it.
// We handle it locally by clearing the exception and returning an array with dummy descriptors.
// This lets the MBean server initialization routine complete successfully,
// but this particular command will have no argument descriptors exposed.
// Hence we postpone, or delegate, handling of OOME's to code that is better suited.
log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
thread->clear_pending_exception();
initialize_dummy_descriptors(array);
assert(array->length() == _num_arguments, "invariant");
return array;
}
objArrayOop arguments = objArrayOop(result.get_oop());
assert(arguments != NULL, "invariant");
assert(arguments->is_array(), "must be array");
GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>();
const int length = arguments->length();
const int num_arguments = arguments->length();
assert(num_arguments == _num_arguments, "invariant");
prepare_dcmd_string_arena();
for (int i = 0; i < length; ++i) {
for (int i = 0; i < num_arguments; ++i) {
DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
assert(dai != NULL, "invariant");
array->append(dai);
@@ -31,23 +31,23 @@ class JfrJavaArguments;
class JfrDCmd : public DCmd {
private:
const char* _args;
const int _num_arguments;
char _delimiter;
protected:
JfrDCmd(outputStream* output, bool heap, int num_arguments);
virtual const char* javaClass() const = 0;
void invoke(JfrJavaArguments& method, TRAPS) const;
public:
JfrDCmd(outputStream* output, bool heap) : DCmd(output,heap), _args(NULL), _delimiter('\0') {}

virtual void execute(DCmdSource source, TRAPS);
virtual void print_help(const char* name) const;
virtual GrowableArray<const char*>* argument_name_array() const;
virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array() const;
virtual void parse(CmdLine* line, char delim, TRAPS);
protected:
virtual const char* javaClass() const = 0;
void invoke(JfrJavaArguments& method, TRAPS) const;
};

class JfrStartFlightRecordingDCmd : public JfrDCmd {
public:
JfrStartFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
JfrStartFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}

static const char* name() {
return "JFR.start";
@@ -72,7 +72,7 @@ class JfrStartFlightRecordingDCmd : public JfrDCmd {

class JfrDumpFlightRecordingDCmd : public JfrDCmd {
public:
JfrDumpFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
JfrDumpFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}

static const char* name() {
return "JFR.dump";
@@ -97,7 +97,7 @@ class JfrDumpFlightRecordingDCmd : public JfrDCmd {

class JfrCheckFlightRecordingDCmd : public JfrDCmd {
public:
JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}

static const char* name() {
return "JFR.check";
@@ -122,7 +122,7 @@ class JfrCheckFlightRecordingDCmd : public JfrDCmd {

class JfrStopFlightRecordingDCmd : public JfrDCmd {
public:
JfrStopFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
JfrStopFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}

static const char* name() {
return "JFR.stop";

1 comment on commit f662127

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on f662127 Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.