JDK-4454115 : Need to deal gracefully with unsafe operations that access invalid memory (C2)
Type:Enhancement
Component:hotspot
Sub-Component:compiler
Affected Version:1.4.0
Priority:P3
Status:Resolved
Resolution:Fixed
OS:generic
CPU:generic
Submitted:2001-05-03
Updated:2017-11-15
Resolved:2001-05-29
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.
CONVERTED DATA
BugTraq+ Release Management Values
COMMIT TO FIX:
merlin-beta2
FIXED IN:
merlin-beta2
INTEGRATED IN:
merlin-beta2
14-06-2004
EVALUATION
Here is a possible solution.
It works currently in the interpreter and both compilers, on SPARC
only. It can be extended to Intel with several dozen more lines of
CPU-specific code. But I don't know if 4454115 applies to win32,
and/or if we care enough about it on Solaris/x86.
The idea is to add a new paragraph to the signal handler which looks for
the Unix signal SIGBUS with subcode BUS_OBJERR. At that point, if the
offending code is advertised as containing unsafe operations (see *),
the trap handler will take two actions: (a) set a bit on the thread
requesting an asynchronous InternalError, and (b) continue execution
at the next instruction after the offending instruction.
This means there are three kinds of imprecision in the reporting of
unsafe memory faults:
1. If code which advertises the presence of unsafe operations gets
a BUS_OBJERR fault, we assume without proof that the offending
instruction was in fact an unsafe memory access. (There is
proof only in the case of the interpreter method: I have
added no new "mapping" structure to nmethods to pinpoint these
instructions.)
2. Compiled Java code which is generating these faults will process
garbage results (if the offending instructions are loads) until the
asynchronous error is delivered at some later safepoint.
3. The point of error delivery to compiled Java code is unpredictable.
The delay is like that of Thread.stop on a different thread.
The backtrace reported in the error is at some safepoint shortly
after the error point. Unsafe memory ops are __not__ safepoints.
I have used InternalError rather than create a new subclass of Error.
I'm pretty sure it should be an Error rather than a RuntimeException.
This change is narrowly targeted to 4454115. If you use unsafe
primitives unwisely, so as to indirect through a stray pointer,
or to load a multi-word value on an odd address, you will still
crash the VM.
Adding a mechanism for more precisely mapping the locations of unsafe
memory operations would be more complex (though doable). It would tend
to reduce the optimization level of code which uses unsafe operations.
Therefore, I think the present imprecise design is preferable.
john.rose@Eng 2001-05-11