Mac OS X application crashes, but only for one user. Why?
April 14, 2015 11:31 AM Subscribe
Fairly gnarly Mac debugging / troubleshooting question, concerning an app that crashes on launch consistently, but only when run by a single particular user. So far, it's stumped everyone. Lots of gory technical details inside.
I have a Mac OS X application (Garmin's "VIRB Edit", which lets you download videos from the VIRB series of GoPro-ish cameras) that has turned into a slightly obsessive technical challenge. The problem is that it crashes immediately after launch, with absolute consistency, but only when run from a particular user's account, but not when run from a Guest account or from another user. So, obviously, the problem is related to that user's account/environment. But how to figure out what's doing it?
When launched by the "bad" user, the application immediately quits with this crashlog output. The error that's causing the crash is setObjectForKey: object cannot be nil (key: LibraryPath)'
terminating with uncaught exception of type NSException, and it's related to this part of the stack trace:
Things I have tried:
Any Mac gurus want to weigh in?
I have a Mac OS X application (Garmin's "VIRB Edit", which lets you download videos from the VIRB series of GoPro-ish cameras) that has turned into a slightly obsessive technical challenge. The problem is that it crashes immediately after launch, with absolute consistency, but only when run from a particular user's account, but not when run from a Guest account or from another user. So, obviously, the problem is related to that user's account/environment. But how to figure out what's doing it?
When launched by the "bad" user, the application immediately quits with this crashlog output. The error that's causing the crash is setObjectForKey: object cannot be nil (key: LibraryPath)'
terminating with uncaught exception of type NSException, and it's related to this part of the stack trace:
8 libobjc.A.dylib 0x00007fff94225fa1 objc_exception_throw + 343 9 com.apple.CoreFoundation 0x00007fff8a14a22e -[__NSDictionaryM setObject:forKey:] + 1102 10 com.garmin.VIRBEdit 0x000000010546b5a7 +[PreferencesViewController initDefaults] + 212 11 com.garmin.VIRBEdit 0x000000010539b745 -[AppDelegate init] + 124 12 com.apple.AppKit 0x00007fff8841f6f4 -[NSCustomObject nibInstantiate] + 368 13 com.apple.AppKit 0x00007fff8841f520 -[NSIBObjectData instantiateObject:] + 309 14 com.apple.AppKit 0x00007fff8841e815 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 413 15 com.apple.AppKit 0x00007fff884135ce loadNib + 327 16 com.apple.AppKit 0x00007fff88412b6c +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 288 17 com.apple.AppKit 0x00007fff8841295c -[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:] + 197 18 com.apple.AppKit 0x00007fff8841274b +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 357 19 com.apple.AppKit 0x00007fff8840e597 NSApplicationMain + 448 20 com.garmin.VIRBEdit 0x00000001053a8d90 main + 95 21 libdyld.dylib 0x00007fff91a115fd start + 1My interpretation of this is that it's trying to load something from a NIB, possibly from a shared framework, and it's choking. But I'm open to other thoughts on what it might mean. When run from a Guest account or a different user's account, it launches just fine with no suggestion as to what might be going wrong. In fairness, I do have a lot of stuff installed (XCode and CLI tools, MacPorts, Homebrew, LaTeX, various releases of Python, etc.) but they are all installed for all users, not to the affected user's homedir.
Things I have tried:
- Repair permissions - Just for starters, I ran Disk Utility's "Repair Permissions" a few times on the boot disk. It fixed a couple of things, but didn't appear to make a difference.
- Environment variables - On the theory that there's something going on with the "bad" user's $PATH, I copied/chowned .profile, .bash_profile, and .bashrc to the "good" user account, such that printenv shows the same variables set in each user's environment... and I get the same results. Program launches fine for one user, crashes for the other. So it doesn't seem to just be an environment var that's set on one side but not on the other. (Yeah, I really liked that theory, too.) N.B. I also moved/chowned ~/bin over, so they had access to the same stuff in the path, in addition to having the same $PATH set.
- User-specific Framework - Neither user has a ~/Library/Frameworks folder in their homedir, which would be the obvious place for a user-specific framework to be hiding. Though Apple's way of loading Frameworks seems rather complex, so maybe there is something else that can be eliminated?
- Preferences garbage - I tried copying (and chowning) the ~/Library/Application Support/Preferences folder from the "bad" account to the "good" account, thinking that perhaps there were some preferences causing the crash. Same result; after a logout/login on the "good" account side, the app still runs.
- Application Support garbage - Lacking other intelligent avenues, I tried copying the entire ~/Library/Application Support folder from the "bad" to "good" account, to see if that did anything. No dice.
- Run as another user with su - Here's where things get interesting. If, while logged in to OS X as the "bad" user, I open a shell and do either su - gooduser or su -m gooduser and then invoke the actual executable from the su'd shell, it launches cleanly in both situations. Since the difference between su - and su -m is whether it resets the environment, this seems to be further confirmation that it's not an environment/path issue. But—and here it gets weird—if I tell su to invoke the open command, then it crashes.
- Crash: su -m gooduser -c 'open /Applications/Garmin\ VIRB\ Edit.app'
- No Crash: su -m gooduser -c '/Applications/Garmin\ VIRB\ Edit.app/Contents/MacOS/Garmin\ Virb\ Edit'
Any Mac gurus want to weigh in?
What happens if you login as gooduser and su to baduser to run the app?
posted by primethyme at 11:37 AM on April 14, 2015
posted by primethyme at 11:37 AM on April 14, 2015
Is there something funky (spaces somehow, special characters, etc...) about gooduser's actual username that isn't shared by other users?
posted by zachlipton at 11:41 AM on April 14, 2015 [1 favorite]
posted by zachlipton at 11:41 AM on April 14, 2015 [1 favorite]
Without having access to the source code, initDefaults is probably crashing on a bad NSUserDefaults dictionary, which is set per-user. Try deleting the defaults domain for the app and trying again:
- Open Terminal and run "defaults read | grep garmin". It should find a dictionary, something like this:
"com.garmin.xxxxx = {
- Run "defaults delete com.garmin.xxxxx" replacing the string with whatever the actual match was.
posted by perihare at 11:50 AM on April 14, 2015 [1 favorite]
- Open Terminal and run "defaults read | grep garmin". It should find a dictionary, something like this:
"com.garmin.xxxxx = {
- Run "defaults delete com.garmin.xxxxx" replacing the string with whatever the actual match was.
posted by perihare at 11:50 AM on April 14, 2015 [1 favorite]
Best answer: While I don't have the source code obviously, I do have a disassembler and a conference call less interesting than disassembling a random app.
I need to wrap my head around this a little more, but in the meantime, make sure the user has a Movies folder in his home directory (it's there by default). Did he delete it somehow?
posted by zachlipton at 12:11 PM on April 14, 2015 [2 favorites]
I need to wrap my head around this a little more, but in the meantime, make sure the user has a Movies folder in his home directory (it's there by default). Did he delete it somehow?
posted by zachlipton at 12:11 PM on April 14, 2015 [2 favorites]
Response by poster: You may want to check preferences inside the .app
Good thought. I ran sudo chmod -R a+rX on the application bundle; didn't seem to do anything. Everything seems to be rwxr-xr-x by root/admin.
What happens if you login as gooduser and su to baduser to run the app?
You get the 'reverse' behavior. Both su - baduser and su -m baduser, followed by trying to execute the binary inside the application bundle directly, cause a crash (it's the same setObjectForKey error that it always is). But if you run open /Applications/Garmin\ VIRB\ Edit.app/Contents/MacOS/Garmin\ VIRB\ Edit then it opens fine.
Is there something funky (spaces somehow, special characters, etc...) about gooduser's actual username
Nope. The "baduser" is all lowercase, same length as the "gooduser", and they're UIDs 501 and 504 respectively. Can't find anything notably different about them.
Working on the defaults thing at the moment. (There are a bunch of defaults for "Garmin" that I'm trying to sort through; I do have some other legitimate Garmin software installed so I don't want to nuke it all accidentally.)
posted by Kadin2048 at 12:17 PM on April 14, 2015
Good thought. I ran sudo chmod -R a+rX on the application bundle; didn't seem to do anything. Everything seems to be rwxr-xr-x by root/admin.
What happens if you login as gooduser and su to baduser to run the app?
You get the 'reverse' behavior. Both su - baduser and su -m baduser, followed by trying to execute the binary inside the application bundle directly, cause a crash (it's the same setObjectForKey error that it always is). But if you run open /Applications/Garmin\ VIRB\ Edit.app/Contents/MacOS/Garmin\ VIRB\ Edit then it opens fine.
Is there something funky (spaces somehow, special characters, etc...) about gooduser's actual username
Nope. The "baduser" is all lowercase, same length as the "gooduser", and they're UIDs 501 and 504 respectively. Can't find anything notably different about them.
Working on the defaults thing at the moment. (There are a bunch of defaults for "Garmin" that I'm trying to sort through; I do have some other legitimate Garmin software installed so I don't want to nuke it all accidentally.)
posted by Kadin2048 at 12:17 PM on April 14, 2015
I'd try what perihare suggests, or simply trashing (or moving/renaming) any likely looking preferences files in ~/Library/Application Support/Preferences and allowing the application to recreate them. The application is crashing when it tries to set up the preferences view, so it's presumably something in there.
I'm unfamiliar with this particular application, but since it sounds like it's intended to interface with a plugged in GoPro it may be reading configuration or preferences files associated with the device, not just the actual application. You may want to see if you can track down anything that looks like that within the user's account, and move or delete it as well.
posted by figurant at 12:19 PM on April 14, 2015
I'm unfamiliar with this particular application, but since it sounds like it's intended to interface with a plugged in GoPro it may be reading configuration or preferences files associated with the device, not just the actual application. You may want to see if you can track down anything that looks like that within the user's account, and move or delete it as well.
posted by figurant at 12:19 PM on April 14, 2015
Best answer: The app is trying to find and/or create a directory at ~/Movies/Garmin (/Users/baduser/Movies/Garmin). Does that path exist? Are there strange permissions issues preventing baduser from accessing that path?
posted by zachlipton at 12:26 PM on April 14, 2015 [1 favorite]
posted by zachlipton at 12:26 PM on April 14, 2015 [1 favorite]
Response by poster: in the meantime, make sure the user has a Movies folder in his home directory
Holy crap, that was it.
The "baduser" account doesn't have a "~/Movies" folder and never has (media lives elsewhere, on a NAS), but the newly-created "gooduser" did. And apparently the program chokes if that folder doesn't exist, because its default storage location for imported files is ~/Movies/Garmin.
I don't even... but it seems to be running now.
Nice work, zachlipton!
And no points to Garmin, because that is ridiculous behavior.
posted by Kadin2048 at 12:27 PM on April 14, 2015
Holy crap, that was it.
The "baduser" account doesn't have a "~/Movies" folder and never has (media lives elsewhere, on a NAS), but the newly-created "gooduser" did. And apparently the program chokes if that folder doesn't exist, because its default storage location for imported files is ~/Movies/Garmin.
I don't even... but it seems to be running now.
Nice work, zachlipton!
And no points to Garmin, because that is ridiculous behavior.
posted by Kadin2048 at 12:27 PM on April 14, 2015
Try rebooting within the recovery partition. Open terminal and run resetpassword. On that screen is a button to reset the user permissions. (Disk Utility only fixes Apple's System folder)
posted by Gungho at 12:28 PM on April 14, 2015 [1 favorite]
posted by Gungho at 12:28 PM on April 14, 2015 [1 favorite]
And no points to Garmin, because that is ridiculous behavior.
posted by Kadin2048 at 3:27 PM on April 14 [+] [!]
Microsoft Office will do the same shit if moved from where it wants to be. But then again that is to be expected of Microsoft.
posted by Gungho at 12:29 PM on April 14, 2015 [1 favorite]
posted by Kadin2048 at 3:27 PM on April 14 [+] [!]
Microsoft Office will do the same shit if moved from where it wants to be. But then again that is to be expected of Microsoft.
posted by Gungho at 12:29 PM on April 14, 2015 [1 favorite]
Would a symlink work to allow that user to continue to keep the media files and Garmin imports on the NAS?
posted by infinitewindow at 1:01 PM on April 14, 2015
posted by infinitewindow at 1:01 PM on April 14, 2015
Response by poster: Well you don't actually need to store the files in the ~/Movies/Garmin folder. As soon as you run the program, you can go into its Preferences and specify whatever folder you want to keep your downloaded clips in. (Which are huge, so if you have an SSD or something, you probably want them on a different disk. Not exactly an uncommon configuration.)
The program won't actually even write anything there, if you point it at some other storage location before you start importing video.
But... if you don't have that ~/Movies folder in your homedir, at least on first run (not sure yet what happens if you delete it after you've set the preferences to a different location) it throws an exception.
posted by Kadin2048 at 2:09 PM on April 14, 2015
The program won't actually even write anything there, if you point it at some other storage location before you start importing video.
But... if you don't have that ~/Movies folder in your homedir, at least on first run (not sure yet what happens if you delete it after you've set the preferences to a different location) it throws an exception.
posted by Kadin2048 at 2:09 PM on April 14, 2015
« Older Cosigners on foreign bank accounts: how do you... | How to record sounds inside the body? Newer »
This thread is closed to new comments.
That and the other solution, which admittedly is a little more drastic. Preserve the user's documents, delete the user, create a new user, transfer the documents back...
posted by signsofrain at 11:34 AM on April 14, 2015