Issue #9725 has been updated by Charles Nutter.


Yukihiro Matsumoto wrote:
> I am interested why referencing the target object could cause problem. The target object must be existed before the exception, and exception should disappear soon after handling.

Oh I see, you were asking about this line in my original description:

* A NameError that gets held in memory will also prevent GC of the object it references.

This is a problem because a NameError is never just a NameError object...it could hold a reference to a giant object graph. In a system that collects exceptions, e.g. for logging or auditing, NameError is the only exception that could potentially root a bunch of memory just because you happen to keep it around.

Having the object available via #target obviously still has the same problem. I'm not opposed to doing it that way, but I still don't like that a NameError can be just the tip of a giant object graph iceberg.

----------------------------------------
Feature #9725: Do not inspect NameError target object unless verbose
https://bugs.ruby-lang.org/issues/9725#change-52341

* Author: Charles Nutter
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
At least once every few months, we get an error report of JRuby raising a memory error where MRI does not due to `NameError`'s `Message` object holding a reference to an object that's too large to inspect. I propose that this inspection of the target object should only be done in verbose mode.

## Background:

`NameError` is raised when a variable-like method call fails to find a defined method. The resulting exception is created with a hidden `NameError::Message` that holds the object in which the method could not be found.

When name error needs to render its message, such as when it bubbles out or when `#message` is called, it does `to_str` on the `NameError::Message`, which ends up inspecting the target object. If this object's inspect output is large (or infinite) it can end up consuming a large amount of memory.

## Problems:

* If the amount of memory required to render a `NameError` exceeds available memory, a very confusing and misleading memory error can be raised instead.
* If the target object is considered sensitive data, it will end up bubbling out through potentially untrustworthy code. It is an encapsulation flaw, basically.
* A `NameError` that gets held in memory will also prevent GC of the object it references.

## Solutions:

* `NameError` should not capture the target object.
* `NameError` should build a message based on the target object *at creation time*, and only include information useful to indicate the type of object.
* (Optional) If verbose mode is set, `NameError` can just do what it does now.




-- 
https://bugs.ruby-lang.org/