GR.jl icon indicating copy to clipboard operation
GR.jl copied to clipboard

Cannot interrupt `plot` in a loop

Open YingboMa opened this issue 5 years ago • 17 comments

julia> using GR; for i in 1:10
           plot(1:10000000)
       end
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
julia> versioninfo()
Julia Version 1.1.0
Commit 80516ca202 (2019-01-21 21:24 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, skylake)

(v1.1) pkg> st GR
    Status `~/.julia/environments/v1.1/Project.toml`
  [28b8d3ca] GR v0.39.0

YingboMa avatar Apr 15 '19 13:04 YingboMa

I'm not sure whether this should/can be handled within GR!?

The following snippet would work:

using GR
for i = 1:10
    try
        plot(1:100000)
        println(i)
        sleep(1)
    catch InterruptException
        println("Interrupt")
        break
    end
end

jheinen avatar Apr 15 '19 14:04 jheinen

julia> using GR

julia> for i = 1:10
           try
               plot(1:100000)
               println(i)
               sleep(1)
           catch InterruptException
               println("Interrupt")
               break
           end
       end
1
2
^C3
^C^C4
^C^C^C^C5
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C6
^C^C7
8
9
10

Unfortunately, it doesn't quite work.

YingboMa avatar Apr 15 '19 14:04 YingboMa

Which platform are you using? Did you invoke Julia using julia -i ... ?

jheinen avatar Apr 15 '19 14:04 jheinen

Which platform are you using?

I am using Arch Linux.

Did you invoke Julia using julia -i ... ?

No, I didn't.

YingboMa avatar Apr 15 '19 15:04 YingboMa

This happens on Fedora Linux as well. Have to just kill -9 my Julia scripts that use GR. It seems to me this is a problem with Julia itself. It's odd that even with a large sleep statement outside of GR, you still can't get Julia to respond to a SIGINT. How could GR be responsible for something that is happening outside of GR? Although, none of that changes the fact that GR is the only package I've had this problem with.

DevJac avatar Jun 11 '19 04:06 DevJac

I just tried several OSs: macOS and Windows 10 work fine - on Ubuntu 18, it doesn't work. The problem seems to be specific to Linux. I'm currently out of office, but it's on my radar ...

jheinen avatar Dec 21 '19 07:12 jheinen

I have the same problem (on Linux) with this script:

for i = 1:10
    try
        io = open("foo.txt", "w")
        println(io, 1:10000)
        close(io)
        println(i)
        sleep(1)
    catch InterruptException
        println("Interrupt")
        break
    end
end

... which means, that it's not related to GR (IMO).

jheinen avatar Dec 21 '19 21:12 jheinen

@jheinen I was able to get stuck in the loop you just posted. Just to be clear, this is the loop I get stuck in:

for i = 1:10
    try
        io = open("foo.txt", "w")
        println(io, 1:10000)
        close(io)
        println(i)
        sleep(1)
    catch InterruptException
        println("Interrupt")
        break
    end
end

However, this only happens if I have imported GR and done a plot. If I do not import GR, then I can interrupt the loop you posted just fine. If I do import and use GR, then I can no longer break from the loop you posted. I am on Linux / Fedora 31.

It seems to me that this issue is exclusive to GR. Yet, your examples makes us ask, how does GR cause problems in a loop which is not even calling GR? It could be an issue with Julia, but every example of this problem I have seen involves GR.

DevJac avatar Dec 25 '19 06:12 DevJac

MacOS, Julia 1.6.2, GR 0.58.1. Simply GR.clearws() totally kills Ctrl+C even for loops without GR in them, that would interrupt otherwise. The problem doesn't exist in 0.55.0.

$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.6.2 (2021-07-14)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> for i=1:1000000 for j=1:1000000 i^j end end
^C^C^C^C^CWARNING: Force throwing a SIGINT
ERROR: ^C^C^CInterruptException:
Stacktrace:
 [1] >>
   @ ./int.jl:455 [inlined]
 [2] >>
   @ ./int.jl:462 [inlined]
 [3] power_by_squaring(x_::Int64, p::Int64)
   @ Base ./intfuncs.jl:276
 [4] ^
   @ ./intfuncs.jl:290 [inlined]
 [5] top-level scope
   @ ./REPL[1]:1

julia> ^C

julia> using GR

julia> GR.clearws()

julia> for i=1:1000000 for j=1:1000000 i^j end end
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C

ghost avatar Aug 31 '21 16:08 ghost

You will have to disable the internal exit handler in GR's underlying GKS, e.g.

env GKS_NO_EXIT_HANDLER=1 julia

In many graphics applications, an exit handler in the graphics subsystem makes perfect sense. In your case, however, it must be switched off.

jheinen avatar Aug 31 '21 16:08 jheinen

Unfortunately, it doesn't seem to fix the problem for me

➜  env GKS_NO_EXIT_HANDLER=1 julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.6.2-pre.0 (2021-04-23)
 _/ |\__'_|_|_|\__'_|  |  release-1.6/dd122918ce (fork: 333 commits, 265 days)
|__/                   |

julia> using GR

julia> for i = 1:10
           try
               plot(1:100000)
               println(i)
               sleep(1)
           catch InterruptException
               println("Interrupt")
               break
           end
       end
1
2
^C3
^C^C4
^C^C5
^C^C^C6
^C^C^C7
^C^C8
^C^C^C^C^C^C^C^C^C^C9
^C^C^C^C^C^C^C^C^C^C10
^C^C^C^C^C

julia> versioninfo()
Julia Version 1.6.2-pre.0
Commit dd122918ce (2021-04-23 21:21 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin20.3.0)
  CPU: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, icelake-client)
Environment:
  JULIA_NUM_THREADS = 4
  JULIA_PKG_DEVDIR = /Users/scheme/src/julia
  JULIA_PKG_SERVER = https://neuralsim.juliahub.com

YingboMa avatar Aug 31 '21 16:08 YingboMa

I can't reproduce the behaviour with our binaries. Could you please try to build GR using ENV["JULIA_GR_PROVIDER"] = "GR"? It seems to me, that the problem is related the BinaryBuilder run-time.

jheinen avatar Aug 31 '21 16:08 jheinen

No, doesn't help. I even tried the following:

sigsetmask = t -> ccall(:sigsetmask, Cint, (Cint,), t)
sigblock = t -> ccall(:sigblock, Cint, (Cint,), t)
mask = sigblock(0)
using GR
GR.clearws()
grmask = sigblock(0)
using Printf
@printf("orig mask: %x, after GR: %x, GR w/o SIGTERM block: %x\n", mask, grmask, grmask & ~(1<<14))
sigsetmask(mask)

According to it, GR disables SIGTERM (signal 15, bit 14) receipt, so I tried re-enabling it, but it doesn't help. In any case Control+C should send SIGINT… but that one (signal 2, bit 1) is blocked with or without GR. Weird… Also just sending SIGINT to julia directly causes it to crash. So Julia must have some weird nonstandard ^C processing.

ghost avatar Aug 31 '21 16:08 ghost

I can't reproduce the behaviour with our binaries. Could you please try to build GR using ENV["JULIA_GR_PROVIDER"] = "GR"? It seems to me, that the problem is related the BinaryBuilder run-time.

How is that done?

ghost avatar Aug 31 '21 16:08 ghost

My next attempt would be to study tcgetattr to see if there are some terminal Ctrl+C settings, but that's more work as C structs would be needed… maybe one day.

ghost avatar Aug 31 '21 17:08 ghost

Based on the above issue I reported against Julia, I also tested sending SIGINT directly instead of with Ctrl+C to Julia while running the final loop in my earlier comment https://github.com/jheinen/GR.jl/issues/211#issuecomment-909376759: for i in $(seq 1 10); do kill -SIGINT $JULIAPID; done. Nothing, the loop won't terminate. So the issue is not about the terminal configuration as suggested in my previous post. It has to be something about how SIGINT is being processed internally in Julia after GR is loaded.

Also, if I just kill -SIGINT $JULIAPID after loading GR (using GR; GR.clearws()) but keeping the REPL idle, nothing happens. However, if GR is not loaded, Julia crashes (https://github.com/JuliaLang/julia/issues/42072). So GR somehow totally disables SIGINT handling, but according to my other comment https://github.com/jheinen/GR.jl/issues/211#issuecomment-909414800, this does not seem to be directly using signal masks.

ghost avatar Aug 31 '21 18:08 ghost

Duplicate of https://github.com/jheinen/GR.jl/issues/391

vtjnash avatar Aug 31 '21 20:08 vtjnash