Bonus bugs with GDB

September 2nd, 2005

I guess the last bug report got me in the mood, and since it’s 11:55 here in Somerville, I have time to write up a quickie that I just noticed again, while investigating the other bug I reported tonight!

This is an obscure bug, but part of my reason for sharing it in a post is that some of you may not be familiar with the particular feature of gdb where this bug rears its head. The feature I speak of is the “info sharedlibrary” extension Apple was kind enough to add several releases ago, which allows the debugger (that’s you!) to easily match up an address in code memory with the shared library from which it was loaded. I thought some of you might not know about it, and the next time you’re digging around through somebody else’s code, you might find it handy.

In the old days (haha! old, meaning like, 2001), if we ran across a mystery chunk of code in gdb, we had to do a plain “info shared” and then scan through the list of libraries, forcing our brains into hex overdrive as we tried to match the address with the ranges of addresses attributed to the bazillion libraries that had inevitably been loaded into the process.

In the new days (haha! new, meaning like, 2003), Apple added the obvious argument to this utility, which allows you to specify the particular address your interested in, and have gdb handle the hard searching for you:

(gdb) info shared 0x52240
  1 Finder                     - 0x1000            exec Y Y /System/Library/

Sweet! Love that taking away the pain functionality. The only problem is, when a nice new feature comes along, you expect it to do everything wonderfully and perfectly. In the case of “info shared”, a major drawback has plagued it since its inception. Sure, it lets you find the associated shared library for an address, but it fails to extend this concept in the most freaking obvious way imaginable. It doesn’t accept variable arguments! If I’m stopped in gdb, and I want to know where I’m at, my feeble little brain still expects “info shared” to do the right thing, so I inevitably do something like the following:

(gdb) info shared $pc
[unknown]
(gdb) ugh!
Undefined command: "ugh".  Try "help".
(gdb) p $pc
$6 = 336448
(gdb) info shared 336448
  1 Finder                     - 0x1000            exec Y Y /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder (offset 0x0)
(gdb)

That’s no way to live! It’s time that this wonderful little helper got with the program. Any reasonable expression that evaluates to “a number” and can be passed to any other command in gdb should also be accepted by this little gem. Radar #4243991.

Bug Report Friday

September 2nd, 2005

When I first read Dan Wood’s plan for Report-An-Apple-Bug Friday, I was amused but a little disgruntled by the idea. Turns out this once long-term Apple employee has a bit more loyalty than he thought he did. Or is it just empathy? The part that turned me off was the idea that everybody should cooperate in a “mass report” of the same issue. I suppose if it’s everybody’s pet peeve, that’s fine, but I almost got the feeling that the idea was to promote some kind of bug reporting solidarity regardless of personal investment in the issue.

Although a bug with lots of “marked as duplicate” tags on it may in fact get a bit more attention than it would otherwise, it was always my impression while inside that a more significant fast-trick to fixing was how the issue ranked on the Apple Support telephone logs. Think about it. It takes a mere 30 seconds to review a bug and mark it as a duplicate. The way most groups screen bugs, there is a dedicated group member who probably has all the common bug numbers bookmarked or memorized by now. When somebody calls in to discuss a problem, it costs toll-free telephone time, and probably at a minimum 5 minutes of a telephone operator’s time. While the operator probably makes less than the bug screener, they would have to make 10 times less for the cost of just the wasted salary to match the cost of marking a bug as a duplicate.

Perhaps if this movement really is meant to be a guerrilla campaign to control Apple’s bug fixing priorities from the outside, it should be dubbed “call 1-800-SOS-APPL Friday” instead.

Nonetheless, I like the reminder to get those pesky peeves out of my head and into the system. Don’t get me wrong, I’m an avid bug reporter as-is, but I do go through slumps where I just feel too lazy to navigate the sometimes obnoxious HTML-based bug reporter Apple provides.

Today I will participate for the first time in reporting a bug that directly affects the behavior of my application, FastScripts. I am also taking Mike Zornek’s suggestion of tagging this entry with the keyword “applebugfriday.” If that causes some new readers to come on board, then “hello, and welcome!”

The bug I’m reporting is a smaller part of a larger issue which has to do with the “rights of cursor ownership.” I already have an outstanding bug report from 2003 (#3260283) which addresses the bigger issue: Apple’s unfair practice of allowing the front-most application to change the cursor even if the user’s mouse is hovering over a floating UI that doesn’t belong to that application.

Until that bug is fixed we’re left with a scenario where a certain amount of courtesy is called for when it comes to manipulating the cursor. Most applications are well-behaved in this regard, but some are ridiculously rude. PowerPlant is especially villainous in this regard. All PowerPlant apps that I’ve encountered have a habit of constantly resetting the cursor back to a plain arrow. This means that if any UI floating over the app attempts to change the cursor, it is instantaneously switched back to an arrow by the offending app. A terrible UI results for all parties involved. The floating UI doesn’t get its point across. The user gets frustrated by the flickering cursor, and the application author gets embarrassed (I wish!) by its rude over-involvement with all things cursor.

For the most part Apple’s own applications are better behaved. One glaring exception is unfortunately the one Apple application that is always running: the Finder! And that is the target of my bug, today. Thankfully, the Finder doesn’t behave quite as badly as most PowerPlant applications (though it may have at one time when it was more heavily based on that framework). What the Finder does though, is listen for changes in the state of the modifier keys (shift, ctrl, etc.), and uses that opportunity to reset the cursor to whatever it feels is correct (always an arrow in my tests). This overrides any UI that might be presented in front of it, and any custom cursor which might help the user better understand the software that they are piloting. In FastScripts, I allow the user to perform certain shortcuts by selecting menu items with certain of these modifier keys held down. For instance, to easily change the keyboard shortcut of a script, the user can select it while holding down the command key. To aid the user’s understanding that a special action will occur, I change the cursor when the key is held down. The Finder, and other rude applications, are the bane of my application’s elegant user experience.

It’s not just FastScripts that is affected by this. A great example is shipped by Apple and used by (presumably) hundreds of thousands of people per day: the Dashboard. With the Finder as the frontmost application, activate the Dashboard. Now, move your mouse to any widget which has good reason to modify the cursor. For example, select the text entry field of the Translation widget. Notice the familiar “I-Beam” cursor appears, as we would expect. Now, simply press the shift key, or control key, or caps lock. Whatever. You’ve lost your I-Beam. Worse, to get it back you’ll have to coerce the widget into resetting it by activating another widget and then switching back. It has no way of knowing it needs to reset the I-Beam – it already set it once and it knows it doesn’t need to set it again! At least, in a predictable world it wouldn’t need to.

Ideally Apple would fix the root problem, and disallow the front application from willy-nilly changing the cursor when the mouse is positioned over a window that it doesn’t own. Failing that, Apple’s own products should showcase a more respectful attitude towards cursor rights. If another application is displaying meaningful UI above the Finder, then the Finder should stop hogging the cursor! Radar #4243655.

Rock the Funky Finder Regex

August 24th, 2005

I’m on a bit of a productivity kick lately. I’m trying to listen to the little voice in my head that speaks up when I’m doing something incredibly tedious and error-prone, and could clearly be automated.

Some people would say that spending 3 hours cranking out a script that might save you at most a minute or two each time you use it is the opposite of productivity, but I beg to differ. Yes, it may take a while to fully earn back the time I spend on such modest life improvements, but the little changes often clear the way for bigger changes down the road.

How many of you have ever stared at a folder in the Finder, teeming with files of varying types and names, and wished you could easily select by regular expression? Well, your reward for reading this blog is that as of today, you can!

I was inspired by a project of mine whose directory hierarchy was “out of control.” Since the project started out small, I had colocated all of the source files, images, documentation, reference materials, etc., in one directory. Now I’m looking at it and thinking, “gosh, I’d like to at least put all the source files in a sub-folder, but it’s drag to select every ‘.m’ and ‘.h’ file by hand.”

At first I tried to accomplish the task in AppleScript alone. Among the many things missing from AppleScript is a built-in regular expression engine, so I knew I’d have to either install a scripting component, or resort to Mac OS X’s built-in command line tools. My script started out as an AppleScript that merely called out to perl (via “do shell script”) to handle the regular expression parsing:

This worked great, but as expected, those repeated “do shell script” calls dogged performance big time. The point of this is to automate a task so that it happens in the blink of an eye. If I have to wait for a long pause, then I’ve just replaced one frustration with another!

How to avoid the delay of the repeated “do shell script” commands? I thought about spitting out the names of the files to a temporary file, and running perl just once against that file. Yeah – complicated and I don’t like to use temporary files when it’s possible to avoid them.

I decided it was time to approach the problem from the other angle. There’s no reason I can’t write the script in Perl and just call out to AppleScript as necessary to interface with the Finder. An added benefit is that I can easily use the Perl script from the command line or a script menu. I set the script up as a FastScripts Finder-specific script, and applied the keystroke “Cmd-Opt-S” as a shortcut. Now when I’m looking at a window like this:

I just hit Cmd-Opt-S to bring up this dialog, enter a regular expression:

And end up with this!

Can’t wait to get your hands on this? Feel free to download a copy of “Select Regular Expression” from the Red Sweater scripts page. Enjoy!

Update: Version 1.0.1 of the script saves and restores the regular expression you enter, so the dialog is always pre-populated with the last string you tried.

FastScripts 2.2.5

August 23rd, 2005

FastScripts 2.2.5 has been released and is available for download.

This update fixes a few minor bugs and adds a significant new feature: custom menu sorting. FastScripts now recognizes scripts and folders named with the “BBEdit style” organization convention, and will sort them appropriately in the FastScripts menu. For those of you unfamiliar with this convention, the gist is that if you prefix a script or folder’s name with two characters and a right-parenthesis, those characters will be stripped from the visible name of the item, but still used for sort-ordering. FastScripts also respects the folder naming suffix of “-***”, meaning “add a menu separator item.”

For example, a directory containing the following items:

is displayed in a submenu with the following appearance:

People have been asking for this feature for a long time, but it required a surprising amount of redesign, since so much of the app assumed there would always be a straight alphabetical ordering of things.