Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bypass signal handling in interpreted code #14019

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

cyangle
Copy link
Contributor

@cyangle cyangle commented Nov 26, 2023

Would this be an acceptable workaround for issue #12241?

It bypasses signal handling in interpreted code and waits until child process terminates.

I also tried forwarding child process exit code to interpreted code via Unix socket, but it doesn't work because it seems like the interpreter fiber never yields to other fibers unless it enters into debugger repl.

@straight-shoota

@straight-shoota
Copy link
Member

My comment in #14016 (comment) still stands: What's the point? Do you have a specific use case which this change enables or is it just to get more specs running?

@cyangle
Copy link
Contributor Author

cyangle commented Nov 27, 2023

This allows running shell commands with the interpreter.

And I think it's worth it because several github issues were created due to not being able to run shell commands. And fixing more spec tests is a side effect of fixing Process.run

As for the issue of handling process signals, I don't think it's used as widely as Process.run

This brings a lot of benefits with minimal efforts, so why not?

@straight-shoota

@cyangle cyangle marked this pull request as ready for review November 27, 2023 15:24
@HertzDevil HertzDevil added topic:stdlib:system topic:compiler:interpreter kind:bug A bug in the code. Does not apply to documentation, specs, etc. labels Nov 27, 2023
@straight-shoota
Copy link
Member

So do you think this is actually a proper bugfix instead of a workaround?

@cyangle
Copy link
Contributor Author

cyangle commented Dec 7, 2023

This is still a workaround with a much smaller impact than #14016.

@HertzDevil
Copy link
Contributor

Process#wait must not block the current thread whether as a bug or by design, especially now that it is asynchronous on compiled Windows as well. IMO at a minimum the LibC.waitpid needs to happen on a fresh system thread.

@ysbaddaden
Copy link
Contributor

Hum, that workaround ain't so bad (fake it until you can make it 🤫).

It's very inefficient, but if it enables running sub-processes in interpreted mode that would be nice. It currently hangs forever, and I regularly trip on that limitation myself + have a bunch of skip "interpreted mode hangs forever on Process.run" in some test suites (e.g. Minitest).

@HertzDevil you mean something like that? the issue is how to enqueue the suspended fiber, but #send_fiber should do the job:

def wait
  {% if flag?(:interpreted) %}
    fiber = Fiber.current
    exit_code = uninitialized Int32

    Thread.new do
      LibC.waitpid(pid, pointerof(exit_code), 0)
      fiber.current_thread.scheduler.send_fiber(fiber)
    end

    fiber.reschedule
    @channel.send(exit_code)
    @channel.close
  {% end %}
  @channel.receive
end

@cyangle if the reenabled specs are calling into Crystal, they may be calling crystal run and not crystal i 🤔 if so, they don't test what they should be.

@cyangle
Copy link
Contributor Author

cyangle commented Dec 16, 2023

I don't think thread works properly when interpreted. There seems to be something wrong with thread local variables.

result = ""
thread = Thread.new do
  result = "From Thread #{Thread.current}"
end

thread.join

puts "#{Thread.current}: #{result}"

@oprypin oprypin changed the title Maybe a proper workaround for #12241 Bypass signal handling in interpreted code Dec 17, 2023
spec/std/spec_helper.cr Outdated Show resolved Hide resolved
@ysbaddaden
Copy link
Contributor

I have nothing more to say about this PR. It's still just a hack, but not being able to spawn a child process is very limiting. Threads are indeed unsupported in interpreted code, so we can't use 'em.

@beta-ziliani beta-ziliani added this to the 1.13.0 milestone Jun 28, 2024
@straight-shoota straight-shoota removed this from the 1.13.0 milestone Jul 2, 2024
@straight-shoota
Copy link
Member

Clearing the milestone because it's not yet read to merge and #14766 might provide a better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:interpreter topic:stdlib:system
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants