[Win32utils-devel] Process.kill and at_exit

Daniel Berger djberg96 at gmail.com
Sun Jun 17 17:29:38 UTC 2012


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?

Regards,

Dan


More information about the win32utils-devel mailing list