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

[GTK3] Test Tree crash in SetData event #1611

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

basilevs
Copy link
Contributor

@basilevs basilevs commented Nov 22, 2024

The failure only happens in Ubuntu 24 (GTK 3.24.41)

This is a test for #678

The fix is in #1612.

Copy link
Contributor

github-actions bot commented Nov 22, 2024

Test Results

   483 files  ±0     483 suites  ±0   8m 30s ⏱️ - 4m 4s
 4 096 tests +1   4 086 ✅ +1   7 💤 ±0  3 ❌ ±0 
16 177 runs  +4  16 084 ✅ +4  90 💤 ±0  3 ❌ ±0 

For more details on these failures, see this check.

Results for commit f811bf7. ± Comparison against base commit e6588c2.

♻️ This comment has been updated with latest results.

@basilevs basilevs force-pushed the issue_678_renderer_crash branch 3 times, most recently from 2dc0189 to c54d5e7 Compare November 22, 2024 13:54
The failure only happens in Ubuntu 24 (GTK 3.24.41)
@basilevs basilevs force-pushed the issue_678_renderer_crash branch from c54d5e7 to f811bf7 Compare November 22, 2024 14:39
@basilevs
Copy link
Contributor Author

basilevs commented Nov 22, 2024

Test failures are caused by #1564

@basilevs basilevs marked this pull request as ready for review November 22, 2024 15:23
zkxvh added a commit to zkxvh/eclipse.platform.swt that referenced this pull request Dec 13, 2024
…latform#678

Fix and test for bug eclipse-platform#678

Fixes eclipse-platform#678

Reproducing the crash:
- eclipse-platform#678 (comment)
- eclipse-platform#1611
- eclipse-platform#678 (comment)

The cause of the crash is described here:
eclipse-platform#678 (comment)
In short, the problem was executing `Tree.createRenderers()` inside
`TreeItem.setImage()`.
The sequence of action leading to the crash was:
in a `Tree` with `SWT.VIRTUAL` a `TreeItem` is rendered for the first
time or after `clear()`
  `Tree.cellDataProc()` is executed for the item and one of it's
renderers
    `Tree.checkData(item)` is called for the item
      `SWT.SetData` is invoked and executes `TreeItem.setImage()`
         `Tree.createRenderers()` executes and disposes the current
renderer
    further actions in `Tree.cellDataProc()` that access the
already-disposed renderer (they think it's alive)

How it's fixed:
1. set fixed height+width to pixbuf renderers with
`GTK.gtk_cell_renderer_set_fixed_size`
   This does 2 things:
     - from now on it makes images rendered by the renderer to be
rendered with these height+width
     - from now on fixed row height calculation will return height of at
least fixed height of the pixbuf
2. make `GtkTreeView` recompute it's internally stored fixed row height
with re-setting `fixed_height_mode` of the GtkTreeView
3. make all existing tree rows update their height by invoking
`gtk_tree_view_row_changed()` on each of the rows.

(2) and (3) can also be achieved by creating a copy of the current
`GtkTreeModel` and assigning it to the `GtkTreeView`.
But this also resets current selected rows, focus and scroll position;
that's why I chose re-setting `fixed_height_mode` +
`gtk_tree_view_row_changed()` instead.
zkxvh added a commit to zkxvh/eclipse.platform.swt that referenced this pull request Dec 13, 2024
…latform#678

Fix and test for bug eclipse-platform#678

Fixes eclipse-platform#678

Reproducing the crash:
- eclipse-platform#678 (comment)
- eclipse-platform#1611
- eclipse-platform#678 (comment)

The cause of the crash is described here:
eclipse-platform#678 (comment)
In short, the problem was executing `Tree.createRenderers()` inside
`TreeItem.setImage()`.
The sequence of action leading to the crash was:
in a `Tree` with `SWT.VIRTUAL` a `TreeItem` is rendered for the first
time or after `clear()`
  `Tree.cellDataProc()` is executed for the item and one of it's
renderers
    `Tree.checkData(item)` is called for the item
      `SWT.SetData` is invoked and executes `TreeItem.setImage()`
         `Tree.createRenderers()` executes and disposes the current
renderer
    further actions in `Tree.cellDataProc()` that access the
already-disposed renderer (they think it's alive)

How it's fixed:
1. set fixed height+width to pixbuf renderers with
`GTK.gtk_cell_renderer_set_fixed_size`
   This does 2 things:
     - from now on it makes images rendered by the renderer to be
rendered with these height+width
     - from now on fixed row height calculation will return height of at
least fixed height of the pixbuf
2. make `GtkTreeView` recompute it's internally stored fixed row height
with re-setting `fixed_height_mode` of the GtkTreeView
3. make all existing tree rows update their height by invoking
`gtk_tree_view_row_changed()` on each of the rows.

(2) and (3) can also be achieved by creating a copy of the current
`GtkTreeModel` and assigning it to the `GtkTreeView`.
But this also resets current selected rows, focus and scroll position;
that's why I chose re-setting `fixed_height_mode` +
`gtk_tree_view_row_changed()` instead.
zkxvh added a commit to zkxvh/eclipse.platform.swt that referenced this pull request Jan 9, 2025
Fix for `SIGSEGV` in `Tree.cellDataProc(...)` when calling
`TreeItem.setImage(...)`.

Fixes eclipse-platform#678

Reproducing the crash:
- eclipse-platform#678 (comment)
- eclipse-platform#1611
- eclipse-platform#678 (comment)

The cause of the crash is described here:
eclipse-platform#678 (comment)
In short, the crash happens due to read accesses to an already disposed
renderer.
The sequence of action leading to the crash was:
- in a `Tree` with `SWT.VIRTUAL` a `TreeItem` is rendered for the first
time or after `clear()`
  - `Tree.cellDataProc()` is executed for the item and one of the
renderers
    - `Tree.checkData(item)` is called for the item
      - `SWT.SetData` event is created and sent for the item
        - `TreeItem.setImage() is executed by the event handler for
`SWT.SetData``
         - `Tree.createRenderers()` executes and disposes the current
renderer
    - further actions in `Tree.cellDataProc()` that access the
already-disposed renderer (they think it's alive)

How it's fixed: in `Tree.cellDataProc()` wrap `Tree.checkData(item)`
into `Display.asyncExec()`.

Why fixed this way:
1. on one hand, `Tree.cellDataProc()` is a [cell data
function](https://docs.gtk.org/gtk3/treeview-tutorial.html#cell-data-functions)
which is not supposed to change tree structure. Violation of this leads
to C memory errors.
2. On the other hand, `SWT.SetData` event handlers are written by swt
users and therefore can contain any code.

Using `Display.asyncExec()` to postpone `SWT.SetData` event handlers
until `Tree.cellDataProc()` is finished seems like the most simple and
bullet-proof solution to eclipse-platform#678 and all similar bugs.
@zkxvh zkxvh mentioned this pull request Jan 9, 2025
zkxvh added a commit to zkxvh/eclipse.platform.swt that referenced this pull request Jan 10, 2025
Fix for `SIGSEGV` in `Tree.cellDataProc(...)` when calling
`TreeItem.setImage(...)`.

Fixes eclipse-platform#678

Reproducing the crash:
- eclipse-platform#678 (comment)
- eclipse-platform#1611
- eclipse-platform#678 (comment)

The cause of the crash is described here:
eclipse-platform#678 (comment)
In short, the crash happens due to read accesses to an already disposed
renderer.
The sequence of action leading to the crash was:
- in a `Tree` with `SWT.VIRTUAL` a `TreeItem` is rendered for the first
time or after `clear()`
  - `Tree.cellDataProc()` is executed for the item and one of the
renderers
    - `Tree.checkData(item)` is called for the item
      - `SWT.SetData` event is created and sent for the item
        - `TreeItem.setImage() is executed by the event handler for
`SWT.SetData``
         - `Tree.createRenderers()` executes and disposes the current
renderer
    - further actions in `Tree.cellDataProc()` that access the
already-disposed renderer (they think it's alive)

How it's fixed: in `Tree.cellDataProc()` wrap `Tree.checkData(item)`
into `Display.asyncExec()`.

Why fixed this way:
1. on one hand, `Tree.cellDataProc()` is a [cell data
function](https://docs.gtk.org/gtk3/treeview-tutorial.html#cell-data-functions)
which is not supposed to change tree structure. Violation of this leads
to C memory errors.
2. On the other hand, `SWT.SetData` event handlers are written by swt
users and therefore can contain any code.

Using `Display.asyncExec()` to postpone `SWT.SetData` event handlers
until `Tree.cellDataProc()` is finished seems like the most simple and
bullet-proof solution to eclipse-platform#678 and all similar bugs.
zkxvh added a commit to zkxvh/eclipse.platform.swt that referenced this pull request Jan 10, 2025
Fix for `SIGSEGV` in `Tree.cellDataProc(...)` when calling
`TreeItem.setImage(...)`.

Fixes eclipse-platform#678

Reproducing the crash:
- eclipse-platform#678 (comment)
- eclipse-platform#1611
- eclipse-platform#678 (comment)

The cause of the crash is described here:
eclipse-platform#678 (comment)
In short, the crash happens due to read accesses to an already disposed
renderer.
The sequence of action leading to the crash was:
- in a `Tree` with `SWT.VIRTUAL` a `TreeItem` is rendered for the first
time or after `clear()`
  - `Tree.cellDataProc()` is executed for the item and one of the
renderers
    - `Tree.checkData(item)` is called for the item
      - `SWT.SetData` event is created and sent for the item
        - `TreeItem.setImage() is executed by the event handler for
`SWT.SetData``
         - `Tree.createRenderers()` executes and disposes the current
renderer
    - further actions in `Tree.cellDataProc()` that access the
already-disposed renderer (they think it's alive)

How it's fixed: in `Tree.cellDataProc()` wrap `Tree.checkData(item)`
into `Display.asyncExec()`.

Why fixed this way:
1. on one hand, `Tree.cellDataProc()` is a [cell data
function](https://docs.gtk.org/gtk3/treeview-tutorial.html#cell-data-functions)
which is not supposed to change tree structure. Violation of this leads
to C memory errors.
2. On the other hand, `SWT.SetData` event handlers are written by swt
users and therefore can contain any code.

Using `Display.asyncExec()` to postpone `SWT.SetData` event handlers
until `Tree.cellDataProc()` is finished seems like the most simple and
bullet-proof solution to eclipse-platform#678 and all similar bugs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant