Skip to content

Commit

Permalink
integrate a crash reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
henderea committed Sep 9, 2014
1 parent dc3003d commit 6f433aa
Show file tree
Hide file tree
Showing 33 changed files with 1,830 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ source 'https://rubygems.org'

gem 'rake'
# Add your dependencies here:
gem 'everyday-menu', '>= 1.3.5'
gem 'everyday-menu', '~> 1.3', '>= 1.3.5'
gem 'ib', '~> 0.6'
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ PLATFORMS
ruby

DEPENDENCIES
everyday-menu (>= 1.3.5)
everyday-menu (~> 1.3, >= 1.3.5)
ib (~> 0.6)
rake
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ A RubyMotion application for keeping memory usage in check. Shows up in the men
* As part of the preferences update, you can now turn off all notifications or individual ones. Note that if you have the notification system set to "None", the individual notification checkboxes will be ignored.
* When upgrading from a pre-1.0 version, the "update while freeing" option will be turned off the first time you launch 1.0. This is because the suddenly decreasing free memory amount may cause confusion. You can turn this option back on if desired.
* Thanks to all of the beta testers that helped me get this version working well.
* **v1.0.1:** integrate a crash reporter

###Versions (code-signed with developer ID):
* **v0.3:** <http://memorytamer.s3.amazonaws.com/MemoryTamer-0.3.zip> (Mavericks-only)
Expand Down Expand Up @@ -78,3 +79,4 @@ A RubyMotion application for keeping memory usage in check. Shows up in the men
* **v0.9.6:** <https://memorytamer.s3.amazonaws.com/MemoryTamer-0.9.6.zip>
* **v0.9.6.1:** <https://memorytamer.s3.amazonaws.com/MemoryTamer-0.9.6.1.zip>
* **v1.0:** <https://memorytamer.s3.amazonaws.com/MemoryTamer-1.0.zip>
* **v1.0.1:** <https://memorytamer.s3.amazonaws.com/MemoryTamer-1.0.1.zip>
5 changes: 3 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ Motion::Project::App.setup do |app|
app.icon = 'Icon.icns'
app.info_plist['CFBundleIconFile'] = 'Icon.icns'
app.name = 'MemoryTamer'
app.version = '1.0'
app.short_version = '1.0'
app.version = '1.0.1'
app.short_version = '1.0.1'
app.identifier = 'us.myepg.MemoryTamerMAS'
app.info_plist['NSUIElement'] = 1
app.info_plist['SUFeedURL'] = 'https://github.com/raw/henderea/MemoryTamer/master/appcast.xml'
app.deployment_target = '10.7'
app.codesign_certificate = 'Developer ID Application: Eric Henderson (SKWXXEM822)'
app.entitlements['com.apple.security.app-sandbox'] = true
app.embedded_frameworks << 'vendor/Growl.framework'
app.embedded_frameworks << 'vendor/HockeySDK.framework'
app.vendor_project('vendor/mem_info', :static)
end
7 changes: 7 additions & 0 deletions app/app_delegate.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
class AppDelegate
attr_accessor :prefs

BITCrashManagerStatusDisabled = 0
BITCrashManagerStatusAlwaysAsk = 1
BITCrashManagerStatusAutoSend = 2

# noinspection RubyUnusedLocalVariable
def applicationDidFinishLaunching(notification)
BITHockeyManager.sharedHockeyManager.configureWithIdentifier('128ebd3240db358d4b1ea5f228269de6')
# BITHockeyManager.sharedHockeyManager.crashManager.crashManagerStatus = BITCrashManagerStatusAutoSend
BITHockeyManager.sharedHockeyManager.startManager
Util.setup_paddle
SUUpdater.sharedUpdater if Info.paddle?
Info.freeing = false
Expand Down
9 changes: 9 additions & 0 deletions appcast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
<link>https://github.com/raw/henderea/MemoryTamer/master/appcast.xml</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version 1.0.1</title>
<sparkle:releaseNotesLink>
http://releases.io/henderea/MemoryTamer/1.0.1?heading=true
</sparkle:releaseNotesLink>
<pubDate>Tue, 9 Sep 2014 15:30:00 -0400</pubDate>
<enclosure url="http://memorytamer.s3.amazonaws.com/MemoryTamer-1.0.1.zip" sparkle:version="1.0.1" length="4947381" type="application/octet-stream" />
<sparkle:minimumSystemVersion>10.7</sparkle:minimumSystemVersion>
</item>
<item>
<title>Version 1.0</title>
<sparkle:releaseNotesLink>
Expand Down
1 change: 1 addition & 0 deletions vendor/HockeySDK.framework/Headers
1 change: 1 addition & 0 deletions vendor/HockeySDK.framework/HockeySDK
1 change: 1 addition & 0 deletions vendor/HockeySDK.framework/Resources
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
*
* Copyright (c) 2012-2014 HockeyApp, Bit Stadium GmbH.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#import <Cocoa/Cocoa.h>

/**
* `NSApplication` subclass to catch additional exceptions
*
* On OS X runtime not all uncaught exceptions do end in an custom `NSUncaughtExceptionHandler`.
* In addition "sometimes" exceptions don't even cause the app to crash, depending on where and
* when they happen.
*
* Here are the known scenarios:
*
* 1. Custom `NSUncaughtExceptionHandler` don't start working until after `NSApplication` has finished
* calling all of its delegate methods!
*
* Example:
* - (void)applicationDidFinishLaunching:(NSNotification *)note {
* ...
* [NSException raise:@"ExceptionAtStartup" format:@"This will not be recognized!"];
* ...
* }
*
*
* 2. The default `NSUncaughtExceptionHandler` in `NSApplication` only logs exceptions to the console and
* ends their processing. Resulting in exceptions that occur in the `NSApplication` "scope" not
* occurring in a registered custom `NSUncaughtExceptionHandler`.
*
* Example:
* - (void)applicationDidFinishLaunching:(NSNotification *)note {
* ...
* [self performSelector:@selector(delayedException) withObject:nil afterDelay:5];
* ...
* }
*
* - (void)delayedException {
* NSArray *array = [NSArray array];
* [array objectAtIndex:23];
* }
*
* 3. Any exceptions occurring in IBAction or other GUI does not even reach the NSApplication default
* UncaughtExceptionHandler.
*
* Example:
* - (IBAction)doExceptionCrash:(id)sender {
* NSArray *array = [NSArray array];
* [array objectAtIndex:23];
* }
*
*
* Solution A:
*
* Implement `NSExceptionHandler` and set the `ExceptionHandlingMask` to `NSLogAndHandleEveryExceptionMask`
*
* Benefits:
*
* 1. Solves all of the above scenarios
*
* 2. Clean solution using a standard Cocoa System specifically meant for this purpose.
*
* 3. Safe. Doesn't use private API.
*
* Problems:
*
* 1. To catch all exceptions the `NSExceptionHandlers` mask has to include `NSLogOtherExceptionMask` and
* `NSHandleOtherExceptionMask`. But this will result in @catch blocks to be called after the exception
* handler processed the exception and likely lets the app crash and create a crash report.
* This makes the @catch block basically not working at all.
*
* 2. If anywhere in the app a custom `NSUncaughtExceptionHandler` will be registered, e.g. in a closed source
* library the develop has to use, the complete mechanism will stop working
*
* 3. Not clear if this solves all scenarios there can be.
*
* 4. Requires to adjust PLCrashReporter not to register its `NSUncaughtExceptionHandler` which is not a good idea,
* since it would require the `NSExceptionHandler` would catch *all* exceptions and that would cause
* PLCrashReporter to stop all running threads every time an exception occurs even if will be handled right
* away, e.g. by a system framework.
*
*
* Solution B:
*
* Overwrite and extend specific methods of `NSApplication`. Can be implemented via subclassing NSApplication or
* by using a category.
*
* Benefits:
*
* 1. Solves scenarios 2 (by overwriting `reportException:`) and 3 (by overwriting `sendEvent:`)
*
* 2. Subclassing approach isn't enforcing the mechanism onto apps and let developers opt-in.
* (Category approach would enforce it and rather be a problem of this soltuion.)
*
* 3. Safe. Doesn't use private API.
*
* Problems:
*
* 1. Does not automatically solve scenario 1. Developer would have to put all that code into @try @catch blocks
*
* 2. Not a clean implementation, rather feels like a workaround.
*
* 3. Not clear if this solves all scenarios there can be.
*
*
* Chosen Solution: B via subclassing
*
* Reasons:
*
* 1. The Problems 1. and 2. of Solution A are too drastic and aren't acceptable for every developer using this SDK
* Especially Problem 1 is a big No Go for lots of developers.
*
* 2. Solution B can be used optionally, can be adopted easily into developers own `NSApplication` subclasses and
* by implementing it in a subclass instead of a category isn't enforced even though it requires additional
* steps for setup.
*
* 3. The not covered Scenario 1. can be achieved by the developer by enclosing most of the code within
* NSApplication startup delegates in @try @catch blocks or moving as much code as possible out of these
* methods and deferring their execution, e.g. using background threads. Not ideal though.
*
*
* References:
* https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/Exceptions/Tasks/ControllingAppResponse.html#//apple_ref/doc/uid/20000473-BBCHGJIJ
* http://stackoverflow.com/a/4199717/474794
* http://stackoverflow.com/a/3419073/474794
* http://macdevcenter.com/pub/a/mac/2007/07/31/understanding-exceptions-and-handlers-in-cocoa.html
*
*/
@interface BITCrashExceptionApplication : NSApplication

@end
Loading

0 comments on commit 6f433aa

Please sign in to comment.