[Win32utils-devel] Process.kill and at_exit

Heesob Park phasis at gmail.com
Mon Jun 18 02:51:13 UTC 2012


Hi,

2012/6/18 Heesob Park <phasis at gmail.com>

> 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)
>
>
> Sorry, I realized that the above statement is wrong.
I guess it is not safe to call a ruby exit function in the different thread
which is not created in the ruby process.

Regards,
Park Heesob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/win32utils-devel/attachments/20120618/5d9482ce/attachment-0001.html>


More information about the win32utils-devel mailing list