[Win32utils-devel] Process.kill and at_exit

Daniel Berger djberg96 at gmail.com
Mon Jun 18 05:38:49 UTC 2012


On Sun, Jun 17, 2012 at 9:07 PM, Heesob Park <phasis at gmail.com> wrote:
> Hi,
>
> 2012/6/18 Daniel Berger <djberg96 at gmail.com>
>>
>> On Sun, Jun 17, 2012 at 7:55 PM, Heesob Park <phasis at gmail.com> wrote:
>> > Hi,
>> >
>> > 2012/6/18 Daniel Berger <djberg96 at gmail.com>
>> >>
>> >> On Thu, Jun 14, 2012 at 10:10 PM, Heesob Park <phasis at gmail.com> wrote:
>> >> > Hi,
>> >> >
>> >> > 2012/6/13 Daniel Berger <djberg96 at gmail.com>
>> >> >>
>> >> >> I could have sworn our custom Process.kill implementation for
>> >> >> signals
>> >> >> 1 and 4-8 (the one that uses CreateRemoteThread + ExitProcess)
>> >> >> allowed
>> >> >> processes to call exit handlers. But it doesn't seem to be the case.
>> >> >>
>> >> >> # kill.rb
>> >> >> require 'win32/process'
>> >> >>
>> >> >> cmd = "ruby -e 'sleep 3; at_exit{ puts \"done\" }"
>> >> >> pid = Process.spawn(cmd)
>> >> >>
>> >> >> Process.kill(1, pid)
>> >> >>
>> >> >> But it doesn't seem that the at_exit block fires. Why not?
>> >> >>
>> >> >>
>> >> >
>> >> > The at_exit block is called by ruby_finalize_0, ruby_finalize,
>> >> > ruby_cleanup,
>> >> > rb_f_exit, rb_f_abort or rb_exit function.
>> >> > Call ExitProcess with ruby process means skipping any of these
>> >> > functions.
>> >> >
>> >> > After modifying CreateRemoteThread function in the process.rb like
>> >> > following, you can see at_exit block fires.
>> >> >
>> >> > thread = CreateRemoteThread(
>> >> >                   handle,
>> >> >                   0,
>> >> >                   0,
>> >> >                   GetProcAddress(GetModuleHandle('msvcrt-ruby191'),
>> >> > 'rb_f_exit'),
>> >> >                   0,
>> >> >                   0,
>> >> >                   thread_id
>> >> >                 )
>> >> >
>> >> > But you can also see the annoying error dialog.
>> >>
>> >> I tried this with:  ruby 1.9.3p194 (2012-04-20 revision 35410)
>> >> [i386-mswin32_100]
>> >>
>> >> I did not have much luck, however.
>> >>
>> >> When I ran this using rb_f_exit, rb_exit or rb_f_abort I did not see
>> >> the at_exit function call get executed, though the process was killed
>> >> successfully.
>> >>
>> >> I got mixed results with ruby_cleanup, sometimes it worked, others it
>> >> seemed to cause a segfault. With ruby_finalize I get a
>> >> SystemStackError. It doesn't seem ruby_finalize_0 is actually
>> >> exported.
>> >>
>> >> If you checkout the "ffi" branch for win32-process you can see that
>> >> I've added some hash options, so you can now do this;
>> >>
>> >> Process.kill(1, pid, :exit_proc => "rb_f_exit", :dll_module =>
>> >> "msvcr100-ruby191", :wait_time => 25)
>> >>
>> >> There's also a shortcut for Ruby processes that just sets :exit_proc
>> >> and :dll_module to default values:
>> >>
>> >> Process.kill(1, pid, :ruby_proc => true)
>> >>
>> >> Can you please take a look and see if this is working for you?
>> >>
>> >
>> > If you comment out SetErrorMode process.rb like following, you can
>> > see the
>> > at_exit function call get executed.
>> >
>> > # SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)
>>
>> I still don't see it. I see the dialogue come up, but I don't see the
>> at_exit function get executed. And is there any way to avoid this and
>> avoid the annoying dialogue? Or would people have to setup their own
>> SetConsoleCtrlHandler function?
>>
> You missed my last message.
> Commenting out SetErrorMode is not the solution.
> And calling a ruby function with a thread which is not created in the ruby
> process is not safe and undesirable.
>
> I think using inter-process communication like signal or event handling is
> reliable.

Darn, I was afraid of that. I guess I'll remove the :ruby_proc option then.

I'm pondering changes to core Ruby so that this -would- be a safer option.

Regards,

Dan


More information about the win32utils-devel mailing list