8212883: Setting a double manageable flag with jcmd/jinfo crashes the JVM
authortonyp
Mon, 05 Nov 2018 14:00:52 -0500
changeset 52417 439b4a9b5a2e
parent 52416 1fc8166e28a2
child 52418 c2d35a0c5611
8212883: Setting a double manageable flag with jcmd/jinfo crashes the JVM Reviewed-by: dholmes, gziemski, stuefe
src/hotspot/share/services/writeableFlags.cpp
src/hotspot/share/services/writeableFlags.hpp
--- a/src/hotspot/share/services/writeableFlags.cpp	Mon Nov 05 12:27:38 2018 -0600
+++ b/src/hotspot/share/services/writeableFlags.cpp	Mon Nov 05 14:00:52 2018 -0500
@@ -116,7 +116,7 @@
 JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   int value;
 
-  if (sscanf(arg, "%d", &value)) {
+  if (sscanf(arg, "%d", &value) == 1) {
     return set_int_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an integer");
@@ -133,7 +133,7 @@
 JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   uint value;
 
-  if (sscanf(arg, "%u", &value)) {
+  if (sscanf(arg, "%u", &value) == 1) {
     return set_uint_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned integer");
@@ -150,7 +150,7 @@
 JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   intx value;
 
-  if (sscanf(arg, INTX_FORMAT, &value)) {
+  if (sscanf(arg, INTX_FORMAT, &value) == 1) {
     return set_intx_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an integer");
@@ -167,7 +167,7 @@
 JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   uintx value;
 
-  if (sscanf(arg, UINTX_FORMAT, &value)) {
+  if (sscanf(arg, UINTX_FORMAT, &value) == 1) {
     return set_uintx_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned integer");
@@ -184,7 +184,7 @@
 JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   uint64_t value;
 
-  if (sscanf(arg, UINT64_FORMAT, &value)) {
+  if (sscanf(arg, UINT64_FORMAT, &value) == 1) {
     return set_uint64_t_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned 64-bit integer");
@@ -201,7 +201,7 @@
 JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   size_t value;
 
-  if (sscanf(arg, SIZE_FORMAT, &value)) {
+  if (sscanf(arg, SIZE_FORMAT, &value) == 1) {
     return set_size_t_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned integer");
@@ -214,6 +214,23 @@
   return err;
 }
 
+// set a double global flag
+JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
+  double value;
+
+  if (sscanf(arg, "%lf", &value) == 1) {
+    return set_double_flag(name, value, origin, err_msg);
+  }
+  err_msg.print("flag value must be a double");
+  return JVMFlag::WRONG_FORMAT;
+}
+
+JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
+  JVMFlag::Error err = JVMFlag::doubleAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
+}
+
 // set a string global flag using value from AttachOperation
 JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
   JVMFlag::Error err = JVMFlag::ccstrAtPut((char*)name, &value, origin);
@@ -286,6 +303,8 @@
     return set_uint64_t_flag(f->_name, flag_value, origin, err_msg);
   } else if (f->is_size_t()) {
     return set_size_t_flag(f->_name, flag_value, origin, err_msg);
+  } else if (f->is_double()) {
+    return set_double_flag(f->_name, flag_value, origin, err_msg);
   } else if (f->is_ccstr()) {
     return set_ccstr_flag(f->_name, flag_value, origin, err_msg);
   } else {
@@ -319,6 +338,9 @@
   } else if (f->is_size_t()) {
     size_t svalue = (size_t)new_value.j;
     return set_size_t_flag(f->_name, svalue, origin, err_msg);
+  } else if (f->is_double()) {
+    double dvalue = (double)new_value.d;
+    return set_double_flag(f->_name, dvalue, origin, err_msg);
   } else if (f->is_ccstr()) {
     oop str = JNIHandles::resolve_external_guard(new_value.l);
     if (str == NULL) {
--- a/src/hotspot/share/services/writeableFlags.hpp	Mon Nov 05 12:27:38 2018 -0600
+++ b/src/hotspot/share/services/writeableFlags.hpp	Mon Nov 05 14:00:52 2018 -0500
@@ -52,6 +52,8 @@
   static JVMFlag::Error set_uint64_t_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
   // set a size_t global flag using value from AttachOperation
   static JVMFlag::Error set_size_t_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
+  // set a double global flag using value from AttachOperation
+  static JVMFlag::Error set_double_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
   // set a boolean global flag
   static JVMFlag::Error set_bool_flag(const char* name, bool value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
   // set a int global flag
@@ -66,6 +68,8 @@
   static JVMFlag::Error set_uint64_t_flag(const char* name, uint64_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
   // set a size_t global flag using value from AttachOperation
   static JVMFlag::Error set_size_t_flag(const char* name, size_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
+  // set a double global flag using value from AttachOperation
+  static JVMFlag::Error set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);
   // set a string global flag
   static JVMFlag::Error set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg);