Package Compiler error when reproducing documentation example

While trying to reproduce the first example to create a sysimage with PackageCompiler.jl, I got a

fatal: error thrown and no exception handler available.
ReadOnlyMemoryError()
memcpy at C:\windows\System32\msvcrt.dll (unknown line)

error.

My custom_sysimage.jl reads

Base.init_depot_path()
Base.init_load_path()

using CSV

empty!(LOAD_PATH)
empty!(DEPOT_PATH)

and is located in the current julia folder.

Does somebody have a clue ? or met this error before ?

Here is the full log

>julia --startup-file=no --output-o sys.o -J"D:\\bamboo\\AppData\\Local\\Programs\\Julia 1.5.4\\lib\\julia\\sys.dll" custom_sysimage.jl
fatal: error thrown and no exception handler available.
ReadOnlyMemoryError()
memcpy at C:\windows\System32\msvcrt.dll (unknown line)
ios_write at /cygdrive/c/buildbot/worker/package_win64/build/src/support\ios.c:421
unsafe_write at .\iostream.jl:43
write at .\strings\io.jl:183 [inlined]
print at .\strings\io.jl:185 [inlined]
#with_output_color#745 at .\util.jl:76
unknown function (ip: 0000000011f6b044)
with_output_color##kw at .\util.jl:70 [inlined]
#printstyled#746 at .\util.jl:104 [inlined]
printstyled##kw at .\util.jl:104
unknown function (ip: 0000000011f6a56a)
display_error at .\client.jl:102
display_error at .\client.jl:106
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1691 [inlined]
do_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\builtins.c:674
jl_f__apply at /cygdrive/c/buildbot/worker/package_win64/build/src\builtins.c:688 [inlined]
jl_f__apply_latest at /cygdrive/c/buildbot/worker/package_win64/build/src\builtins.c:724
#invokelatest#1 at .\essentials.jl:710 [inlined]
invokelatest at .\essentials.jl:709 [inlined]
_start at .\client.jl:508
unknown function (ip: 000000000e44a3a3)
jl_apply at /cygdrive/c/buildbot/worker/package_win64/build/src\julia.h:1691 [inlined]
true_main at /cygdrive/c/buildbot/worker/package_win64/build/ui\repl.c:106
wmain at /cygdrive/c/buildbot/worker/package_win64/build/ui\repl.c:227
__tmainCRTStartup at /usr/src/debug/mingw64-x86_64-runtime-8.0.0-1/crt\crtexe.c:328
mainCRTStartup at /usr/src/debug/mingw64-x86_64-runtime-8.0.0-1/crt\crtexe.c:212
BaseThreadInitThunk at C:\windows\System32\KERNEL32.DLL (unknown line)
RtlUserThreadStart at C:\windows\SYSTEM32\ntdll.dll (unknown line)

It seems to me that you’re trying to follow the instructions in the “manual way” section of PackageCompiler’s documentation; as I understand it, this section is mostly there to explain what happens under the hood.

The primary user-facing interface that PackageCompiler exposes to build system images is the create_sysimage function, presented in earlier sections of its documentation:

In short, creating a system image should be as simple as:

using PackageCompiler
create_sysimage(
    # list of packages you want to include in the sysimage
    [:Plots, :DataFrames],

    # where to put the generated sysimage
    sysimage_path = joinpath("my_image.so"),

    # optional: a custom script that triggers the compilation of the
    # methods you want to embed in the sysimage
    precompile_execution_file = "precomp.jl", 
)

Thanks for the pointers. I will check that ASAP.
I went to that example because my end goal is to actually create binaries (specifically dlls) from julia code.
That’s why I went to the Creating a binary from Julia code section.

Perhaps take a look at https://github.com/JuliaLang/PackageCompiler.jl/pull/490

1 Like

Well, this seems very promising ! It is not pulled yet, but it seems to be exactly what I am looking for. Thanks a lot !

I just tested your approach, replacing the packages and scripts with some of my own, but (as expected) this returns a .so file which seems to be linux specific, while I am on a Windows machine. Am I missing something here ?

I suspect it is actually a DLL; it only appears to be a shared library because of its name ending in “.so”.
Maybe try renaming the produced file to “.dll”, or simply change the sysimage_path argument in the script to generate a .dll file.

I don’t have much experience using PackageCompiler on Windows, but it should work in the same way as other OS.

I modified my create_sysimage call to obtain a .dll file. As you suggested, it is probably close to a native .dll. In fact, I tried to read into the file using the dumpbin executable as suggested in windows - How to check for DLL dependency? - Stack Overflow.
The result of dumpbin my_image.dll /exports reads

Microsoft (R) COFF/PE Dumper Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file my_image.dll

File Type: DLL

  Section contains the following exports for my_image.dll

    00000000 characteristics
    60744E01 time date stamp Mon Apr 12 15:41:21 2021
        0.00 version
           1 ordinal base
          14 number of functions
          14 number of names

    ordinal hint RVA      name

          1    0 0AB092C8 jl_RTLD_DEFAULT_handle_pointer
          2    1 0AB30B38 jl_dispatch_fvars_idxs
          3    2 0AB30B3C jl_dispatch_fvars_offsets
          4    3 0AB30B34 jl_dispatch_reloc_slots
          5    4 0AB30AC0 jl_dispatch_target_ids
          6    5 0AC57128 jl_get_ptls_states_slot
          7    6 0AB30B40 jl_globalUnique
          8    7 0000FA20 jl_sysimg_fvars_base
          9    8 0AB092D0 jl_sysimg_fvars_offsets
         10    9 0AC387A0 jl_sysimg_gvars_base
         11    A 0AB20CD0 jl_sysimg_gvars_offsets
         12    B 00920300 jl_system_image_data
         13    C 0AB30B48 jl_system_image_size
         14    D 0AC57130 jl_tls_offset

  Summary

        1000 .CRT
       22000 .bss
     A1D8000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
      738000 .debug_info
      3F3000 .debug_line
        1000 .debug_macinfo
      5AA000 .debug_ranges
       67000 .debug_str
        1000 .edata
        2000 .idata
       49000 .pdata
       3B000 .rdata
        1000 .reloc
      91E000 .text
        1000 .tls
       BB000 .xdata

Obviously, this is quite unreadable for an uneducated user, though I would have expected at least some of my functions / structs to be mentioned here as I have some functions and structs exported from my module.
I remember some Base.@ccallable macro in the documentation, but it does not seem to be available anymore. However, I just encountered the macro Base.@cfunction which seems to be designated to export a function for use in C, yet I can’t figure if it should be used with PackageCompiler.

I also tested to read the dll file using the procedure proposed in this SO answer. However, IL DASM returns my_image.dll has no valid CLR header and cannot be disassembled … So I guess this explains the developments mentioned by @kristoffer.carlsson.