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

Properties passed to loadqml makes app to crash when loaded from module #165

Closed
JanisErdmanis opened this issue May 24, 2023 · 9 comments
Closed

Comments

@JanisErdmanis
Copy link

In the current master version of QML, in a situation where an application code is placed within a module exposing a julia_main function to start the application, there happens to be a crash when this julia_main function is called. As an example, consider the following:

module QMLApp

using QML


const _PROPERTIES = JuliaPropertyMap(
    "text" => "Hello World Again!",
    "count" => 16
)


function julia_main()::Cint

    loadqml((@__DIR__) * "/App.qml"; _PROPERTIES)
    exec()

    return 0
end

end # module QMLApp

When called from a module with using QMLApp; QMLApp.julia_main() a following error happens:

ERROR: C++ object of type N7qmlwrap16JuliaPropertyMapE was deleted
Stacktrace:
  [1] cxxupcast
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:624 [inlined]
  [2] cxxupcast
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:274 [inlined]
  [3] cxxupcast
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:277 [inlined]
  [4] convert
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:682 [inlined]
  [5] cxxconvert
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:582 [inlined]
  [6] cconvert
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:558 [inlined]
  [7] _set_context_property
    @ ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:624 [inlined]
  [8] set_context_property(ctx::QML.QQmlContextDereferenced, name::String, value::QML._JuliaPropertyMapAllocated)
    @ QML ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:61
  [9] set_context_property(ctx::CxxWrap.CxxWrapCore.CxxPtr{QML.QQmlContext}, name::String, jpm::QML.JuliaPropertyMap)
    @ QML ~/.julia/packages/CxxWrap/aXNBY/src/CxxWrap.jl:408
 [10] loadqml(qmlfilename::String; kwargs::Base.Pairs{Symbol, QML.JuliaPropertyMap, Tuple{Symbol}, NamedTuple{(:_PROPERTIES,), Tuple{QML.JuliaPropertyMap}}})
    @ QML ~/.julia/packages/QML/dFnTL/src/QML.jl:90
 [11] loadqml
    @ ~/.julia/packages/QML/dFnTL/src/QML.jl:86 [inlined]
 [12] julia_main()
    @ QMLApp ~/BtSync/PeaceFounder/SandBox/QMLApp/src/QMLApp.jl:14
 [13] top-level scope
    @ REPL[2]:1

This error does not happen if the _PROPERTIES are not passed to loadqml. Also, interestingly, the code works fine when the module is included within a file like include("src/QMLApp.jl"); QMLApp.julia_main().

A full self-contained example is available at https://github.com/JanisErdmanis/QMLAppTest/tree/julia_main_bug

@ufechner7
Copy link
Member

Can you replicate the issue with QML 0.8?

@ufechner7 ufechner7 added the needs more info Clarification or reproducable example needed label Sep 29, 2023
@JanisErdmanis
Copy link
Author

Yes, I just tested it with Julia 1.9.2 and QML 0.8. The error is still there.

@ufechner7 ufechner7 added bug and removed needs more info Clarification or reproducable example needed labels Oct 2, 2023
@ufechner7
Copy link
Member

Which operating system are you using?

@ufechner7 ufechner7 added the needs more info Clarification or reproducable example needed label Oct 2, 2023
@JanisErdmanis
Copy link
Author

MacOS 14 on Apple silicon. I will check it later on Ubuntu.

@ufechner7 ufechner7 added the mac label Oct 8, 2023
@JanisErdmanis
Copy link
Author

I can report that the problem persists when using Ubuntu 22.10 with Julia 1.9.3 and the current QML 0.8 version.

@ufechner7 ufechner7 added linux and removed needs more info Clarification or reproducable example needed labels Oct 8, 2023
@barche
Copy link
Collaborator

barche commented Oct 13, 2023

The reason for this is that _PROPERTIES actually stores a pointer to a C++ object, so it stores a pointer during precompilation that is then used in a later run, but of course no longer valid. To work around that you can return _PROPPERTIES from a function instead of making it a module constant.

barche added a commit that referenced this issue Oct 16, 2023
Issue Properties passed to `loadqml` makes app to crash when loaded from module #165
Issue Segfault when calling Julia functions #183
@barche
Copy link
Collaborator

barche commented Oct 16, 2023

The new documentation at https://juliagraphics.github.io/QML.jl/dev/#Using-QML.jl-inside-another-Julia-module should make this clearer, so I'm closing this.

@barche barche closed this as completed Oct 16, 2023
@JanisErdmanis
Copy link
Author

This makes sense. Another workaround I just tested is that one can define the relevant global variables in the __init__ block:

module QMLApp

using QML

function __init__()

    global PROPERTIES = JuliaPropertyMap(
        "text" => "Hello World Again!",
        "count" => 16
    )

end

function julia_main()::Cint

    loadqml((@__DIR__) * "/App.qml"; PROPERTIES)
    exec()

    return 0
end

end 

This makes it easier to structure larger applications where passing multiple properties to every function would be cumbersome. It also seems necessary for processing signals on the Julia side, which updates the model and ultimately from which QML redraws the view.

@barche
Copy link
Collaborator

barche commented Oct 18, 2023

Indeed, good solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants