Skip to content

[GTK3] SIGSEGV in Text.copy (and similar methods) #2675

@jonahgraham

Description

@jonahgraham

Leaving owned data on the Clipboard after Display.dispose causes SIGSEGV in JVM if a new Display is created and new data is copied to the clipboard.

Here is a standalone example:

/*******************************************************************************
 * Copyright (c) 2025 Kichwa Coders Canada and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/

package org.eclipse.swt.tests.manual;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public final class DisposeDisplayWithClipboardContents {
	public static void main(String[] args) {
		copyWithClipboard();
		copyWithTextBox();
	}

	private static void copyWithClipboard() {
		final Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setLayout(new GridLayout(1, true));
		Button button = new Button(shell, SWT.PUSH);
		button.setText("Click me!");
		button.addListener(SWT.Selection, e -> {
			Clipboard clipboard = new Clipboard(display);
			clipboard.setContents(new Object[] { "Hello" }, new Transfer[] { TextTransfer.getInstance() });
			shell.close();
		});

		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

		// There is still owned data on the clipboard after dispose
		// is done (assuming no clipboard manager that has taken ownership
		// the data)
		// This leaves callbacks (specifically GTK3 ClipboardProxy.clearFunc)
		// disposed that can still be called by GTK
		display.dispose();
	}

	private static void copyWithTextBox() {
		final Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setLayout(new GridLayout(1, true));
		Text text = new Text(shell, SWT.SINGLE);
		text.setText("Hello!");
		Button button = new Button(shell, SWT.PUSH);
		button.setText("Click me!");
		button.addListener(SWT.Selection, e -> {
			text.setSelection(0, 5);
			// This calls ClipboardProxy.clearFunc to clear out the old selection in
			// the clipboard, since the Callback has been disposed, the Callback is
			// invalid and the JVM crashes
			text.copy();
		});

		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

		display.dispose();
	}
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions