src/share/vm/runtime/arguments.cpp
Print this page
*** 54,63 ****
--- 54,65 ----
#endif // INCLUDE_ALL_GCS
// Note: This is a special bug reporting site for the JVM
#define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
#define DEFAULT_JAVA_LAUNCHER "generic"
+ #define N_MAX_OPTIONS 64
+ #define OPTION_BUFFER_SIZE 1024
#define UNSUPPORTED_GC_OPTION(gc) \
do { \
if (gc) { \
if (FLAG_IS_CMDLINE(gc)) { \
*** 110,120 ****
--- 112,188 ----
SystemProperty *Arguments::_java_home = NULL;
SystemProperty *Arguments::_java_class_path = NULL;
SystemProperty *Arguments::_sun_boot_class_path = NULL;
char* Arguments::_ext_dirs = NULL;
+ // change the 0 on next line to 1 to enable argument tracing
+ #if 0
+ #define JVM_ARGS_ETRACE(x) x
+ #else
+ #define JVM_ARGS_ETRACE(x)
+ #endif
+ // Dump VM Option with a tag
+ void DumpOption(const JavaVMOption *option_p,
+ const int index, const char *tag) {
+ if (PrintVMOptions && Verbose) {
+ if (index >= 0) {
+ jio_fprintf(defaultStream::output_stream(),
+ "%s:[%d]='%s'\n", tag, index, option_p->optionString);
+ }
+ }
+ }
+
+ // Dump VM Option with a tag
+ void DumpVMOption(const JavaVMInitArgs* args_p,
+ const int index, const char *tag) {
+ if (PrintVMOptions && Verbose) {
+ if (args_p->options != NULL) {
+ if ((index >= 0) && (index < args_p->nOptions)) {
+ JavaVMOption *option_p = args_p->options + index;
+ jio_fprintf(defaultStream::output_stream(),
+ "%s:[%d]='%s'\n", tag, index, option_p->optionString);
+ }
+ }
+ }
+ }
+
+ // Dump VM Options with a tag
+ void DumpVMOptions(const JavaVMInitArgs* args_p, const char *tag) {
+ if (PrintVMOptions && Verbose) {
+ if (args_p->options != NULL) {
+ for (int index = 0; index < args_p->nOptions; index++) {
+ JavaVMOption *option_p = args_p->options + index;
+ jio_fprintf(defaultStream::output_stream(),
+ "%s:[%d]='%s'\n", tag, index, option_p->optionString);
+ }
+ }
+ }
+ }
+
+ // Free memory associated with an options list
+ void FreeVMOptions(JavaVMInitArgs **args_pp, const JavaVMInitArgs *args_base_p) {
+ assert(args_pp != NULL, "args_pp must not be NULL");
+ assert(*args_pp != NULL, "*args_pp must not be NULL");
+ if (args_base_p == (*args_pp)) {
+ // Do not free memory we did not allocate
+ return;
+ }
+ assert((*args_pp)->options != NULL, "(*args_pp)->options must not be NULL");
+ for (int index = 0; index < (*args_pp)->nOptions; index++) {
+ JavaVMOption *option_p = (*args_pp)->options + index;
+ if (option_p->optionString != NULL) {
+ os::free(option_p->optionString);
+ option_p->optionString = NULL;
+ }
+ }
+ os::free((void *)(*args_pp)->options);
+ (*args_pp)->options = NULL;
+ os::free((void *)(*args_pp));
+ (*args_pp) = NULL;
+ }
+
// Check if head of 'option' matches 'name', and sets 'tail' to the remaining
// part of the option string.
static bool match_option(const JavaVMOption *option, const char* name,
const char** tail) {
int len = (int)strlen(name);
*** 2642,2651 ****
--- 2710,2720 ----
Flag::Flags origin) {
// Remaining part of option string
const char* tail;
// iterate over arguments
+ DumpVMOptions(args, "Parse each");
for (int index = 0; index < args->nOptions; index++) {
bool is_absolute_path = false; // for -agentpath vs -agentlib
const JavaVMOption* option = args->options + index;
*** 3275,3286 ****
} else if (match_option(option, "-XX:-CreateMinidumpOnCrash")) {
FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false);
jio_fprintf(defaultStream::output_stream(),
"CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is off\n");
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
! // Skip -XX:Flags= since that case has already been handled
! if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
if (!process_argument(tail, args->ignoreUnrecognized, origin)) {
return JNI_EINVAL;
}
}
// Unknown option
--- 3344,3357 ----
} else if (match_option(option, "-XX:-CreateMinidumpOnCrash")) {
FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false);
jio_fprintf(defaultStream::output_stream(),
"CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is off\n");
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
! // Skip -XX:Flags= and -XX:VMOptionsFile= since those cases have
! // already been handled
! if ((strncmp(tail, "Flags=", strlen("Flags=")) != 0) &&
! (strncmp(tail, "VMOptionsFile=", strlen("VMOptionsFile=")) != 0)) {
if (!process_argument(tail, args->ignoreUnrecognized, origin)) {
return JNI_EINVAL;
}
}
// Unknown option
*** 3696,3721 ****
return false;
}
#endif // PRODUCT
! // Parse entry point called from JNI_CreateJavaVM
! jint Arguments::parse(const JavaVMInitArgs* args) {
! // Remaining part of option string
! const char* tail;
! // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
const char* hotspotrc = ".hotspotrc";
bool settings_file_specified = false;
bool needs_hotspotrc_warning = false;
const char* flags_file;
int index;
for (index = 0; index < args->nOptions; index++) {
const JavaVMOption *option = args->options + index;
if (ArgumentsExt::process_options(option)) {
continue;
}
if (match_option(option, "-XX:Flags=", &tail)) {
flags_file = tail;
--- 3767,4331 ----
return false;
}
#endif // PRODUCT
! jint Arguments::alloc_JVM_options_list(const int needed_slots,
! const int version,
! struct JavaVMInitArgs **ret_args_head) {
! assert(needed_slots > 0, "needed_slots must greater than zero");
! assert(ret_args_head != NULL, "ret_args_head must not be NULL");
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Allocating %d option slots\n", needed_slots));
! JavaVMInitArgs *new_args_head =
! (JavaVMInitArgs *) os::malloc(sizeof (JavaVMInitArgs), mtInternal);
! if (new_args_head == NULL) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not allocate arguments list head\n");
! return JNI_ENOMEM;
! }
! memset(new_args_head, 0, sizeof (struct JavaVMInitArgs));
! int bytes_needed = needed_slots * (sizeof (struct JavaVMOption));
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "to allocate options list %d %d\n",
! needed_slots, bytes_needed));
!
! JavaVMOption *new_options_head =
! (struct JavaVMOption *) os::malloc(bytes_needed, mtInternal);
!
! if (new_options_head == NULL) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not allocate options list with %d entries"
! " and %d bytes\n",
! needed_slots, bytes_needed);
!
! os::free(new_args_head);
! new_args_head = NULL;
!
! return JNI_ENOMEM;
! }
!
! memset(new_options_head, 0, bytes_needed);
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "allocation need for options list %d %d\n",
! needed_slots, bytes_needed));
!
! // Assemble the args object
! new_args_head->options = new_options_head;
! new_args_head->nOptions = 0;
! new_args_head->version = version;
!
! // Return newly allocated but not populated options list
! *ret_args_head = new_args_head;
!
! return JNI_OK;
! }
!
! // Copy num_slots NULL separated JVM options from buffer to
! // new_options[0] through new_options[num_slots - 1].
! // The byte_cnt includes null termination.
! jint Arguments::copy_JVM_options_from_buf(const char *buffer,
! const size_t byte_cnt,
! const int num_slots,
! int *cur_slot_p,
! struct JavaVMOption *new_options) {
!
! assert(buffer != NULL, "buffer must not be NULL");
! assert(byte_cnt > 1, "byte_cnt must be greater than one");
! assert(num_slots > 0, "num_slots must be greater than zero");
! assert(cur_slot_p != NULL, "cur_slot_p must not be NULL");
! assert(new_options != NULL, "new_options must not be NULL");
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Copying %d options from buffer\n",
! num_slots));
! (*cur_slot_p) = 0;
! const char *head = buffer;
! const char *tail = buffer + byte_cnt - 1;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Copying option %d %d %d\n",
! byte_cnt, *cur_slot_p, num_slots));
!
! while ((head < tail) && (*cur_slot_p < num_slots)) {
! // Skip null character separator(s)
! while ((head < tail) && (*head == '\0')) {
! head++;
! }
!
! if (head >= tail) {
! break;
! }
!
! // save a copy of the string in the options list
! new_options[(*cur_slot_p)].optionString =
! os::strdup_check_oom(head, mtInternal);
!
! if (new_options[(*cur_slot_p)].optionString == NULL) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not copy file option string '%s'\n", head);
! return JNI_ENOMEM;
! }
!
! DumpOption(new_options, *cur_slot_p, "copy");
! const char *dummy;
! if (match_option(&new_options[(*cur_slot_p)],
! "-XX:VMOptionsFile=", &dummy)) {
! jio_fprintf(defaultStream::error_stream(),
! "VM options file is only supported on the command line\n");
!
! (*cur_slot_p)++; // We do not need this slot, but count it on the
! // list so the error handling can clean this up
! return JNI_EINVAL;
! }
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Copying option %d %d %s\n",
! *cur_slot_p,
! num_slots,
! new_options[(*cur_slot_p)].optionString));
! (*cur_slot_p)++; // Done with current slot
!
! while ((head < tail) && (*head != '\0')) {
! head++;
! }
! }
!
! return JNI_OK;
! }
!
! // Parse the JVM options from file_name into ret_buff. The
! // options in ret_buff are NULL separated in order to preserve
! // any embedded white space that was quoted in file_name.
! jint Arguments::parse_JVM_options_file(const char *file_name,
! char **ret_buff,
! size_t *ret_bytes,
! int *ret_opt_cnt) {
!
! assert(file_name != NULL, "file_name must not be NULL.");
! assert(ret_buff != NULL, "ret_buff must not be NULL.");
! assert(ret_bytes != NULL, "ret_bytes must not be NULL.");
! assert(ret_opt_cnt != NULL, "ret_opt_cnt must not be NULL.");
!
! // Default all return params to not return data
! *ret_buff = NULL;
! *ret_bytes = 0;
! *ret_opt_cnt = 0;
!
! int fd = ::open(file_name, O_RDONLY);
! if (fd < 0) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not open options file '%s'\n",
! file_name);
! return JNI_ERR;
! }
!
! // '+ 1' for NULL termination even with max bytes
! int bytes_alloc = OPTION_BUFFER_SIZE + 1;
!
! char *buf = (char *)os::malloc(bytes_alloc, mtInternal);
!
! if (buf == NULL) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not allocate read buffer for options file parse\n");
! os::close(fd);
! return JNI_ENOMEM;
! }
!
! memset(buf, 0, (unsigned)bytes_alloc);
!
! // Fill buffer
! // Use ::read() instead of os::read because os::read()
! // might do a thead state transition
! // and it is too early for that here
!
! int bytes_read = ::read(fd, (void *)buf,
! (unsigned)bytes_alloc);
! if (bytes_read < 0) {
! os::free(buf);
! buf = NULL;
! os::close(fd);
! jio_fprintf(defaultStream::error_stream(),
! "Could not read options file '%s'\n", file_name);
! return JNI_ERR;
! }
!
! if (bytes_read == 0) {
! // tell caller there is no option data and that is ok
! os::free(buf);
! buf = NULL;
! os::close(fd);
! return JNI_OK;
! }
!
! // file is larger than OPTION_BUFFER_SIZE
! if (bytes_read > bytes_alloc - 1) {
! os::free(buf);
! buf = NULL;
! os::close(fd);
! jio_fprintf(defaultStream::error_stream(),
! "Options file '%s' is larger than %d bytes.\n",
! file_name, bytes_alloc - 1);
! return JNI_EINVAL;
! }
!
! os::close(fd);
!
! // some pointers to help with parsing
! char *buf_end = buf + bytes_read;
! char *cur_token_head = buf;
! char *wrt = buf;
! char *rd = buf;
!
! // count tokens
! int token_cnt = 0;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Parse buf loop > '%s'\n",
! buf));
! // parse all options
! while (rd < buf_end) {
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Parse buf loop white > >%s<\n", rd));
! // skip leading white space from the input string
! while (rd < buf_end && iswhite(*rd)) {
! rd++;
! }
!
! if (rd >= buf_end) {
! break;
! }
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Parse next token > %s\n", rd));
! // Remember this is where we found the head of the token.
! cur_token_head = wrt;
!
! // Tokens are strings of non white space characters separated
! // by one or more white spaces.
! while (rd < buf_end && !iswhite(*rd)) {
! if (*rd == '\'' || *rd == '"') { // handle a quoted string
! int quote = *rd; // matching quote to look for
! rd++; // don't copy open quote
! while (rd < buf_end && *rd != quote) {
! // include everything (even spaces)
! // up until the close quote
! *wrt++ = *rd++; // copy to option string
! }
!
! if (rd < buf_end) {
! rd++; // don't copy close quote
! } else {
! // did not see closing quote
! jio_fprintf(defaultStream::error_stream(),
! "Unmatched quote in '%s'\n", file_name);
! os::free(buf);
! buf = NULL;
! return JNI_EINVAL;
! }
! } else {
! *wrt++ = *rd++; // copy to option string
! }
! }
!
! // steal a white space character and set it to NULL
! *wrt++ = '\0';
! token_cnt++;
! // We now have a complete token
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Current parsed token > %s\n",
! cur_token_head));
!
! rd++; // Advance to next character
! }
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Done parsing tokens > %d\n",
! token_cnt));
!
! if (token_cnt > N_MAX_OPTIONS) {
! jio_fprintf(defaultStream::error_stream(),
! "Options file has more than %d options.\n",
! N_MAX_OPTIONS);
! os::free(buf);
! buf = NULL;
! return JNI_EINVAL;
! }
!
! // Pass the data the back to the caller
! *ret_buff = buf;
! *ret_opt_cnt = token_cnt;
! *ret_bytes = (size_t)(wrt - buf);
!
! return JNI_OK;
! }
!
! // Merge options from a JVM options file with the options provided
! // by argsin and return the merge results via *argsout. If the
! // '-XX:VMOptionsFile=...' option is not specified on the command
! // line, then there is nothing to merge and *argsout is set to NULL.
! jint Arguments::merge_JVM_options_file(const JavaVMInitArgs *argsin,
! JavaVMInitArgs **argsout) {
!
! assert(argsin != NULL, "argsin should not be NULL");
! assert(argsout != NULL, "argsout should not be NULL");
!
! JavaVMInitArgs *new_args_head = NULL;
! char *options_file = NULL;
! bool options_file_found = false;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Found %d existing option(s)\n",
! argsin->nOptions));
!
! // Take a peak at options passed in, looking for an options file
! int old_index = 0;
! const char *tail = NULL;
! while (old_index < argsin->nOptions) {
! JavaVMOption *option = argsin->options + old_index;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Found existing option %s\n",
! option->optionString));
!
! if (match_option(option, "-XX:VMOptionsFile=", &tail)) {
! // Only one options file allowed on the command line.
! if (options_file_found) {
! jio_fprintf(defaultStream::error_stream(),
! "Only one VM Options file is supported "
! "on the command line\n");
!
! *argsout = NULL;
! os::free(options_file);
! options_file = NULL;
! return JNI_EINVAL;
! } else {
! options_file_found = true;
! }
! options_file = os::strdup_check_oom(tail, mtInternal);
! if (options_file == NULL) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not copy options file path\n");
!
! return JNI_ENOMEM;
! }
! }
! old_index++;
! }
!
! // No option file specified so nothing more to do
! if (options_file == NULL) {
! *argsout = NULL;
! return JNI_OK;
! }
!
! DumpVMOptions(argsin, "Premerge");
!
! char *buff; // Contents of the options file
! size_t byte_cnt = 0; // bytes in buffer
! int file_slots = 0; // # options found in file
!
! // We have requested an options file, so we need to read it
! // and do a simple white space parse on it.
! jint result = parse_JVM_options_file(options_file,
! &buff,
! &byte_cnt,
! &file_slots);
! if (result != JNI_OK) {
! // the option file processing failed
! jio_fprintf(defaultStream::error_stream(),
! "Options file '%s', parsing error\n",
! options_file);
!
! os::free(options_file);
! options_file = NULL;
! *argsout = NULL;
! return result;
! }
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Found %d bytes and %d options\n",
! byte_cnt, file_slots));
! // no options but that is ok
! if (file_slots == 0) {
! os::free(options_file);
! options_file = NULL;
! *argsout = NULL;
! return JNI_OK;
! }
!
! // Combine cmd line slot count and the options file slots passed to us
! // We need one less because the "-XX:VMOptionsFile" is not included
! // in the new list.
! int num_slots = argsin->nOptions + file_slots - 1;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Allocate option list with %d slots, %d file,"
! " %d exist\n",
! num_slots, file_slots, argsin->nOptions));
!
! // Allocate a new option list
! result = Arguments::alloc_JVM_options_list(num_slots, argsin->version,
! &new_args_head);
! if (result != JNI_OK) {
! // the option file processing failed
! jio_fprintf(defaultStream::error_stream(),
! "Memory error in options processing\n");
! os::free(buff);
! buff = NULL;
! os::free(options_file);
! options_file = NULL;
! *argsout = NULL;
! return result;
! }
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "merge option list > %d %d\n",
! argsin->nOptions, num_slots));
!
! old_index = 0;
! while ((old_index < argsin->nOptions) &&
! (new_args_head->nOptions < num_slots)) {
!
! JavaVMOption *old_option_p = argsin->options + old_index;
! JavaVMOption *new_option_p = new_args_head->options +
! new_args_head->nOptions;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "Merge option %s old %d new %d\n",
! old_option_p->optionString,
! old_index, new_args_head->nOptions));
!
! // Allow the VM option tracing to come on early.
! if (match_option(old_option_p, "-XX:+PrintVMOptions")) {
! PrintVMOptions = true;
! }
!
! if (match_option(old_option_p, "-XX:VMOptionsFile=", &tail)) {
! int file_slots_used = 0;
! result = Arguments::copy_JVM_options_from_buf(buff,
! byte_cnt,
! file_slots,
! &file_slots_used,
! new_option_p);
! // Update option count for success and failure.
! // The initialized count is required to free the new args object
! new_args_head->nOptions += file_slots_used;
!
! if (result != JNI_OK) {
! // the option file processing failed
! jio_fprintf(defaultStream::error_stream(),
! "Options copy error '%s'\n",
! options_file);
!
! os::free(buff);
! buff = NULL;
! os::free(options_file);
! options_file = NULL;
! FreeVMOptions(&new_args_head, argsin);
! *argsout = NULL;
! return result;
! }
!
! old_index++; // Next slot in the input list
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "old %d new %d file %d\n",
! old_index,
! new_args_head->nOptions,
! file_slots));
! } else {
! // We only increment the index if the option preexisted.
! // The options file copying increments the index too
! new_option_p->optionString =
! os::strdup_check_oom(old_option_p->optionString, mtInternal);
!
! if (new_option_p->optionString == NULL) {
! jio_fprintf(defaultStream::error_stream(),
! "Could not allocate command option string '%s'\n",
! old_option_p->optionString);
!
! FreeVMOptions(&new_args_head, argsin);
! *argsout = NULL;
! os::free(buff);
! buff = NULL;
! os::free(options_file);
! options_file = NULL;
! return JNI_ENOMEM;
! }
!
! new_option_p->extraInfo = NULL;
!
! DumpOption(old_option_p, old_index, "old");
! DumpOption(new_option_p, new_args_head->nOptions, "new");
!
! DumpVMOption(new_args_head, new_args_head->nOptions, "new");
! DumpVMOption(argsin, old_index, "old");
! old_index++; // Next slot in the input list
! new_args_head->nOptions++; // Next slot in the new args list
! }
!
! }
!
! os::free(buff);
! buff = NULL;
! os::free(options_file);
! options_file = NULL;
!
! JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
! "trace final num ops %d\n",
! new_args_head->nOptions));
!
! // We have a list of options that is ready to be returned to the caller.
! *argsout = new_args_head;
! DumpVMOptions(*argsout, "Postmerge");
! return JNI_OK;
! }
!
! // Parse entry point called from JNI_CreateJavaVM
!
! jint Arguments::parse(const struct JavaVMInitArgs *argsin) {
const char* hotspotrc = ".hotspotrc";
bool settings_file_specified = false;
bool needs_hotspotrc_warning = false;
+ // If flag "-XX:Flags=flags-file" is used it will be the
+ // first option to be processed.
const char* flags_file;
int index;
+ struct JavaVMInitArgs *args = NULL;
+
+ jint result = Arguments::merge_JVM_options_file(argsin, &args);
+ if (result != JNI_OK) {
+ // A more specific error message has been printed to the error stream
+ jio_fprintf(defaultStream::error_stream(),
+ "Options merge error, VM will exit\n");
+ vm_exit(1);
+ }
+
+ if (args == NULL) {
+ args = (JavaVMInitArgs *)argsin;
+ JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
+ "no file options merged\n"));
+ } else {
+ JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
+ "file options merged\n"));
+ }
+
+ DumpVMOptions(args, "Final Command Line");
+ const char* tail = NULL;
for (index = 0; index < args->nOptions; index++) {
const JavaVMOption *option = args->options + index;
+ if (match_option(option, "-XX:VMOptionsFile=", &tail)) {
+ // -XX:VMOptionsFile= can only appear here if the option file
+ // is empty or if there are no options to process, ignore it.
+ continue;
+ }
if (ArgumentsExt::process_options(option)) {
continue;
}
if (match_option(option, "-XX:Flags=", &tail)) {
flags_file = tail;
*** 3780,3795 ****
--- 4390,4407 ----
}
// Parse specified settings file
if (settings_file_specified) {
if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
+ FreeVMOptions(&args, argsin);
return JNI_EINVAL;
}
} else {
#ifdef ASSERT
// Parse default .hotspotrc settings file
if (!process_settings_file(".hotspotrc", false, args->ignoreUnrecognized)) {
+ FreeVMOptions(&args, argsin);
return JNI_EINVAL;
}
#else
struct stat buf;
if (os::stat(hotspotrc, &buf) == 0) {
*** 3806,3820 ****
}
}
}
// Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
! jint result = parse_vm_init_args(args);
if (result != JNI_OK) {
return result;
}
// Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
SharedArchivePath = get_shared_archive_path();
if (SharedArchivePath == NULL) {
return JNI_ENOMEM;
}
--- 4418,4435 ----
}
}
}
// Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
! result = parse_vm_init_args(args);
if (result != JNI_OK) {
+ FreeVMOptions(&args, argsin);
return result;
}
+ FreeVMOptions(&args, argsin);
+
// Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
SharedArchivePath = get_shared_archive_path();
if (SharedArchivePath == NULL) {
return JNI_ENOMEM;
}