JDK-8129855 : -XX:+IgnoreUnrecognizedVMOptions hides out of range VM options.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-06-25
  • Updated: 2023-07-21
  • Resolved: 2015-10-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b93Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Previously, VM failed in case of improperly option and  -XX:+IgnoreUnrecognizedVMOptions flag passed as options.

Now -XX:+IgnoreUnrecognizedVMOptions hides improperly specified VM options. Example:

JDK 9 b66:

java -XX:MinTLABSize=0
MinTLABSize of 0 is invalid; must be at least 1
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit

The same message with -XX:+IgnoreUnrecognizedVMOptions.

New JDK (nightly build):

The same behavior (VM exits with error message) as in previously promoted JDK with new message:
java -XX:-IgnoreUnrecognizedVMOptions -XX:MinTLABSize=0 -version
size_t MinTLABSize=0 is outside the allowed range [ 1 ... 4294967295 ]
Improperly specified VM option 'MinTLABSize=0'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

JDK continues to work with out-of-range message:
java -XX:+IgnoreUnrecognizedVMOptions -XX:MinTLABSize=0 -version
size_t MinTLABSize=0 is outside the allowed range [ 1 ... 4294967295 ]
java version "1.9.0-internal-fastdebug"
Java(TM) SE Runtime Environment (build 1.9.0-internal-fastdebug-20150624183527.jesper.main2rt-b00)
Java HotSpot(TM) Server VM (build 1.9.0-internal-fastdebug-20150624183527.jesper.main2rt-b00, mixed mode)


Comments
URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/0314c31d9c3e User: lana Date: 2015-11-18 23:53:22 +0000
18-11-2015

RULE "gc/arguments/TestTargetSurvivorRatioFlag.java" Exception java.lang.RuntimeException: Expected to get exit value of [1]
04-11-2015

URL: http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/rev/0314c31d9c3e User: coleenp Date: 2015-10-23 20:10:46 +0000
23-10-2015

I am about to file a new bug, as Michail suggested. Latest HS-Runtime nightly has this mismatch issue, causing 16 "New" failures.
17-09-2015

Nikita, you are right, it was made by mistake. If we cannot add rules to this CR for correct Aurora's matching, I can create one new CR for storing all of these rules for matching in Aurora. So this issues is used by developers, separate issue will be used for testing and matching purposes.
16-09-2015

In the history for this bug I see: Michail Chernov made changes - 2015-06-25 15:28 Link This issue backport of JDK-8129840 [ JDK-8129840 ] So apparently it was marked as a backport by mistake.
16-09-2015

Attaching simple script with test cases.
07-08-2015

Came up with a full matrix covering hopefully all possibilities: #1 desired JDK behavior: Note: "(1)" next to results denotes a result that is different from the current jdk9/hs-rt behavior! Note: "(2)" next to results denotes a result that is different from the jdk8 behavior! #1.1 normal flag (new behavior): ..............................................................exists, invalid value...........................does not exist .............................................................-XX:MinHeapFreeRatio=notnum.......-XX:THIS_FLAG_DOESNT_EXIST -IgnoreUnrecognizedVMOptions...........................ERR.........................................................ERR +IgnoreUnrecognizedVMOptions..........................ERR (1)(2)...............................................OK #1.1.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:MinHeapFreeRatio=notnum -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.1.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:THIS_FLAG_DOESNT_EXIST -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.1.3 java -XX:+IgnoreUnrecognizedVMOptions -XX:MinHeapFreeRatio=notnum -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.1.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:THIS_FLAG_DOESNT_EXIST -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.2 normal flag with ranges (this fix): ............................................................exists, in range......................exists, out of range ............................................................-XX:StackRedPages=1.........-XX:StackRedPages=0 -IgnoreUnrecognizedVMOptions......................OK.....................................ERR +IgnoreUnrecognizedVMOptions.....................OK.....................................ERR (1) #1.2.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:StackRedPages=1 -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.2.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:StackRedPages=0 -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.2.3 java -XX:+IgnoreUnrecognizedVMOptions -XX:StackRedPages=1 -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.2.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:StackRedPages=0 -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.3 locked flag (new behavior): ............................................................diagnostic & locked..............................experimental & locked............................commercial & locked ............................................................-XX:-UnlockDiagnosticVMOptions.......-XX:-UnlockExperimentalVMOptions......-XX:-UnlockCommercialFeatures ............................................................-XX:+PrintInlining................................-XX:+AlwaysSafeConstructors................-XX:+FlightRecorder -IgnoreUnrecognizedVMOptions....................ERR............................................................ERR...................................................ERR +IgnoreUnrecognizedVMOptions...................ERR (1)(2)..................................................ERR (1)(2)..........................................ERR (1)(2) #1.3.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:-UnlockDiagnosticVMOptions -XX:+PrintInlining -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.3.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:-UnlockExperimentalVMOptions -XX:+AlwaysSafeConstructors -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.3.3 java -XX:-IgnoreUnrecognizedVMOptions -XX:-UnlockCommercialFeatures -XX:+FlightRecorder -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.3.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:-UnlockDiagnosticVMOptions -XX:+PrintInlining -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.3.5 java -XX:+IgnoreUnrecognizedVMOptions -XX:-UnlockExperimentalVMOptions -XX:+AlwaysSafeConstructors -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.3.6 java -XX:+IgnoreUnrecognizedVMOptions -XX:-UnlockCommercialFeatures -XX:+FlightRecorder -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.4 develop & notproduct flag on debug VM (trivial, unchanged): ............................................................develop & !product_build...........notproduct & !product_build ............................................................-XX:+DeoptimizeALot................-XX:+VerifyCodeCache -IgnoreUnrecognizedVMOptions........................OK........................................OK +IgnoreUnrecognizedVMOptions.......................OK........................................OK #1.4.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.4.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:+VerifyCodeCache -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.4.3 java -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.4.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:+VerifyCodeCache -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.5 develop & notproduct flag on product VM (consistent with JDK-6886353, unchanged): ............................................................develop & !product_build...........notproduct & !product_build ............................................................-XX:+DeoptimizeALot................-XX:+VerifyCodeCache -IgnoreUnrecognizedVMOptions........................ERR......................................ERR +IgnoreUnrecognizedVMOptions.......................OK........................................OK #1.5.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.5.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:+VerifyCodeCache -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.5.3 java -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.5.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:+VerifyCodeCache -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.6 malformed locked flag (new behavior): ............................................................diagnostic & locked..............................experimental & locked............................commercial & locked ............................................................-XX:-UnlockDiagnosticVMOptions.......-XX:-UnlockExperimentalVMOptions......-XX:-UnlockCommercialFeatures ............................................................-XX:PrintInlining...................................-XX:AlwaysSafeConstructors..................-XX:FlightRecorder -IgnoreUnrecognizedVMOptions....................ERR............................................................ERR...................................................ERR +IgnoreUnrecognizedVMOptions...................ERR (1)(2)..................................................ERR (1)(2)..........................................ERR (1)(2) #1.6.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:-UnlockDiagnosticVMOptions -XX:PrintInlining -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.6.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:-UnlockExperimentalVMOptions -XX:AlwaysSafeConstructors -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.6.3 java -XX:-IgnoreUnrecognizedVMOptions -XX:-UnlockCommercialFeatures -XX:FlightRecorder -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.6.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:-UnlockDiagnosticVMOptions -XX:PrintInlining -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.6.5 java -XX:+IgnoreUnrecognizedVMOptions -XX:-UnlockExperimentalVMOptions -XX:AlwaysSafeConstructors -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.6.6 java -XX:+IgnoreUnrecognizedVMOptions -XX:-UnlockCommercialFeatures -XX:FlightRecorder -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.7 malformed develop & notproduct flag on debug VM (new behavior): ............................................................develop & !product_build...........notproduct & !product_build ............................................................-XX:DeoptimizeALot..................-XX:VerifyCodeCache -IgnoreUnrecognizedVMOptions........................ERR........................................ERR +IgnoreUnrecognizedVMOptions.......................ERR (1)(2)..............................ERR (1)(2) #1.7.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:DeoptimizeALot -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.7.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:VerifyCodeCache -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.7.3 java -XX:+IgnoreUnrecognizedVMOptions -XX:DeoptimizeALot -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.7.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:VerifyCodeCache -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.8 malformed develop & notproduct flag on product VM (unchanged behavior): ............................................................develop & !product_build...........notproduct & !product_build ............................................................-XX:DeoptimizeALot..................-XX:VerifyCodeCache -IgnoreUnrecognizedVMOptions........................ERR........................................ERR +IgnoreUnrecognizedVMOptions.......................OK...........................................OK #1.8.1 java -XX:-IgnoreUnrecognizedVMOptions -XX:DeoptimizeALot -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.8.2 java -XX:-IgnoreUnrecognizedVMOptions -XX:VerifyCodeCache -version ; if [ $? -ne 0 ] ; then echo PASS ; else echo FAIL ; fi #1.8.3 java -XX:+IgnoreUnrecognizedVMOptions -XX:DeoptimizeALot -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi #1.8.4 java -XX:+IgnoreUnrecognizedVMOptions -XX:VerifyCodeCache -version ; if [ $? -eq 0 ] ; then echo PASS ; else echo FAIL ; fi
06-08-2015

The new strict behavior of IgnoreUnrecognizedVMOptions, is: - ignore unrecognized OR not applicable EVEN if they are malfmored - those that are recognized (regardless of whether they are ignored) CAN NOT be malformed OR locked
31-07-2015

# hg diff diff -r e8351756255d src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon Jul 27 13:56:26 2015 -0700 +++ b/src/share/vm/runtime/arguments.cpp Wed Jul 29 15:51:28 2015 -0500 @@ -844,7 +844,7 @@ JDK_Version since = JDK_Version(); - if (parse_argument(arg, origin) || ignore_unrecognized) { + if (parse_argument(arg, origin)) { return true; } @@ -893,9 +893,16 @@ "Improperly specified VM option '%s'\n", argname); } } else { + // We can get here if, for example, we have a develop flag in a product build + if (ignore_unrecognized) { + return true; + } jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf); } } else { + if (ignore_unrecognized) { + return true; + } jio_fprintf(defaultStream::error_stream(), "Unrecognized VM option '%s'\n", argname); Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true);
29-07-2015

Thank you Dmitry. I see: a locked flag could be a developer flag, that is not available in product build. That would mean that it is found by the locked code, but it could result in error in product build. In such cases IgnoreUnrecognizedVMOptions was used to short-circuit the flag check and return OK, before getting to the "locked flags" code. Indeed as Dmitry says we do need to short-circuit the "locked flags" code too - verified by running: java -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -version ; echo $?
29-07-2015

Gerard, I think that case for locked flag should exist, since as I remember "-XX:+IgnoreUnrecognizedVMOptions" is often used in tests to handle such situation, e.g. when develop flag is used in test for product build. See for example https://bugs.openjdk.java.net/browse/JDK-6886353
29-07-2015

Actually, the fix is even simpler, because we don't need to handle "locked" flags in any special way. The code path handling locked flags is only taken if the flag is recognized, so we will never be in that code with a locked/unrecognized flag: # hg diff diff -r e8351756255d src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon Jul 27 13:56:26 2015 -0700 +++ b/src/share/vm/runtime/arguments.cpp Wed Jul 29 14:50:55 2015 -0500 @@ -844,7 +844,7 @@ JDK_Version since = JDK_Version(); - if (parse_argument(arg, origin) || ignore_unrecognized) { + if (parse_argument(arg, origin)) { return true; } @@ -896,6 +896,9 @@ jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf); } } else { + if (ignore_unrecognized) { + return true; + } jio_fprintf(defaultStream::error_stream(), "Unrecognized VM option '%s'\n", argname); Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true);
29-07-2015

Following Dmitry's suggestion, the following simple fix should do it: # hg diff src/share/vm/runtime/arguments.cpp diff -r e8351756255d src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon Jul 27 13:56:26 2015 -0700 +++ b/src/share/vm/runtime/arguments.cpp Wed Jul 29 12:09:50 2015 -0500 @@ -844,7 +844,7 @@ JDK_Version since = JDK_Version(); - if (parse_argument(arg, origin) || ignore_unrecognized) { + if (parse_argument(arg, origin)) { return true; } @@ -893,9 +893,15 @@ "Improperly specified VM option '%s'\n", argname); } } else { + if (ignore_unrecognized) { + return true; + } jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf); } } else { + if (ignore_unrecognized) { + return true; + } jio_fprintf(defaultStream::error_stream(), "Unrecognized VM option '%s'\n", argname); Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true);
29-07-2015

So we have the following test cases for a regular (product) flags: current JDK behavior: ...........................................................exists, in range...............exists, out of range..........does not exist ..........................................................-XX:StackRedPages=1...-XX:StackRedPages=0...-XX:THIS_FLAG_DOESNT_EXIST -IgnoreUnrecognizedVMOptions..................OK.................................ERR.........................................ERR +IgnoreUnrecognizedVMOptions.................OK.................................OK...........................................OK desired JDK behavior: ...........................................................exists, in range...............exists, out of range..........does not exist ..........................................................-XX:StackRedPages=1...-XX:StackRedPages=0...-XX:THIS_FLAG_DOESNT_EXIST -IgnoreUnrecognizedVMOptions..................OK.................................ERR.........................................ERR +IgnoreUnrecognizedVMOptions.................OK.................................ERR.........................................OK In particular, with +IgnoreUnrecognizedVMOptions the VM currently returns OK regardless of whether the flag existed or not (desired behavior), but also regardless of whether a recognized flag had valid value set (incorrect behavior).
29-07-2015

The other way is just handle "IgnoreUnrecognizedVMOption" in more precise manner(as it names means),i.e. ignore option only if option with passed name is not exist or if option is locked(e.g. diagnostic flag). In this case out-of-range options, badly specified options(e.g. -XX:UseG1GC) will be considered as invalid options.
29-07-2015

Probably the safest way to go forward would be to add a new flag (ex. IgnoreFlagsList JDK-8132545) with very clear specifications and then deprecate "IgnoreUnrecognizedVMOption" (JDK-8132546) In the meantime, however, it would probably be useful to quickly fix the existing issue to unblock the current tests that are failing (ie. JDK-8130697)
29-07-2015

The current consensus seems to be that it is time to change how the flag works, i.e.: ------------------------------------------------------------------------------------------------------------------- I agree with this suggestion. Make it ccstrlist so we can specify list of flags. But then the name should be different - "Unrecognized" is misleading in such case I think. Thanks, Vladimir On 6/26/15 1:59 AM, Stefan Karlsson wrote: > On 2015-06-26 08:00, Bengt Rutisson wrote: >> >> Hi all, >> >> Just one more thought if we are thinking about making changes to the >> IgnoreUnrecognizedVMOptions flag. >> >> I am not a big fan of this flag since I think it just goes to show >> that we don't have enough control over our testing. As I understand it >> the main reason for the introduction of this flag was that when >> compressed oops was implemented we had no way of controlling which >> tests were run on 32 bit platforms (where the UseCompressedOops flag >> is not available) or o 64 bit platforms. >> >> I think it is unfortunate that we don't have better control of our >> testing. But one way of at least increasing the control would be to >> make IgnoreUnrecognizedVMOptions more specific. I would suggest that >> we change it to take a named argument that should be ignored. >> >> Something like: >> >> -XX:IgnoreUnrecognizedVMOption=UseCompressedOops >> >> That way it would not hide other issues in our testing. As it is now >> we run a lot of our testing with IgnoreUnrecognizedVMOptions which >> means that we don't find tests that need to be updated when we for >> example remove a command line option. >> >> Maybe it is a side track, but I wanted to mention it in this discussion. > > Yes, I've also suggested this a couple of times. Maybe it's time to > create an RFE? > > StefanK > >> >> Bengt
29-07-2015

http://mail.openjdk.java.net/pipermail/hotspot-dev/2015-June/019213.html
29-07-2015

I think we need a clear specification of how options should be processed so that we can verify that against the code. In particular it is not clear to me how "ignoreUnrecognizedVMOptions" should interact with things like out-of-range values. A flowchart for option processing would be quite valuable here I think.
25-06-2015

The problem in Arguments::process_argument function(src/share/vm/runtime/arguments.cpp module): 817 bool Arguments::process_argument(const char* arg, 818 jboolean ignore_unrecognized, Flag::Flags origin) { 819 820 JDK_Version since = JDK_Version(); 821 822 if (parse_argument(arg, origin) || ignore_unrecognized) { 823 return true; 824 } ... 850 // For locked flags, report a custom error message if available. 851 // Otherwise, report the standard unrecognized VM option. 852 Flag* found_flag = Flag::find_flag((const char*)argname, arg_len, true, true); 853 if (found_flag != NULL) { 854 char locked_message_buf[BUFLEN]; 855 found_flag->get_locked_message(locked_message_buf, BUFLEN); 856 if (strlen(locked_message_buf) == 0) { 857 if (found_flag->is_bool() && !has_plus_minus) { 858 jio_fprintf(defaultStream::error_stream(), 859 "Missing ± setting for VM option '%s'\n", argname); 860 } else if (!found_flag->is_bool() && has_plus_minus) { 861 jio_fprintf(defaultStream::error_stream(), 862 "Unexpected ± setting in VM option '%s'\n", argname); 863 } else { 864 jio_fprintf(defaultStream::error_stream(), 865 "Improperly specified VM option '%s'\n", argname); 866 } 867 } else { 868 jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf); 869 } 870 } else { 871 jio_fprintf(defaultStream::error_stream(), 872 "Unrecognized VM option '%s'\n", argname); 873 Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true); 874 if (fuzzy_matched != NULL) { 875 jio_fprintf(defaultStream::error_stream(), 876 "Did you mean '%s%s%s'? ", 877 (fuzzy_matched->is_bool()) ? "(+/-)" : "", 878 fuzzy_matched->_name, 879 (fuzzy_matched->is_bool()) ? "" : "=<value>"); 880 } 881 } 882 883 // allow for commandline "commenting out" options like -XX:#+Verbose 884 return arg[0] == '#'; 885 } The range check is performed when parse_argument(arg, origin) function is called. But if "-XX:+IgnoreUnrecongnizedVMOptions" is specified, then "ignore_unrecognized" will be true and "if" statement on line 822 will always be true. I think that a better place to check "ignore_unrecognized" is on "else" branch on line 867(for locked flags) and on "else" branch on line 870(where we actually found unrecognized option). If "ignore_unrecognized" is true, then return true in this case, otherwise execute code in these "else" branches. In this case out-of-range options(line 822) and improperly specified options will be catched(lines 857-866), e.g. "-XX:UseG1GC" (without +/-) or "java -XX:MaxRAMFraction=NOTNUM".
25-06-2015