How correct open and close Julia DLL in C++?

When I compiled Julie with my own userimg.jl sometimes the compile process does not create correct the DLL (System Image Building with help of createDLL.bat). Here’s the key command.

%Pathname%\julia.exe “%workDir%build_sysimg_tim.jl” libXJZ core2 “%workDir%userimg.jl” --force

Sometimes, after compilation I can not open the final libXJZ_tim.dll in C/C++ with the help of julia.h (Embedding Julia). I get error in function jl_init_with_image() respectively program only crash :frowning: .
Here is the print screen

I also created mini statistics good/ bad open DLLs (Of course without changing the code, I just called the compilation script).

I created a simple demo in Visual Studio with function foo() to control the DLL opening. Function jl_init_with_image() calls julia_init() where program crash. I modify jl_init_with_image and created own version to detect the problem.

My questions are:
I. How to exit the program correctly when the function julia_init() does not return anything and the program only crash?
(How to capture an exception?,…?)

II. How to ensure stable compilation for system image building to work every created dll?

All the necessary files with good/ bad DLL and Project Visual Studio are in Drive.
This topic is closely related “Static julia compilation with own package”

INFO:
Microsoft Visual Studio Community 2015, Version: 14.0.
On Windows 8.1

julia> versioninfo()
Julia Version 0.5.1
Commit 6445c82 (2017-03-05 13:25 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Xeon(R) CPU E5-2430L v2 @ 2.40GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
LAPACK: libopenblas64_
LIBM: libopenlibm
LLVM: libLLVM-3.7.1(ORCJIT, ivybridge)

As mentioned in the other thread, please start from the embedding example!

I’m not going to debug your code at the moment, but my main comment is that in 0.6 the only call you should need is jl_init() (on 0.5 you need to provide the image path). You should not need to call libsupport_init yourself, and it’s not clear why so much other initialization code is duplicated. Again, start from the embedding example and the default system image: make sure you can compile it with MSVC, then work from there.

I’m not sure I understand the first question: if the program crashes, it crashes… [edit: the runtime doesn’t exist at that point, so there’s no Julia-level exception to capture – the debugger is the only option then]

For the second question: if you can isolate a build issue in a clean way (using the recommended initialization functions), then please file a bug and hopefully someone can take a look. However, we are now exercising the embedding code on Windows (and elsewhere) with every Continuous Integration (appveyor) run, so hopefully such an issue would have been seen already. Ref:

https://github.com/JuliaLang/julia/pull/21299

I’m not sure I understand the first question: if the program crashes, it crashes…

The problem is that the program crashes, and doesn’t treat the crash itself - there is no error returned. jl_init_with_image doesn’t return anything. (so we cannot correctly close the process which calls jl_init_with_image)

For the second question…

The problems can be following:

  • There is no error in Julia code, but some names for example variable e conflicts. This produces warning at least, but the compiled DLL may or may not crash - undefined behavior in other words!
  • The build process (compiling and linking Julia code into DLL) finishes without any error or warning. But the code doesn’t run as expected. After a long and desperate debugging one finds and error in Julia code (might be simple typo). I compare it to C++ as an example: compiler checks each and every character of the code, and once compiled, I’m sure the code is correct (I mean the code syntactically itself). In Julia until we run the code, we don’t know if we have correct code. Of course we can write a unit test for each and every line of code… I personally like what Stroustrup said in C++ book: don’t try to be smarter than compiler and use compiler as at tool for finding errors.

Are you trying to say that you like static languages more than dynamic languages?

I don’t try to say what I like more :slight_smile:
I’m describing everyday problems, that we’re facing, when trying to use Julia for product development. And since I’ve been using C++ for 10+ years (in MS VS), it comes to me natural to compare it. I started with Julia a year ago.

Julia is great math library.

And it is hard to compare languages itself. Great part of a ‘feeling’ comes for me from development environment. We all know work in Visual Studio is great.

As far as runtime errors, for the most part, that’s a known design trade-off when choosing to use Julia.

In general, I would suggest you get familiar with and use GDB to debug initialization issues, because debugging and backtraces should make more sense there than in MSVC.

Thanks for suggesting GDB.
I don’t use MSVS for debugging Julia lib (what doesn’t make sense as you pointed out). I just mean debugging native C++ code is great there.

I also get a stackoverflow when trying to embed Julia-0.6.1-pre.0 in C#. Issue #22320 seems like it might be related. I tried increasing the stack size of the .Net executable, but it didn’t help.

Yes, that’s exactly the issue. Unfortunately I’m not sure what, if anything, can be done about that in the short term.

As far as the work-around, could you please double-check against 0.6 release? I have used 8MB stack size with C# and C++ on VS2015 against some pre-release or late nightly in the 0.6 series, I’m not sure the date exactly, and it worked in simple initialization and call tests (the specific problem is too-deep recursion while reading back the system image).

I have the same issue with the official 0.6.0 download. BUT, it turns out, it works just fine if you run it from the command line, rather than from visual studio. In the version I built, I get the following error even though the dll is in the bin directory.

Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.

OK, it works, if I copy the mkl_intel_thread.dll to the same directory as the .Net executable.

That seems unrelated to the stack size issue, just the usual Windows DLL hell :weary:.

1 Like