Bug 250048 - DebugUIPlugin.start() pollutes SWT Display
Summary: DebugUIPlugin.start() pollutes SWT Display
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Debug (show other bugs)
Version: 3.3.2   Edit
Hardware: PC All
: P3 major (vote)
Target Milestone: 3.4.2   Edit
Assignee: Darin Wright CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-08 03:12 EDT by Hongchang Lin CLA
Modified: 2012-04-30 14:18 EDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hongchang Lin CLA 2008-10-08 03:12:02 EDT
In DebugUIPlugin.start(), Display.getDefault() is invoked. If the DebugUIPlugin is started in a worker thread and the first-time invocation of Display.getDefault() happens in DebugUIPlugin.start(), then the default Display is bind to a worker thread instead of main thread (the UI thread). This may brings vital exception if the started Eclipse Application invokes Display.getDefault() when handling UI in main thread. 

For example, in main thread, new a Clipboard(Display.getDefault()), it will have error because the default display's thread isn't the main thread. Usually, the root cause of this kind of error is very difficult to realize and identify.

I remember there is a regulation in Eclipse, it is not allow to handle UI in plugin.start() method. 

As a core plugin, by doing this, DebugUI really causes lots of trouble to the Eclipse application who is depends on DebugUI. Even worse, the developer has no knowledge about when the default display will be polluted and has no way to stop the pollution.

I already see some bugs opened on the "Invalid thread access" exception caused by DebugUIPlugin.start(). But I believe what I experienced with DebugUI is worse than that. I'll be appreciated if this issue can have owner's consideration.
Comment 1 Remy Suen CLA 2008-10-08 04:06:37 EDT
Perhaps getWorkbench().getDisplay() should be used instead?
Comment 2 Hongchang Lin CLA 2008-10-08 04:35:02 EDT
(In reply to comment #1)
> Perhaps getWorkbench().getDisplay() should be used instead?
> 

You're right! We use PlatformUi.getWorkbench().getDisplay() to replace all the Display.getDefault() to avoid the problem.

But I still think DebugUI does fault.

Comment 3 Remy Suen CLA 2008-10-08 04:44:50 EDT
(In reply to comment #2)
> (In reply to comment #1)
> > Perhaps getWorkbench().getDisplay() should be used instead?
> > 
> 
> You're right! We use PlatformUi.getWorkbench().getDisplay() to replace all the
> Display.getDefault() to avoid the problem.

Technically, I don't think PlatformUI.getWorkbench().getDisplay() should be used everywhere. I mean, if you have an SWT Widget instance handy, then you should just use widget.getDisplay() instead. Also, when I mentioned getWorkbench().getDisplay(), I meant calling that directly from the AbstractUIPlugin subclass (like DebugUIPlugin) since AbstractUIPlugin defines a getWorkbench() method. It's not really a huge difference but I just prefer not using static methods if there isn't a need to.

> But I still think DebugUI does fault.

Right, I was suggesting it to the Debug team and wasn't necessarily suggesting that your code was at fault actually. :)
Comment 4 Hongchang Lin CLA 2008-10-08 09:02:39 EDT
Sorry for my misunderstanding. I think your suggestion works. 
But I don't know when this issue can be taken into account.

Comment 5 Curtis Windatt CLA 2008-10-08 09:34:39 EDT
Reducing severity (it has been this way for a while) and priority (this is up to developers to determine).  Marking for investigation in 3.5.
Comment 6 Darin Wright CLA 2008-10-08 10:45:05 EDT
Modified debug's #getStandardDisplay() to return the workbench's display.
Comment 7 Darin Wright CLA 2008-10-08 10:45:28 EDT
Please verify, Curtis.
Comment 8 Samantha Chan CLA 2008-10-08 11:30:20 EDT
We have seen similar problems in our 3.4-based products.  The problems are very difficult to track and are quite serious in nature.  We think that the core plugins *must* do this correctly since many products rely on them.  We are requesting this to be fixed in 3.4.2.

Reopening this bug.
Comment 9 Darin Wright CLA 2008-10-08 11:44:09 EDT
Target for 3.4.2 as well.
Comment 10 Darin Wright CLA 2008-10-08 12:04:14 EDT
Released fix to 3.4.2 as well. Curtis, please veriry.
Comment 11 Curtis Windatt CLA 2008-10-17 16:00:49 EDT
Verified.
Comment 12 Wim Jongman CLA 2011-07-25 09:17:42 EDT
Activation of the debug.ui plugin still causes a Display.getDefault() to be called before the workbench is initialized. This causes a wrong initialization of the Display internal state.

See bug 352292
Comment 13 Wim Jongman CLA 2011-07-25 09:18:45 EDT
CORRECTION

see bug 352992
Comment 14 Remy Suen CLA 2011-07-25 09:25:59 EDT
(In reply to comment #12)
> Activation of the debug.ui plugin still causes a Display.getDefault() to be
> called before the workbench is initialized.

DebugUIPlugin's getStandardDisplay() was reimplemented to not call Display.getDefault().

Where is Display.getDefault() still a problem in the org.eclipse.debug.ui bundle?
Comment 15 Wim Jongman CLA 2011-07-25 09:49:36 EDT
(In reply to comment #14)
> Where is Display.getDefault() still a problem in the org.eclipse.debug.ui
> bundle?

Try a search for Display.getDefault in the debug.ui plugin. Many classes still use Display.getDefault().

I just debugged again. It might not be debug.ui but its initialization is causing it:

Daemon Thread [Start Level Event Dispatcher] (Suspended (entry into method getDefault in Display))	
	Display.getDefault() line: 1632	
	PreferenceConverter.<clinit>() line: 81	
	DebugUIPreferenceInitializer.setDefault(IPreferenceStore, String, RGB, boolean) line: 186	
	DebugUIPreferenceInitializer.setThemeBasedPreferences(IPreferenceStore, boolean) line: 204	
	DebugUIPreferenceInitializer.initializeDefaultPreferences() line: 79	
	PreferenceServiceRegistryHelper$1.run() line: 281	
	SafeRunner.run(ISafeRunnable) line: 42	
	PreferenceServiceRegistryHelper.runInitializer(IConfigurationElement) line: 284	
	PreferenceServiceRegistryHelper.applyRuntimeDefaults(String, WeakReference) line: 130	
	PreferencesService.applyRuntimeDefaults(String, WeakReference) line: 369	
	DefaultPreferences.applyRuntimeDefaults() line: 166	
	DefaultPreferences.load() line: 237	
	DefaultPreferences(EclipsePreferences).create(EclipsePreferences, String, Object) line: 307	
	DefaultPreferences(EclipsePreferences).internalNode(String, boolean, Object) line: 543	
	DefaultPreferences(EclipsePreferences).node(String) line: 669	
	DefaultScope(AbstractScope).getNode(String) line: 38	
	DefaultScope.getNode(String) line: 67	
	ScopedPreferenceStore.getDefaultPreferences() line: 250	
	ScopedPreferenceStore.getPreferenceNodes(boolean) line: 285	
	ScopedPreferenceStore.internalGet(String) line: 475	
	ScopedPreferenceStore.getString(String) line: 535	
	PerspectiveManager.initPerspectives() line: 990	
	PerspectiveManager.startup() line: 253	
	DebugUIPlugin.start(BundleContext) line: 501	
	BundleContextImpl$1.run() line: 783	
	AccessController.doPrivileged(PrivilegedExceptionAction<T>) line: not available [native method]	
	BundleContextImpl.startActivator(BundleActivator) line: 774	
	BundleContextImpl.start() line: 755	
	BundleHost.startWorker(int) line: 370	
	BundleHost(AbstractBundle).resume() line: 374	
	Framework.resumeBundle(AbstractBundle) line: 1067	
	StartLevelManager.resumeBundles(AbstractBundle[], boolean, int) line: 561	
	StartLevelManager.resumeBundles(AbstractBundle[], int) line: 546	
	StartLevelManager.incFWSL(int, AbstractBundle[]) line: 459	
	StartLevelManager.doSetStartLevel(int) line: 243	
	StartLevelManager.dispatchEvent(Object, Object, int, Object) line: 440	
	EventManager.dispatchEvent(Set, EventDispatcher, int, Object) line: 227	
	EventManager$EventThread.run() line: 337
Comment 16 Remy Suen CLA 2011-07-25 09:55:18 EDT
(In reply to comment #15)
> Try a search for Display.getDefault in the debug.ui plugin. Many classes still
> use Display.getDefault().
> 
> I just debugged again. It might not be debug.ui but its initialization is
> causing it:
> 
> Daemon Thread [Start Level Event Dispatcher] (Suspended (entry into method
> getDefault in Display))    
>     Display.getDefault() line: 1632    
>     PreferenceConverter.<clinit>() line: 81    
>     DebugUIPreferenceInitializer.setDefault(IPreferenceStore, String, RGB,
> boolean) line: 186    
>     DebugUIPreferenceInitializer.setThemeBasedPreferences(IPreferenceStore,
> boolean) line: 204    
>     DebugUIPreferenceInitializer.initializeDefaultPreferences() line: 79    
>     PreferenceServiceRegistryHelper$1.run() line: 281    
>     SafeRunner.run(ISafeRunnable) line: 42

These are separate problems. Please open new bugs for these issues. The problem that was originally reported has been corrected.

Also see bug 342711 for a related PreferenceConverter issue.
Comment 17 Wim Jongman CLA 2011-07-25 10:32:12 EDT
> These are separate problems. 

I don't see them as separated problems if I look at the original report of this bug. It is still the case that starting this plugin early causes the Display to be connected to the worker thread.

> Please open new bugs for these issues. The problem

that could become quite messy.
Comment 18 Alan Boxall CLA 2011-07-25 11:08:44 EDT
(In reply to comment #17)
> > These are separate problems. 
> 
> I don't see them as separated problems if I look at the original report of this
> bug. It is still the case that starting this plugin early causes the Display to
> be connected to the worker thread.
> 
> > Please open new bugs for these issues. The problem
> 
> that could become quite messy.

According to IWorkbench.getDisplay() "getDefault()" is not the recommended way to get the display.

I chased a similar problem a couple of years ago in a large Eclipse based product and it was the same problem.  An early start thread using getDefault and as a result becoming the UI thread.  If you need to use the display then one fix is to use the startup extension point which ensures that the workbench has started and created the proper display thread.

I agree with Wim's comment that all cases of getDefault() should be fixed.
if you don't want to use this defect then I suggest opening another titled - "Replace all Display.getDefault() references with IWorkbench.getDisplay() or similar call"
Comment 19 Michael Rennie CLA 2012-04-30 14:17:42 EDT
The debug part of the issue is fixed. If someone is eager enough to track down all instances of 'Display.getDefault()' they can do so in separate bugs.

Re-marking as fixed.
Comment 20 Michael Rennie CLA 2012-04-30 14:18:45 EDT
re-marking verified