hoffstadt / DearPyGui

Dear PyGui: A fast and powerful Graphical User Interface Toolkit for Python with minimal dependencies
https://dearpygui.readthedocs.io/en/latest/
MIT License
12.94k stars 676 forks source link

Delete widget cause crash if widget is an image #554

Open GivralNguyen opened 3 years ago

GivralNguyen commented 3 years ago

Version of Dear PyGui

Version: 0.6.157 Operating System: Ubuntu 18.04 (Windows 10, macOs xx, Ubuntu 20.04, etc.)

My Issue/Question

Delete widget cause crash ( Segmentation fault (core dumped) ) if widget contains an image ( or image button). Otherwise it works fine.

To Reproduce

I follow the example in https://github.com/hoffstadt/DearPyGui/wiki/Runtime-Adding-and-Deleting-Widgets .

Example code

from dearpygui.core import *
from dearpygui.simple import *

def add_widgets(sender, data):

    with window("Secondary Window"): # simple
        #add_button("New Button")
        add_image_button("image","/home/quannm/DearPyGui/GUI/0183_c6s1_042351_01.jpg",show=True)
def delete_children(sender, data):
    delete_item("Secondary Window", children_only=True)

show_debug()

with window("Tutorial"):
    add_button("Add Window and Items", callback=add_widgets)
    add_button("Delete Window's Children", callback=delete_children)
start_dearpygui() 

Expected behavior

If you add button , the code works as intended. However, if you add an image ( or image button), the program crash when you try to delete widget.

nvglucifer commented 3 years ago

image

hoffstadt commented 3 years ago

Can't seem to reproduce this on windows. Will check on linux later today.

GivralNguyen commented 3 years ago

Have you tested on Ubuntu? It still crash when i try to delete an image or image button using the given code. The only error shown is Segmentation Fault (core dumped)

hoffstadt commented 3 years ago

Sorry. Will check today and if confirmed, will fix it today!

hoffstadt commented 3 years ago

Does this occur on the newest version?

hoffstadt commented 3 years ago

Closing. No response.

eyecan-ai commented 2 years ago

Same here in Ubuntu 20.0, version 1.4.0. Trying to delete a texture will cause the crash Same behavior is fine on MacOSX

hoffstadt commented 2 years ago

Will check into it again on a new linux Machine I got this week.

tobyclh commented 1 year ago

Hi @hoffstadt I am still experiencing this issue together with #1371 on Ubuntu, is there any update? I updated OP's code to use the newer API.

import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()

def add_widgets(sender, data):

    with dpg.window(label="Secondary Window", tag='window'): # simple
        #add_button("New Button")
        width, height, channels, data = dpg.load_image("IMG.jpg")
        with dpg.texture_registry(show=False):
            dpg.add_static_texture(width=width, height=height, default_value=data, tag="texture_tag")
        dpg.add_image_button('texture_tag', label="image", show=True)
def delete_children(sender, data):
    dpg.delete_item("window")
    dpg.delete_item('texture_tag')

dpg.show_debug()

with dpg.window(label="Tutorial"):
    dpg.add_button(label="Add Window and Items", callback=add_widgets)
    dpg.add_button(label="Delete Window's Children", callback=delete_children)
dpg.show_viewport()

dpg.start_dearpygui() 
dpg.destroy_context()
TKmist commented 1 year ago

Hi @hoffstadt, I used the code above posted by @tobyclh on two Linux machines (Fedora 35 and Fedora 34). I used almost the same conda environment on both machines (environment info below). I reproduced the issue on Fedora 34 machine, while on Fedora 35, everything worked fine. The difference in both systems is in the glibc version. Could this be a reason?

Fedora 34 env info: conda version : 22.9.0
conda-build version : 3.21.9
python version : 3.8.8.final.0 virtual packages : cuda=9.1=0 linux=5.16.12=0 glibc=2.33=0 unix=0=0 __archspec=1=x86_64 user-agent : conda/22.9.0 requests/2.28.1 CPython/3.8.8 Linux/5.16.12-100.fc34.x86_64 fedora/34 glibc/2.33

Fedora 35 env info: conda version : 22.9.0 conda-build version : 3.21.9 python version : 3.8.8.final.0 virtual packages : linux=5.19.6=0 glibc=2.34=0 unix=0=0 archspec=1=x86_64 user-agent : conda/22.9.0 requests/2.28.1 CPython/3.8.8 Linux/5.19.6-100.fc35.x86_64 fedora/35 glibc/2.34

jamesdolezal commented 1 year ago

I can reproduce the same issue, using the above code snippet, on Ubuntu 22.04 & Python 3.9.13. Not sure if the problem is glibc - my version is 2.35.

jamesdolezal commented 1 year ago

This is the GDB stacktrace, if it's helpful:

(gdb) info frame
Stack level 3, frame at 0x7ffff5b5c2f0:
 rip = 0x7ffff62e9e6a in DeleteChild(mvAppItem*, unsigned long long); saved rip = 0x7ffff62ea074
 called by frame at 0x7ffff5b5c360, caller of frame at 0x7ffff5b5c260
 Arglist at 0x7ffff5b5c258, args: 
 Locals at 0x7ffff5b5c258, Previous frame's sp is 0x7ffff5b5c2f0
 Saved registers:
  rbx at 0x7ffff5b5c2b8, rbp at 0x7ffff5b5c2c0, r12 at 0x7ffff5b5c2c8, r13 at 0x7ffff5b5c2d0, r14 at 0x7ffff5b5c2d8, r15 at 0x7ffff5b5c2e0,
  rip at 0x7ffff5b5c2e8
(gdb) bt
#0  0x00007ffff5c24f29 in ?? () from /lib/x86_64-linux-gnu/libGLdispatch.so.0
#1  0x00007ffff61c873b in FreeTexture(void*) () from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#2  0x00007ffff625cc88 in mvStaticTexture::~mvStaticTexture() ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#3  0x00007ffff62e9e6a in DeleteChild(mvAppItem*, unsigned long long) ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#4  0x00007ffff62ea074 in DeleteRoot(std::vector<std::shared_ptr<mvAppItem>, std::allocator<std::shared_ptr<mvAppItem> > >&, unsigned long long) ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#5  0x00007ffff62ea60e in DeleteItem(mvItemRegistry&, unsigned long long, bool, int) ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#6  0x00007ffff614f7bb in delete_item(_object*, _object*, _object*) ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#7  0x0000000000507f97 in cfunction_call (func=0x7ffff5ba2ae0, args=<optimized out>, kwargs=<optimized out>)
    at /usr/local/src/conda/python-3.9.13/Objects/methodobject.c:543
#8  0x0000000000506498 in _PyObject_Call (kwargs=<optimized out>, args=0x7ffff757fc40, callable=0x7ffff5ba2ae0, tstate=0x7ffff0000ba0)
    at /usr/local/src/conda/python-3.9.13/Objects/call.c:281
#9  PyObject_Call (callable=0x7ffff5ba2ae0, args=0x7ffff757fc40, kwargs=<optimized out>) at /usr/local/src/conda/python-3.9.13/Objects/call.c:293
#10 0x00000000004edc89 in do_call_core (kwdict=0x7ffff7635340, callargs=0x7ffff757fc40, func=0x7ffff5ba2ae0, tstate=<optimized out>)
    at /usr/local/src/conda/python-3.9.13/Python/ceval.c:5097
#11 _PyEval_EvalFrameDefault (tstate=<optimized out>, f=0x7ffff7304950, throwflag=<optimized out>)
    at /usr/local/src/conda/python-3.9.13/Python/ceval.c:3582
#12 0x00000000004e729a in _PyEval_EvalFrame (throwflag=0, f=0x7ffff7304950, tstate=0x7ffff0000ba0)
    at /usr/local/src/conda/python-3.9.13/Include/internal/pycore_ceval.h:40
#13 _PyEval_EvalCode (tstate=<optimized out>, _co=<optimized out>, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, 
    argcount=<optimized out>, kwnames=0x0, kwargs=0x7ffff7301da0, kwcount=<optimized out>, kwstep=1, defs=0x0, defcount=<optimized out>, 
    kwdefs=0x7ffff5bd77c0, closure=0x0, name=0x7ffff748a7b0, qualname=0x7ffff748a7b0) at /usr/local/src/conda/python-3.9.13/Python/ceval.c:4329
#14 0x00000000004f8645 in _PyFunction_Vectorcall (func=<optimized out>, stack=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>)
    at /usr/local/src/conda/python-3.9.13/Objects/call.c:396
#15 0x00000000004ecebf in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=<optimized out>, args=0x7ffff7301d98, callable=0x7ffff5bd90d0, 
    tstate=0x7ffff0000ba0) at /usr/local/src/conda/python-3.9.13/Include/cpython/abstract.h:118
#16 PyObject_Vectorcall (kwnames=0x0, nargsf=<optimized out>, args=0x7ffff7301d98, callable=0x7ffff5bd90d0)
    at /usr/local/src/conda/python-3.9.13/Include/cpython/abstract.h:127
#17 call_function (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffff0000ba0)
    at /usr/local/src/conda/python-3.9.13/Python/ceval.c:5077
#18 _PyEval_EvalFrameDefault (tstate=<optimized out>, f=0x7ffff7301c10, throwflag=<optimized out>)
    at /usr/local/src/conda/python-3.9.13/Python/ceval.c:3489
#19 0x00000000004f8923 in _PyEval_EvalFrame (throwflag=0, f=0x7ffff7301c10, tstate=0x7ffff0000ba0)
    at /usr/local/src/conda/python-3.9.13/Include/internal/pycore_ceval.h:40
#20 function_code_fastcall (tstate=0x7ffff0000ba0, co=<optimized out>, args=<optimized out>, nargs=<optimized out>, globals=0x7ffff76351c0)
    at /usr/local/src/conda/python-3.9.13/Objects/call.c:330
#21 0x00007ffff628b9a8 in mvRunCallback(_object*, unsigned long long, _object*, _object*, bool) ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
--Type <RET> for more, q to quit, c to continue without paging--
#22 0x00007ffff628baf1 in std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::__future_base::_Task_state<mvAddCallback(_object*, unsigned long long, _object*, _object*, bool)::{lambda()#1}, std::allocator<int>, void ()>::_M_run()::{lambda()#1}, void> >::_M_invoke(std::_Any_data const&) ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#23 0x00007ffff6197939 in std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) () from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#24 0x00007ffff7d0ff68 in __pthread_once_slow (once_control=0x1148138, init_routine=0x7ffff5d70db0 <__once_proxy>) at ./nptl/pthread_once.c:116
#25 0x00007ffff6288c13 in std::__future_base::_Task_state<mvAddCallback(_object*, unsigned long long, _object*, _object*, bool)::{lambda()#1}, std::allocator<int>, void ()>::_M_run() ()
   from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#26 0x00007ffff628a74e in mvRunCallbacks() () from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#27 0x00007ffff613c46b in std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<bool>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<setup_dearpygui(_object*, _object*, _object*)::{lambda()#1}> >, bool> >::_M_invoke(std::_Any_data const&) () from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#28 0x00007ffff6197939 in std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) () from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#29 0x00007ffff7d0ff68 in __pthread_once_slow (once_control=0x88ddd8, init_routine=0x7ffff5d70db0 <__once_proxy>) at ./nptl/pthread_once.c:116
#30 0x00007ffff61402b9 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<setup_dearpygui(_object*, _object*, _object*)::{lambda()#1}> >, bool>::_Async_state_impl(std::thread::_Invoker<std::tuple<setup_dearpygui(_object*, _object*, _object*)::{lambda()#1}> >&&)::{lambda()#1}> > >::_M_run()
    () from /home/shawarma/anaconda3/envs/slideflow/lib/python3.9/site-packages/dearpygui/_dearpygui.so
#31 0x00007ffff5d722b3 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#32 0x00007ffff7d0ab43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#33 0x00007ffff7d9ca00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
jophish commented 1 year ago

I can also reproduce with @tobyclh's snippet. glibc=2.36, python=3.11.0, linux kernel=6.0.8-arch1-1.

This is a pretty big blocker to using DearPyGui for me; not being able to delete textures means my application has rampant memory leaks, making it unusable :(

mef51 commented 1 year ago

I can reproduce this on macOS 13.3 M2 in DPG 1.9.1 as well using add_static_texture, add_dynamic_texture and add_raw_texture. However, the issue does not occur if the window using the texture is not shown. So perhaps the cause of this is the frame attempting to render the texture while it is being deleted?

v-ein commented 9 months ago

Here's what probably happens behind the scenes. There's a discussion on the Nvidia forum that has given me an idea (another discussion on Discord revealed that this issue occurs on Nvidia drivers but not on Intel graphics):

https://forums.developer.nvidia.com/t/solved-bound-by-flame-crashes-with-the-361-16-beta-gtx-970-fedora-23-64bit/40951/8

In particular, this line is interesting, along with the mention of a segfault on glDeleteTextures:

The application apparently calls glDeleteTextures() from a thread where no GLX context was ever made current

Now, back to DPG. First of all, a texture gets loaded in the main thread, during rendering. That's where all OpenGL work happens.

Later on, DPG calls the button callback in the handlers thread, i.e. in a thread that has no OpenGL context at all (or at least shoud not have it). Somewhere along the deletion, mvStaticTexture destructor gets called (or another destructor - depending on what widget you're using), and in the end it gets down to glDeleteTextures - but there's no GL context in this thread!

I bet some drivers would ignore the glDeleteTextures call, some might decide to delete the texture anyway (since most applications create only one context anyway), and libglvnd prefers to simply crash :joy:.

v-ein commented 9 months ago

Starting your app with the environment variable __GLVND_DISALLOW_PATCHING=1 might help, but it's only a workaround. Ideally we need to delete textures in the main thread OR select the GL context in another thread before doing glDeleteTextures (not sure if the latter is doable).

Shoun2137 commented 9 months ago
import platform
import os
if platform.system().upper() == "LINUX":
    os.environ["__GLVND_DISALLOW_PATCHING"] = "1"

For the time being, this is how you guys can monkeypatch it into the code, remember to put it BEFORE any initialization of DPG. It should fix problems for nvidia users, shouldn't cause any problems for amd/intel users.