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

World age assertion adding backedges #23981

Closed
c42f opened this issue Oct 3, 2017 · 6 comments · Fixed by #24449
Closed

World age assertion adding backedges #23981

c42f opened this issue Oct 3, 2017 · 6 comments · Fixed by #24449
Assignees

Comments

@c42f
Copy link
Member

c42f commented Oct 3, 2017

Hi guys, I've been struggling with several crashes while trying to improve the depwarn reporting over at #23712. In release mode there are segfaults, while in debug mode there's an assertion related to the world age (possibly related, possibly not).

After rebuilding Base a lot of times, I've got the following minimial reproduction against a recent master (debug build):

   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.7.0-DEV.2006 (2017-09-29 20:01 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit a6022fd* (4 days old master)
|__/                   |  x86_64-linux-gnu

julia> Base.eval(quote
              _depwarn(msg, opts, bt, caller) = (1:10) .+ 1
              end)
julia.7: /home/cfoster/src/julia/src/gf.c:1351: jl_method_instance_add_backedge: Assertion `callee->min_world <= caller->min_world && callee->max_world >= caller->max_world' failed.

signal (6): Aborted
in expression starting at no file:0
raise at /build/glibc-bfm8X4/glibc-2.23/signal/../sysdeps/unix/sysv/linux/raise.c:54
abort at /build/glibc-bfm8X4/glibc-2.23/stdlib/abort.c:89
__assert_fail_base at /build/glibc-bfm8X4/glibc-2.23/assert/assert.c:92
__assert_fail at /build/glibc-bfm8X4/glibc-2.23/assert/assert.c:101
jl_method_instance_add_backedge at /home/cfoster/src/julia/src/gf.c:1351
finalize_backedges at ./inference.jl:2871
typeinf at ./inference.jl:3327
typeinf_edge at ./inference.jl:3017
jl_call_fptr_internal at /home/cfoster/src/julia/src/julia_internal.h:366
jl_call_method_internal at /home/cfoster/src/julia/src/julia_internal.h:385
jl_apply_generic at /home/cfoster/src/julia/src/gf.c:1980
abstract_call_method at ./inference.jl:1869
...

Some help or helpful suggestions about what to do next would be greatly appreciated at this point!

Possibly related - #23768

@c42f
Copy link
Member Author

c42f commented Oct 6, 2017

By the way, this error disappears when inlining is disabled.

@c42f
Copy link
Member Author

c42f commented Oct 7, 2017

I've been making some (slow) progress on this by digging around in inference, as the crashes are blocking further work on the logging package.

One oddity I've just noticed is that MethodInstance.min_world is declared as jl_long_type, while in other places the world counter seems to be size_t (eg, InferenceState.min_valid). This might be quite a problem, as typemax(UInt) tends to be stored in max_world and some inequality comparisons happen in various places. Same potential problem for world counter type clashes exist in TypeMapEntry, Method, possibly other places.

@vtjnash
Copy link
Member

vtjnash commented Oct 7, 2017

jl_long_type is a size_t everywhere (we don't agree with the Win64 mistake of using the LLP64 model)

there's some debugging code in #22355 (comment)

@c42f
Copy link
Member Author

c42f commented Oct 7, 2017

It's not the bit width, but the signedness which I'm worried about. jl_long_type is signed, but size_t is always unsigned. From julia.h:

#define jl_long_type     jl_int64_type

@c42f
Copy link
Member Author

c42f commented Oct 8, 2017

Thanks for the debugging patch. I tried that out, but in this particular case it doesn't trigger any extra output.

I've been inserting a bit of my own debug logging into inference. It's simple to see that the bad edge is print_to_string calling #print_to_string#247. More interesting, this occurs when analyzing a cycle starting at join, where callers_in_cycle appears to contain two calls to print_to_string(::Vararg{Any,N}) where N, with different world ages. This seems suspicious...

@c42f
Copy link
Member Author

c42f commented Oct 8, 2017

For what seems to be the offending frame, frame.min_valid and frame.linfo.min_world are inconsistent after a call to finish - I'm not sure whether that's a problem or expected.

vtjnash added a commit that referenced this issue Nov 2, 2017
This was over-aggressive. It was only correct in the case where we where
depending on the `.inferred` field or `.rettype` contents exactly.
However, sometimes inference of the method instead depends on `.def.source`.

fix #23981
fix #23768
vtjnash added a commit that referenced this issue Nov 6, 2017
This was over-aggressive. It was only correct in the case where we where
depending on the `.inferred` field or `.rettype` contents exactly.
However, sometimes inference of the method instead depends on `.def.source`.

fix #23981
fix #23768
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

Successfully merging a pull request may close this issue.

2 participants