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

julia REPL aborting after harmless syntax error #24078

Closed
KlausC opened this issue Oct 10, 2017 · 9 comments
Closed

julia REPL aborting after harmless syntax error #24078

KlausC opened this issue Oct 10, 2017 · 9 comments

Comments

@KlausC
Copy link
Contributor

KlausC commented Oct 10, 2017

I found a reproducible abort of julia, when I played around with =>.
Same effect with Version 0.6.0 (2017-06-19 13:05 UTC)

Question evoked by the crash:
Why is const => = Pair (=> is a type alias) and not =>(a,b) = Pair(a,b) (=> is an operator)?

  | | |_| | | | (_| |  |  Version 0.7.0-DEV.2092 (2017-10-09 15:51 UTC)
 _/ |\__'_|_|_|\__'_|  |  master/1216e5f60c (fork: 44 commits, 4 days)
|__/                   |  x86_64-redhat-linux

julia> import Base: =>

julia> =>(a) = 1
Pair                      # I would expect a kind of error message

julia> =>(a,b) = 1
Error showing value of type UnionAll:
ERROR: SYSTEM: show(lasterr) caused an error
MethodError(IOContext, (Base.Terminals.TTYTerminal("xterm-256color", Base.TTY(RawFD(15) paused, 0 bytes waiting), Base.TTY(RawFD(13) open, 0 bytes waiting), Base.TTY(RawFD(10) open, 0 bytes waiting)), 1), 0x0000000000005919)

Stacktrace:
 [1] display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::MIME{Symbol("text/plain")}, ::Type) at ./repl/REPL.jl:125
 [2] display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::Type) at ./repl/REPL.jl:128
 [3] display(::UnionAll) at ./multimedia.jl:277
 [4] (::getfield(Base, Symbol("#inner#4")){Array{Any,1},typeof(display),Tuple{UnionAll}})() at ./essentials.jl:669
 [5] print_response(::Base.Terminals.TTYTerminal, ::Any, ::Void, ::Bool, ::Bool, ::Void) at ./repl/REPL.jl:146
 [6] print_response(::Base.REPL.LineEditREPL, ::Any, ::Void, ::Bool, ::Bool) at ./repl/REPL.jl:132
 [7] (::getfield(Base.REPL, Symbol("#do_respond#17")){Bool,getfield(Base.REPL, Symbol("##27#37")){Base.REPL.LineEditREPL,Base.REPL.REPLHistoryProvider},Base.REPL.LineEditREPL,Base.LineEdit.Prompt})(::Base.LineEdit.MIState, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Bool) at ./repl/REPL.jl:674
 [8] eval(::Module, ::Expr) at ./repl/LineEdit.jl:3
 [9] run_interface(::Base.Terminals.TTYTerminal, ::Base.LineEdit.ModalInterface) at ./repl/LineEdit.jl:1967
 [10] run_frontend(::Base.REPL.LineEditREPL, ::Base.REPL.REPLBackendRef) at ./repl/REPL.jl:986
 [11] run_repl(::Base.REPL.LineEditREPL, ::getfield(Base, Symbol("##542#543"))) at ./repl/REPL.jl:182
 [12] _start() at ./client.jl:439

julia> 1
Error showing value of type Int64:
ERROR: SYSTEM: show(lasterr) caused an error
MethodError(ERROR: fatal: error thrown and no exception handler available.
MethodError(f=Base.IOContext{IO_t} where IO_t<:IO, args=(Base.TTY(handle=0x0000000001f667a0, status=3, buffer=Base.GenericIOBuffer{Array{UInt8, 1}}(data=Array{UInt8, 1}[], readable=true, writable=true, seekable=false, append=true, size=0, maxsize=9223372036854775807, ptr=1, mark=-1), readnotify=Base.Condition(waitq=Array{Any, 1}[]), closenotify=Base.Condition(waitq=Array{Any, 1}[]), sendbuf=Base.Nullable{Base.GenericIOBuffer{Array{UInt8, 1}}}(hasvalue=false, value=#<null>), lock=Base.ReentrantLock(locked_by=Base.Nullable{Task}(hasvalue=false, value=#<null>), cond_wait=Base.Condition(waitq=Array{Any, 1}[]), reentrancy_cnt=0), throttle=10485760), 1), world=0x0000000000005919)
rec_backtrace at /home/julia/julia/src/stackwalk.c:87
record_backtrace at /home/julia/julia/src/task.c:246
jl_throw at /home/julia/julia/src/task.c:568
jl_method_error_bare at /home/julia/julia/src/gf.c:1501
jl_method_error at /home/julia/julia/src/gf.c:1519
jl_lookup_generic_ at /home/julia/julia/src/gf.c:1957 [inlined]
jl_apply_generic at /home/julia/julia/src/gf.c:1977
display_error at ./client.jl:139
jl_call_fptr_internal at /home/julia/julia/src/julia_internal.h:366 [inlined]
jl_call_method_internal at /home/julia/julia/src/julia_internal.h:385 [inlined]
jl_apply_generic at /home/julia/julia/src/gf.c:1980
display_error at ./client.jl:142
jl_call_fptr_internal at /home/julia/julia/src/julia_internal.h:366 [inlined]
jl_call_method_internal at /home/julia/julia/src/julia_internal.h:385 [inlined]
jl_apply_generic at /home/julia/julia/src/gf.c:1980
do_call at /home/julia/julia/src/interpreter.c:70
eval at /home/julia/julia/src/interpreter.c:262
eval_body at /home/julia/julia/src/interpreter.c:552
jl_toplevel_eval_body at /home/julia/julia/src/interpreter.c:524
jl_toplevel_eval_flex at /home/julia/julia/src/toplevel.c:634
jl_toplevel_eval_in at /home/julia/julia/src/builtins.c:626
eval at ./sysimg.jl:53
jl_call_fptr_internal at /home/julia/julia/src/julia_internal.h:366 [inlined]
jl_call_method_internal at /home/julia/julia/src/julia_internal.h:385 [inlined]
jl_apply_generic at /home/julia/julia/src/gf.c:1980
_start at ./client.jl:443
jl_call_fptr_internal at /home/julia/julia/src/julia_internal.h:366 [inlined]
jl_call_method_internal at /home/julia/julia/src/julia_internal.h:385 [inlined]
jl_apply_generic at /home/julia/julia/src/gf.c:1980
unknown function (ip: 0x4019c8)
unknown function (ip: 0x401432)
__libc_start_main at /lib64/libc.so.6 (unknown line)
unknown function (ip: 0x4014e9)
[julia]$ 
@KristofferC
Copy link
Member

KristofferC commented Oct 10, 2017

There is no syntax error. You are redefining a base method to no longer make sense.

This is a dup of: #20945, #22132, #23605, #21944.

@KlausC
Copy link
Contributor Author

KlausC commented Oct 10, 2017

I see, that the dups all have the same reason: Redefine of base methods.
@KristofferC So why does the system allow me to redefine base methods?
In this issue the case is slightly different, because => is not a base method, but a base type alias.
I agree - not a syntax error. But why does the system allow me to redefine a base type alias or a base type with a method?

@KristofferC
Copy link
Member

Because there is nothing special about base methods compared to other methods. The guideline that you go against by defining these methods are discussed at https://docs.julialang.org/en/latest/manual/style-guide/#Avoid-type-piracy-1.

@kmsquire
Copy link
Member

kmsquire commented Oct 10, 2017

It would still be nice to (eventually) find a way to prevent the crash. An optional optional blacklist of functions that can’t be redefined, or modules whose functions can’t be redefined? Maintaining global state for one Julia instruction and rolling back if there’s a catchable segfault crash? Unsure if any of these are feasible, and certainly not for 1.0, but worth an issue?

@vtjnash
Copy link
Member

vtjnash commented Oct 10, 2017

Sure. Before people decided they didn't like that behavior (#19916, #20545, #21027, others), it wouldn't have crashed.

there’s a catchable segfault

Please don't call an arbitrary crash a "segfault". A segfault is a very specific failure that isn't catchable and results in the word "segfault" being printed or displayed.

@kmsquire
Copy link
Member

Before people decided they didn't like that behavior (#19916, #20545, #21027, others), it wouldn't have crashed.

@vtjnash, given that, do you suggest

  1. that those PRs were a bad idea and should be rolled back, because they have the potential to cause these crashes?
  2. that those PRs addressed real issues, and users should be careful not to redefine things that might lead to crashes (and be okay with crashes when they happen)?
  3. neither of these--the current situation is fixable, if someone has the time and knowledge to do so?

Please don't call an arbitrary crash a "segfault". A segfault is a very specific failure that isn't catchable and results in the word "segfault" being printed or displayed.

Okay, updated to "segfault crash". Cheers!

@yuyichao
Copy link
Contributor

users should be careful not to redefine things that might lead to crashes (and be okay with crashes when they happen)?

Yes.

An optional optional blacklist of functions that can’t be redefined, or modules whose functions can’t be redefined?

It could be a good feature to allow doing this, but such features

  1. Should be overwritable or it'll make interactive/base development really annoy.
  2. We should not decide the list of function to do that based on if there will be crashes when a user overwrite something by accident so while some changes can be made, we'll not try to fix issue like this.

@martinholters
Copy link
Member

I've been wondering whether it's feasible to prevent (accidental) type-piracy by ensuring that if a method is added (or overwritten) to a function defined in another module, the signature may not be the supertype of any signature defined solely using types defined outside the current module, except Union{}, unless they have to be subtypes of a type defined in the current module. Does that rule make sense and could it be checked with reasonable effort in general?

Of course, there would have to a be way to disable the check, a @piracy annotation or whatever.

@quinnj
Copy link
Member

quinnj commented Oct 11, 2017

@yes_I_know_what_Im_doing_please_let_me_overwrite_this_very_important_Base_method function Base.+(...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants