Bug #13043
closedException#cause can become recursive/infinite
Description
In a certain situation, Exception#cause can become an infinite list:
def raise_errors
begin
raise "error 1"
ensure
orig_error = $!
begin
raise "error 2"
rescue => err
raise orig_error || err
end
end
end
x = nil
begin
raise_errors
rescue
x = $!
end
x.cause.cause.object_id == x.object_id
Note that this pattern happened during an HTTP request with net/http: see https://github.com/ruby/ruby/blob/v2_3_1/lib/net/http/response.rb#L261. I would expect that x would be "error 2", x.cause would be "error 1", and x.cause.cause would be nil. Instead an infinite loop forms, breaking error reporting code that loops over an exception's cause
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Description updated (diff)
- Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Status changed from Open to Closed
Applied in changeset r57137.
eval.c: fix circular cause
- eval.c (exc_setup_cause): always set cause of cause to get rid
of circular references. [ruby-core:78688] [Bug #13043]
Updated by usa (Usaku NAKAMURA) almost 8 years ago
- Backport changed from 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: REQUIRED, 2.2: DONE, 2.3: REQUIRED
ruby_2_2 r57222 merged revision(s) 57137.
Updated by usa (Usaku NAKAMURA) almost 8 years ago
- Backport changed from 2.1: REQUIRED, 2.2: DONE, 2.3: REQUIRED to 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED
... but reverted in ruby_2_2
because it causes SEGV.
Updated by usa (Usaku NAKAMURA) almost 8 years ago
- Backport changed from 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: REQUIRED, 2.2: DONE, 2.3: REQUIRED
ruby_2_2 r57229 merged revision(s) 57137.
Updated by usa (Usaku NAKAMURA) almost 8 years ago
- Backport changed from 2.1: REQUIRED, 2.2: DONE, 2.3: REQUIRED to 2.1: WONTFIX, 2.2: WONTFIX, 2.3: REQUIRED
I've finally gave up to backport this into ruby_2_2
, because of a test of rake
failed.
I doubt that the test is nonsense, but a maintenance branch should be conservative about changing its behavior.