python / cpython

The Python programming language
https://www.python.org
Other
63.38k stars 30.35k forks source link

Segfault while (probably incorrectly) using Tkinter #122005

Open RLH-2110 opened 3 months ago

RLH-2110 commented 3 months ago

Crash report

What happened?

I am still learning python and then found out that this gives me a segmentation fault.

To reproduce, it should be enough to just run the python file. I commented what line leads to the segmentation fault.

I'm on an Ubuntu vm, used python 3.10, upgraded to 3.12 after I encountered the segfault. tkinter version is 8.6

I attached the python file and the core dump, as well as the error file thing that Ubuntu creates instead of core dumps I dont think I can be of much help with additional information, I know nothing.

import tkinter

root = tkinter.Tk()

# Create a Canvas widget inside a Frame to hold your scrollable content
canvas = tkinter.Canvas(root)
scrollbar = tkinter.Scrollbar(root, orient="vertical", command=canvas.yview)
rootS = tkinter.Frame(canvas)

rootS.bind(
    "<Configure>",
    lambda e: canvas.configure(
        scrollregion=canvas.bbox("all")
    )
)

canvas.create_window((0, 0), window=rootS, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)

# Pack the scrollbar and canvas
scrollbar.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)

def center_rootS(event):
    # Center the scrollable_frame within the canvas
    rootS.update_idletasks()
    canvas_width = canvas.winfo_width()
    canvas_height = canvas.winfo_height()
    scrollable_frame_width = rootS.winfo_reqwidth()
    scrollable_frame_height = rootS.winfo_reqheight()
    x_offset = (canvas_width - scrollable_frame_width) // 2
    y_offset = (canvas_height - scrollable_frame_height) // 2
    canvas.create_window((x_offset, y_offset), window=rootS, anchor="nw") # <---- this line creates a segfault

root.bind("<Configure>", center_rootS)
root.mainloop();

attachments.zip

CPython versions tested on:

3.10, 3.12

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.12.4 (main, Jul 18 2024, 13:27:24) [GCC 11.4.0]

serhiy-storchaka commented 3 months ago

I do not exactly know why it crashes. Perhaps due to stack overflow -- in this case we cannot help, only suggest to avoid deep recursion.

But I think that you should use the coords command instead of create window. You can use the Canvas.coords() method for this:

I hope it will help.

RLH-2110 commented 3 months ago

I do not exactly know why it crashes. Perhaps due to stack overflow -- in this case we cannot help, only suggest to avoid deep recursion.

But I think that you should use the coords command instead of create window. You can use the Canvas.coords() method for this:

* First, save the index of the canvas window:
  ```python
  rootS_index = canvas.create_window((0, 0), window=rootS, anchor="nw")
  ```

* Then change its coords instead of creating a new canvas window in `center_rootS()`:
  ```python
  canvas.coords(rootS_index, x_offset, y_offset)
  ```

I hope it will help.

Thank you!

I was just messing around not really quite knowing what it all does. Makes sence that it crashes because of recursion, I just did not expect that do throw a segfault, especially not in an interpreted language.

terryjreedy commented 3 months ago

We try reasonably hard to prevent crashes in the cpython binary, but tkinter +tkinter are our interface to the compiled C library that comes with the independent (of Python) tcl/tk distribution.