Forum: IronRuby MRI 1.8.6 bug - exit is ignored if ensure clause throws exception which is caught by outer rescue

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Aea6cfe04952626ab630bde47ff82f89?d=identicon&s=25 Shri Borde (Guest)
on 2009-01-12 21:33
(Received via mailing list)
The following code snippet does print "after foo" when using MRI 1.8.6
on Windows Vista, showing that exit is ignored. Any thoughts on whether
this is by design, a known bug, or a new issue? If it's the latter,
should I open a bug for it?

def foo
  begin
    begin
      begin
        exit
      rescue
        puts "We never reach here"
      end
    ensure
      raise "exception from ensure"
    end
  rescue
    puts "We do reach here, which is unexpected"
  end
end

foo
print "after foo"

Thanks,
Shri
540cb3b3712ffe045113cb03bab616a2?d=identicon&s=25 Evan Phoenix (Guest)
on 2009-01-12 22:02
(Received via mailing list)
On Jan 12, 2009, at 12:31 PM, Shri Borde wrote:

> The following code snippet does print “after foo” when using MRI
> 1.8.6 on Windows Vista, showing that exit is ignored. Any thoughts
> on whether this is by design, a known bug, or a new issue? If it’s
> the latter, should I open a bug for it?

No, this is by design. Kernel#exit raises SystemExit, which the
toplevel rescues and performs the actual exit. If you raise a new
exception in the ensure. the SystemExit exception is never seen by the
toplevel, and thus you don't get the exit.

This is used in a few places to cause exit to be ignored, or to allow
a library to convert a SystemExit exception into something else
(perhaps an IllegalOperation or something).

  - Evan Phoenix
Cb51033949ffccd982ae32c9f890f25a?d=identicon&s=25 Tomas Matousek (Guest)
on 2009-01-12 22:35
(Received via mailing list)
I believe this is by design. Exit throws an exception (SystemExit). The
exception is not rescued by a default rescue clause because it doesn't
derive from StandardError. Thus the raise in ensure gets called and it
raises RuntimeError which gets caught in the outer rescue because
RuntimeError <: StandardError.

Tomas

From: Shri Borde [mailto:Shri.Borde@microsoft.com]
Sent: Monday, January 12, 2009 12:32 PM
To: ironruby-core@rubyforge.org; ruby-core@ruby-lang.org
Subject: [ruby-core:21289] MRI 1.8.6 bug - exit is ignored if ensure
clause throws exception which is caught by outer rescue

The following code snippet does print "after foo" when using MRI 1.8.6
on Windows Vista, showing that exit is ignored. Any thoughts on whether
this is by design, a known bug, or a new issue? If it's the latter,
should I open a bug for it?

def foo
  begin
    begin
      begin
        exit
      rescue
        puts "We never reach here"
      end
    ensure
      raise "exception from ensure"
    end
  rescue
    puts "We do reach here, which is unexpected"
  end
end

foo
print "after foo"

Thanks,
Shri
Aea6cfe04952626ab630bde47ff82f89?d=identicon&s=25 Shri Borde (Guest)
on 2009-01-12 23:10
(Received via mailing list)
OK, I have added a RSpec test, and  have already tagged it as an
IronRuby bug.

For reference, .NET allows the equivalent ThreadAbortException to be
caught, but automatically rethrows it at the end of the catch/rescue
block. The programmer is required to take a separate action (calling
Thread.ResetAbort<http://msdn.microsoft.com/en-us/library/system.thr...)
to complete cancel the abort operation. This prevents situations where
one component triggers the abort, and another cancels it unintentially.
In theory, you should always do "rescue SomeSpecificExceptionType", but
a lot of people do use just "rescue".

From: Evan Phoenix [mailto:evan@fallingsnow.net]
Sent: Monday, January 12, 2009 1:01 PM
To: ruby-core@ruby-lang.org
Subject: [ruby-core:21290] Re: MRI 1.8.6 bug - exit is ignored if ensure
clause throws exception which is caught by outer rescue


On Jan 12, 2009, at 12:31 PM, Shri Borde wrote:


The following code snippet does print "after foo" when using MRI 1.8.6
on Windows Vista, showing that exit is ignored. Any thoughts on whether
this is by design, a known bug, or a new issue? If it's the latter,
should I open a bug for it?

No, this is by design. Kernel#exit raises SystemExit, which the toplevel
rescues and performs the actual exit. If you raise a new exception in
the ensure. the SystemExit exception is never seen by the toplevel, and
thus you don't get the exit.

This is used in a few places to cause exit to be ignored, or to allow a
library to convert a SystemExit exception into something else (perhaps
an IllegalOperation or something).

 - Evan Phoenix



def foo
  begin
    begin
      begin
        exit
      rescue
        puts "We never reach here"
      end
    ensure
      raise "exception from ensure"
    end
  rescue
    puts "We do reach here, which is unexpected"
  end
end

foo
print "after foo"

Thanks,
Shri
Aea6cfe04952626ab630bde47ff82f89?d=identicon&s=25 Shri Borde (Guest)
on 2009-01-13 00:03
(Received via mailing list)
I was assuming that exit and Thread.current.kill do the same thing, but
Tomas pointed out that they are different. Would you expect that "after
foo" would get printed even if you replace exit with
Thread.current.kill?

Thanks,
Shri

From: ironruby-core-bounces@rubyforge.org
[mailto:ironruby-core-bounces@rubyforge.org] On Behalf Of Shri Borde
Sent: Monday, January 12, 2009 2:10 PM
To: ruby-core@ruby-lang.org; ironruby-core@rubyforge.org
Subject: Re: [Ironruby-core] [ruby-core:21290] Re: MRI 1.8.6 bug - exit
is ignored if ensure clause throws exception which is caught by outer
rescue

OK, I have added a RSpec test, and  have already tagged it as an
IronRuby bug.

For reference, .NET allows the equivalent ThreadAbortException to be
caught, but automatically rethrows it at the end of the catch/rescue
block. The programmer is required to take a separate action (calling
Thread.ResetAbort<http://msdn.microsoft.com/en-us/library/system.thr...)
to complete cancel the abort operation. This prevents situations where
one component triggers the abort, and another cancels it unintentially.
In theory, you should always do "rescue SomeSpecificExceptionType", but
a lot of people do use just "rescue".

From: Evan Phoenix [mailto:evan@fallingsnow.net]
Sent: Monday, January 12, 2009 1:01 PM
To: ruby-core@ruby-lang.org
Subject: [ruby-core:21290] Re: MRI 1.8.6 bug - exit is ignored if ensure
clause throws exception which is caught by outer rescue


On Jan 12, 2009, at 12:31 PM, Shri Borde wrote:

The following code snippet does print "after foo" when using MRI 1.8.6
on Windows Vista, showing that exit is ignored. Any thoughts on whether
this is by design, a known bug, or a new issue? If it's the latter,
should I open a bug for it?

No, this is by design. Kernel#exit raises SystemExit, which the toplevel
rescues and performs the actual exit. If you raise a new exception in
the ensure. the SystemExit exception is never seen by the toplevel, and
thus you don't get the exit.

This is used in a few places to cause exit to be ignored, or to allow a
library to convert a SystemExit exception into something else (perhaps
an IllegalOperation or something).

 - Evan Phoenix


def foo
  begin
    begin
      begin
        exit
      rescue
        puts "We never reach here"
      end
    ensure
      raise "exception from ensure"
    end
  rescue
    puts "We do reach here, which is unexpected"
  end
end

foo
print "after foo"

Thanks,
Shri
This topic is locked and can not be replied to.