Segfault when calling Julia functions
veddox opened this issue · comments
When my QML window calls a function that was defined in Julia and tagged using @qmlfunction
, I get a segfault:
[132030] signal (11.1): Segmentation fault
in expression starting at [...]/run.jl:13
_ZN7qmlwrap8JuliaAPI13set_js_engineEP9QJSEngine at ~/.julia/artifacts/5b399b8a0d2ef4ba00667e41a3fe59db6eaa6000/lib/libjlqml.so (unknown line)
It seems that Edit: I manually installed libjlqml
is not installed - how can I do so?jlqml_jll
0.5.3, but the error persists.
I'm using QML.jl 0.8 with Qt6Base_jll 6.5.2 and CxxWrap 0.14.0 on Julia 1.9.3. Is there any other dependency I need?
I get the same segfault when running the code example at the @qmlfunction
documentation:
julia> using QML
julia> greet() = "Hello, World!";
julia> @qmlfunction greet
julia> mktempdir() do folder
path = joinpath(folder, "main.qml")
write(path, """
import org.julialang
import QtQuick
import QtQuick.Controls
ApplicationWindow {
visible: true
Text {
text: Julia.greet()
}
Timer {
running: true; repeat: false
onTriggered: Qt.exit(0)
}
}
""")
loadqml(path)
exec()
end
I get the same segfault when running the code example at the @qmlfunction documentation
This just got a bit weirder. I realised that the above statement is not strictly true. As long as I call @qmlfunction greet
every time before executing the do
block, it works. If I call the do
block twice in succession, it segfaults.
The error seems to be in this function in jlqml_jll
, but I don't understand the code well enough to see it.
Working through the code of julia_api.cpp
a bit more, I found the following line:
s_singletonInstance->set_js_engine(qmlEngine);
Shouldn't this pass scriptEngine
rather than qmlEngine
?
Thanks for reporting this and looking into it. The reason is that after exec
has returned the internal Qt state is cleaned up completely, and the functions are no longer registered. So inded, you have to call @qmlfunction
again before exec
, but a segfault probably isn't the most user friendly way of communicating this, so that needs to be fixed.
Wonderful, thank you for addressing this so quickly!
However, I don't yet understand how this affects my original problem. Why do I get this segfault straight away when running my own code?
This is the file in question (redacted, but structurally unchanged):
global model = missing
const running = Observable(false)
const date = Observable(today())
const progress = Observable(0.0)
const delay = Observable(0.5)
const runbuttontext = Observable(">>")
const runbuttontip = Observable("Run")
function newsimulation()
# do some stuff
println("Model initialised.")
end
function nextstep()
# do some stuff
println("Updated model.")
end
function runsimulation()
# do some stuff
end
function togglerunning()
if running[]
running[] = false
runbuttontext[] = ">>"
runbuttontip[] = "Run"
else
running[] = true
runbuttontext[] = "||"
runbuttontip[] = "Pause"
runsimulation()
end
end
function render_map(screen)
# do some stuff
end
@qmlfunction newsimulation
@qmlfunction nextstep
@qmlfunction togglerunning
@qmlfunction render_map
on(delay) do d
println("Delay is now $(round(d, digits=1)) seconds.")
end
on(running) do r
r ? println("Simulation started.") : println("Simulation stopped.")
end
"""
launch()
The main function that creates the application.
"""
function launch()
qmlfile = joinpath(dirname(@__FILE__), "main.qml")
loadqml(qmlfile,
vars = JuliaPropertyMap("running" => running,
"date" => date,
"delay" => delay,
"progress" => progress,
"runbuttontext" => runbuttontext,
"runbuttontip" => runbuttontip))
println("Launched program.")
exec()
end
When I load my package and run launch()
, it segfaults immediately. It also crashes when I load the package but then manually execute loadqml()
and exec()
.
Fixed in QML.jl 0.8.1, with documentation here: https://juliagraphics.github.io/QML.jl/dev/#Using-QML.jl-inside-another-Julia-module
Wonderful, thank you for addressing this so quickly!
However, I don't yet understand how this affects my original problem. Why do I get this segfault straight away when running my own code?
This is the file in question (redacted, but structurally unchanged):
global model = missing const running = Observable(false) const date = Observable(today()) const progress = Observable(0.0) const delay = Observable(0.5) const runbuttontext = Observable(">>") const runbuttontip = Observable("Run") function newsimulation() # do some stuff println("Model initialised.") end function nextstep() # do some stuff println("Updated model.") end function runsimulation() # do some stuff end function togglerunning() if running[] running[] = false runbuttontext[] = ">>" runbuttontip[] = "Run" else running[] = true runbuttontext[] = "||" runbuttontip[] = "Pause" runsimulation() end end function render_map(screen) # do some stuff end @qmlfunction newsimulation @qmlfunction nextstep @qmlfunction togglerunning @qmlfunction render_map on(delay) do d println("Delay is now $(round(d, digits=1)) seconds.") end on(running) do r r ? println("Simulation started.") : println("Simulation stopped.") end """ launch() The main function that creates the application. """ function launch() qmlfile = joinpath(dirname(@__FILE__), "main.qml") loadqml(qmlfile, vars = JuliaPropertyMap("running" => running, "date" => date, "delay" => delay, "progress" => progress, "runbuttontext" => runbuttontext, "runbuttontip" => runbuttontip)) println("Launched program.") exec() endWhen I load my package and run
launch()
, it segfaults immediately. It also crashes when I load the package but then manually executeloadqml()
andexec()
.
Is this still an issue with QML 0.8.1?
Is this still an issue with QML 0.8.1?
No. Bart and I had a short video conference yesterday and it works now 🙂
One problem had been that I was calling @qmlfunction
outside of the launch()
function. The other problem was the QML module lookup bug, which is fixed now.