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

Rework broken-precompilation warning #35410

Merged
merged 1 commit into from
Apr 13, 2020
Merged

Conversation

c42f
Copy link
Member

@c42f c42f commented Apr 9, 2020

This allows me to use Core.eval() for replacing parts of jl_parse_eval_all with Julia code (part of #35243) by splitting out the warning separately. It also allows us to use the normal logging system and Base infrastructure to format the warning more nicely, including the stacktrace and pretty printing of the expression.

For bootstrap I've copied @vtjnash's bootstrap trick where include methods are deleted and redefined. Does this seem ok for use with eval? I'm unsure whether it can leave unwanted traces of the old methods in the sysimg, as I don't fully understand the world age and code caching infrastructure.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Apr 9, 2020

We strongly don't want this to go through the normal machinery—this is explicitly trying to print a fatal error message and should not be easily diverted. I'd be well okay with turning this into a call to throw however.

@c42f
Copy link
Member Author

c42f commented Apr 9, 2020

I'd be ok with making it throw because the stacktrace is actually the most important thing for users to diagnose problems here (it's the module calling eval which is often at fault, not the module which is being eval'd into).

Jeff asked why this was even necessary given that jl_current_modules should contain the module being precompiled, but I didn't know. I'm looking into that now.

@c42f
Copy link
Member Author

c42f commented Apr 9, 2020

Ok, so here's the story:

Base.__toplevel__ is used as the parent module for package precompilation, but is not itself rooted in jl_current_modules. However, create_expr_cache in loading.jl uses Base.include(__toplevel__, modulefile) to bring in the code rather than eval.

It turns out that Base.include just doesn't do this check so it's currently possible to bypass the warning in released julia versions by simply using Base.include(some_other_module, "nefarious_content.jl")

@c42f
Copy link
Member Author

c42f commented Apr 9, 2020

Ok, how about this? I've added a special case to consider Base.__toplevel__ permanently open, and made the warning an error instead.

Changes to fix the bug in include will come separately as part of #35243

src/toplevel.c Outdated Show resolved Hide resolved
@JeffBezanson
Copy link
Sponsor Member

Ah, ok, great. I like making it an error --- good to be decisive about what is and isn't allowed! Will be good to close the include loophole too.

@c42f c42f changed the title Emit broken-precompilation warnings from the julia layer Rework broken-precompilation warning Apr 9, 2020
@c42f
Copy link
Member Author

c42f commented Apr 9, 2020

I thought I should just go ahead and close the include loophole so I've done that as well.

@c42f
Copy link
Member Author

c42f commented Apr 9, 2020

Tests added. Hopefully this is good to go now provided CI passes.

@c42f
Copy link
Member Author

c42f commented Apr 10, 2020

Test failures look spurious. Win32 is a code signing problem, aarch64 presumably whatever existing problem has been causing it to segfault in several recent PRs.

@KristofferC
Copy link
Sponsor Member

A rebase should fix the aarch problem.

* Make incremental compilation failures an error.
* Remove loophole which allowed Base.include to skip the incremental
  compilation warning
* Add special case so that `Base.__toplevel__` is never considered
  closed, allowing normal use of include()
@c42f
Copy link
Member Author

c42f commented Apr 10, 2020

A rebase should fix the aarch problem.

Done + squashed.

@JeffBezanson JeffBezanson merged commit 0e96f04 into master Apr 13, 2020
@JeffBezanson JeffBezanson deleted the cjf/eval-precomp-warning branch April 13, 2020 14:37
ztultrebor pushed a commit to ztultrebor/julia that referenced this pull request Apr 17, 2020
* Make incremental compilation failures an error.
* Remove loophole which allowed Base.include to skip the incremental
  compilation warning
* Add special case so that `Base.__toplevel__` is never considered
  closed, allowing normal use of include()
staticfloat pushed a commit that referenced this pull request Apr 21, 2020
* Make incremental compilation failures an error.
* Remove loophole which allowed Base.include to skip the incremental
  compilation warning
* Add special case so that `Base.__toplevel__` is never considered
  closed, allowing normal use of include()
tkf added a commit to JuliaPy/pyjulia that referenced this pull request Aug 2, 2020
eval Base-based monkey-patching stopped working as of Julia 1.5 presumably
because eval-ing to another module during precompilation now throws an
error: JuliaLang/julia#35410

This PR workarounds this by creating the system image in two stages:

  1.   The first stage is monkey-patching as done before but without
      PyCall. This way, we don't get the error because julia does not
      try to precompile any packages.

  2.   The second stage is the inclusion of PyCall. At this point, we are
      in a monkey-patched system image. So, it's possible to precompile
      PyCall now.

Note that even importing PackageCompiler.jl itself inside julia-py is
problematic because (normally) it has to be precompiled. We avoid this
problem by running PackageCompiler.jl under --compiled-modules=no. This is
safe to do thanks to PackageCompiler.do_ensurecompiled
(https://github.com/JuliaLang/PackageCompiler.jl/blob/3f0f4d882c560c4e4ccc6ab9a8b51ced380bb0d5/src/PackageCompiler.jl#L181-L188)
using a custom function PackageCompiler.get_julia_cmd
(https://github.com/JuliaLang/PackageCompiler.jl/blob/3f0f4d882c560c4e4ccc6ab9a8b51ced380bb0d5/src/PackageCompiler.jl#L113-L116)
(instead of Base.julia_cmd) and ignores --compiled-modules=no of the current
process.
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 this pull request may close these issues.

5 participants