However, there hasn't been an easy way to detect these problems in your applications without manually auditing the code or waiting until an error occurs. Until now. The command-line tool threadedui, works on OS X to check your applications to see if they access the user interface from a thread.
Download: threadedui.
To use threadedui, run it from Terminal supplying it with the path to your application. Like this:
# sudo ./threadedui /Applications/MyApp.app
This launches your application. Use it as you normally would. As it runs, information will appear in the Terminal window. Quit your application when you are finished.
If your application does not have any threaded UI access, then the output in Terminal looks something like this:
Launched /MyApp.app/Contents/MacOS/MyApp (24126)
DTrace attached to 24127
Main thread found, trace starting (may have missed some events)
Program exited, detected no UI operations from a thread
If your application does have threaded UI access, then significantly more information is displayed. This code has a Thread on a Window that directly updates a ProgressBar using this code in its Run event handler:
ProgressBar1.Value = 100
When run using threadedui, this is what the output looks like:
Launched /MyApp.app/Contents/MacOS/MyApp (24210)
DTrace attached to 24211
Main thread found, trace starting (may have missed some events)
MyApp`REALbasic._UITrap
MyApp`ProgressBar.Value.Set%%o<ProgressBar>i4i4+0x2c
MyApp`Window1.Window1.Thread1_Run%%o<Window1.Window1>o<Thread>+0x97
MyApp`Delegate.IM_Invoke%%o<Thread>+0x6e
MyApp`AddHandler.Stub.0%%+0x33
rbframework.dylib`0x001f48a0+0xc0
CarbonCore`CooperativeThread+0x134
libsystem_c.dylib`_pthread_start+0x14f
libsystem_c.dylib`thread_start+0x22
Program exited, detected 1 UI operations from a thread
As you can see, the output tells you that the Thread1 Run event is accessing the UI and it specifically mentions ProgressBar.Value. Once the problem areas of you application have been identified in this manner, you can go about updating them.
10 comments:
Great tool, very useful.
I've used dtrace for other complicated debugging tasks before. Takes some practise but can do astonishing things.
Excellent, thank you
Wow ... found one ! And I was sure that I had already adjusted everything in the right way ...
Thanks a lot!
Hmm.... In Cocoa accessing the UI from a thread simply causes a crash. So very obvious as not too miss. Will try out your tool....
We should not update UI from thread. Is this true for main thread also? or only for threads except the main thread?
User interface elements should only be manipulated from the main thread. Usage from a non-main thread will result in undefined behavior.
Sorry, where do I install threaded in OS X?
Jon
It doesn't have to be installed anywhere -- you can just run it from wherever it was downloaded to.
I've entered this in Terminal, and get a command not found error:
# sudo ./threadedui/MyAppFolder\ Development\ Folder/Myapp.app
You're missing a space between ./threadedui and the application path.
Post a Comment