Skip to content
This repository was archived by the owner on Sep 2, 2022. It is now read-only.

Commit f662127

Browse files
author
Markus Grönlund
committed
8270491: SEGV at read_string_field(oopDesc*, char const*, JavaThread*)+0x54
Reviewed-by: egahlin
1 parent cea7bc2 commit f662127

File tree

2 files changed

+53
-24
lines changed

2 files changed

+53
-24
lines changed

src/hotspot/share/jfr/dcmd/jfrDcmds.cpp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,19 @@ static void print_message(outputStream* output, oop content, TRAPS) {
154154
}
155155

156156
static void log(oop content, TRAPS) {
157-
LogMessage(jfr,startup) msg;
158-
objArrayOop lines = objArrayOop(content);
159-
assert(lines != NULL, "invariant");
160-
assert(lines->is_array(), "must be array");
161-
const int length = lines->length();
162-
for (int i = 0; i < length; ++i) {
163-
const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
164-
if (text == NULL) {
165-
// An oome has been thrown and is pending.
166-
break;
167-
}
168-
msg.info("%s", text);
157+
LogMessage(jfr,startup) msg;
158+
objArrayOop lines = objArrayOop(content);
159+
assert(lines != NULL, "invariant");
160+
assert(lines->is_array(), "must be array");
161+
const int length = lines->length();
162+
for (int i = 0; i < length; ++i) {
163+
const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
164+
if (text == NULL) {
165+
// An oome has been thrown and is pending.
166+
break;
169167
}
168+
msg.info("%s", text);
169+
}
170170
}
171171

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

218+
JfrDCmd::JfrDCmd(outputStream* output, bool heap, int num_arguments) : DCmd(output, heap), _args(NULL), _num_arguments(num_arguments), _delimiter('\0') {}
219+
218220
void JfrDCmd::invoke(JfrJavaArguments& method, TRAPS) const {
219221
JavaValue constructor_result(T_OBJECT);
220222
JfrJavaArguments constructor_args(&constructor_result);
@@ -274,6 +276,20 @@ void JfrDCmd::print_help(const char* name) const {
274276
handle_dcmd_result(output(), result.get_oop(), DCmd_Source_MBean, thread);
275277
}
276278

279+
static void initialize_dummy_descriptors(GrowableArray<DCmdArgumentInfo*>* array) {
280+
assert(array != NULL, "invariant");
281+
DCmdArgumentInfo * const dummy = new DCmdArgumentInfo(NULL,
282+
NULL,
283+
NULL,
284+
NULL,
285+
false,
286+
true, // a DcmdFramework "option"
287+
false);
288+
for (int i = 0; i < array->max_length(); ++i) {
289+
array->append(dummy);
290+
}
291+
}
292+
277293
// Since the DcmdFramework does not support dynamically allocated strings,
278294
// we keep them in a thread local arena. The arena is reset between invocations.
279295
static THREAD_LOCAL Arena* dcmd_arena = NULL;
@@ -340,16 +356,29 @@ static DCmdArgumentInfo* create_info(oop argument, TRAPS) {
340356
GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const {
341357
static const char signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
342358
JavaThread* thread = JavaThread::current();
359+
GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
343360
JavaValue result(T_OBJECT);
344361
JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
345362
invoke(getArgumentInfos, thread);
363+
if (thread->has_pending_exception()) {
364+
// Most likely an OOME, but the DCmdFramework is not the best place to handle it.
365+
// We handle it locally by clearing the exception and returning an array with dummy descriptors.
366+
// This lets the MBean server initialization routine complete successfully,
367+
// but this particular command will have no argument descriptors exposed.
368+
// Hence we postpone, or delegate, handling of OOME's to code that is better suited.
369+
log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
370+
thread->clear_pending_exception();
371+
initialize_dummy_descriptors(array);
372+
assert(array->length() == _num_arguments, "invariant");
373+
return array;
374+
}
346375
objArrayOop arguments = objArrayOop(result.get_oop());
347376
assert(arguments != NULL, "invariant");
348377
assert(arguments->is_array(), "must be array");
349-
GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>();
350-
const int length = arguments->length();
378+
const int num_arguments = arguments->length();
379+
assert(num_arguments == _num_arguments, "invariant");
351380
prepare_dcmd_string_arena();
352-
for (int i = 0; i < length; ++i) {
381+
for (int i = 0; i < num_arguments; ++i) {
353382
DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
354383
assert(dai != NULL, "invariant");
355384
array->append(dai);

src/hotspot/share/jfr/dcmd/jfrDcmds.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,23 @@ class JfrJavaArguments;
3131
class JfrDCmd : public DCmd {
3232
private:
3333
const char* _args;
34+
const int _num_arguments;
3435
char _delimiter;
36+
protected:
37+
JfrDCmd(outputStream* output, bool heap, int num_arguments);
38+
virtual const char* javaClass() const = 0;
39+
void invoke(JfrJavaArguments& method, TRAPS) const;
3540
public:
36-
JfrDCmd(outputStream* output, bool heap) : DCmd(output,heap), _args(NULL), _delimiter('\0') {}
37-
3841
virtual void execute(DCmdSource source, TRAPS);
3942
virtual void print_help(const char* name) const;
4043
virtual GrowableArray<const char*>* argument_name_array() const;
4144
virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array() const;
4245
virtual void parse(CmdLine* line, char delim, TRAPS);
43-
protected:
44-
virtual const char* javaClass() const = 0;
45-
void invoke(JfrJavaArguments& method, TRAPS) const;
4646
};
4747

4848
class JfrStartFlightRecordingDCmd : public JfrDCmd {
4949
public:
50-
JfrStartFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
50+
JfrStartFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}
5151

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

7373
class JfrDumpFlightRecordingDCmd : public JfrDCmd {
7474
public:
75-
JfrDumpFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
75+
JfrDumpFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}
7676

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

9898
class JfrCheckFlightRecordingDCmd : public JfrDCmd {
9999
public:
100-
JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
100+
JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}
101101

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

123123
class JfrStopFlightRecordingDCmd : public JfrDCmd {
124124
public:
125-
JfrStopFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap) {}
125+
JfrStopFlightRecordingDCmd(outputStream* output, bool heap) : JfrDCmd(output, heap, num_arguments()) {}
126126

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

0 commit comments

Comments
 (0)