├── .gitignore ├── CrashSymbal.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── CrashSymbal.xcscheme ├── CrashSymbal ├── DVTFontAndColorTheme.h ├── DVTInvalidation-Protocol.h ├── DVTPreferenceSet-Protocol.h ├── Info.plist ├── JFWCrashSymbal.h ├── JFWCrashSymbal.m ├── JFWDropPathTextField.h ├── JFWDropPathTextField.m ├── JFWSymbolicate.storyboard ├── JFWSymbolicateViewController.h ├── JFWSymbolicateViewController.m ├── NSObject_Extension.h └── NSObject_Extension.m ├── LICENSE.txt ├── README.md └── Screenshots └── CrashSymbal.png /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | .DS_Store? 5 | ._* 6 | .Spotlight-V100 7 | .Trashes 8 | ehthumbs.db 9 | 10 | #profile I have a path containing "Profile". Why should `profile` be ignored? 11 | *.swp 12 | *~.nib 13 | 14 | DerivedData/ 15 | build/ 16 | *.o 17 | 18 | *.pbxuser 19 | *.perspective 20 | *.perspectivev3 21 | *.xccheckout 22 | 23 | *.mode1v3 24 | *.mode2v3 25 | 26 | */xcuserdata/ 27 | 28 | Pods/ 29 | -------------------------------------------------------------------------------- /CrashSymbal.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CB7D6AA41BE68D3500D727C9 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB7D6AA31BE68D3500D727C9 /* AppKit.framework */; }; 11 | CB7D6AA61BE68D3500D727C9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB7D6AA51BE68D3500D727C9 /* Foundation.framework */; }; 12 | CB7D6AAD1BE68D3500D727C9 /* JFWCrashSymbal.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6AAC1BE68D3500D727C9 /* JFWCrashSymbal.m */; }; 13 | CB7D6AB01BE68D3500D727C9 /* NSObject_Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6AAF1BE68D3500D727C9 /* NSObject_Extension.m */; }; 14 | CB7D6ABF1BE68F6500D727C9 /* JFWSymbolicate.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CB7D6ABE1BE68F6500D727C9 /* JFWSymbolicate.storyboard */; }; 15 | CB7D6AC21BE68FD200D727C9 /* JFWSymbolicateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CB7D6AC11BE68FD200D727C9 /* JFWSymbolicateViewController.m */; }; 16 | CBB0C5161BE6E2CE00D70563 /* JFWDropPathTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = CBB0C5151BE6E2CE00D70563 /* JFWDropPathTextField.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | CB7D6AA01BE68D3500D727C9 /* CrashSymbal.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CrashSymbal.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | CB7D6AA31BE68D3500D727C9 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 22 | CB7D6AA51BE68D3500D727C9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 23 | CB7D6AAB1BE68D3500D727C9 /* JFWCrashSymbal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JFWCrashSymbal.h; sourceTree = ""; }; 24 | CB7D6AAC1BE68D3500D727C9 /* JFWCrashSymbal.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JFWCrashSymbal.m; sourceTree = ""; }; 25 | CB7D6AAE1BE68D3500D727C9 /* NSObject_Extension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSObject_Extension.h; sourceTree = ""; }; 26 | CB7D6AAF1BE68D3500D727C9 /* NSObject_Extension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSObject_Extension.m; sourceTree = ""; }; 27 | CB7D6AB11BE68D3500D727C9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | CB7D6ABE1BE68F6500D727C9 /* JFWSymbolicate.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = JFWSymbolicate.storyboard; sourceTree = ""; }; 29 | CB7D6AC01BE68FD200D727C9 /* JFWSymbolicateViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JFWSymbolicateViewController.h; sourceTree = ""; }; 30 | CB7D6AC11BE68FD200D727C9 /* JFWSymbolicateViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JFWSymbolicateViewController.m; sourceTree = ""; }; 31 | CBB0C5141BE6E2CE00D70563 /* JFWDropPathTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JFWDropPathTextField.h; sourceTree = ""; }; 32 | CBB0C5151BE6E2CE00D70563 /* JFWDropPathTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JFWDropPathTextField.m; sourceTree = ""; }; 33 | CBE905A91BE6B42D00A1B4F6 /* DVTInvalidation-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DVTInvalidation-Protocol.h"; sourceTree = ""; }; 34 | CBE905AA1BE6B42D00A1B4F6 /* DVTPreferenceSet-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DVTPreferenceSet-Protocol.h"; sourceTree = ""; }; 35 | CBE905AB1BE6B42D00A1B4F6 /* DVTFontAndColorTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVTFontAndColorTheme.h; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | CB7D6A9E1BE68D3500D727C9 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | CB7D6AA41BE68D3500D727C9 /* AppKit.framework in Frameworks */, 44 | CB7D6AA61BE68D3500D727C9 /* Foundation.framework in Frameworks */, 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXFrameworksBuildPhase section */ 49 | 50 | /* Begin PBXGroup section */ 51 | CB7D6A971BE68D3500D727C9 = { 52 | isa = PBXGroup; 53 | children = ( 54 | CB7D6AA71BE68D3500D727C9 /* CrashSymbal */, 55 | CB7D6AA21BE68D3500D727C9 /* Frameworks */, 56 | CB7D6AA11BE68D3500D727C9 /* Products */, 57 | ); 58 | sourceTree = ""; 59 | }; 60 | CB7D6AA11BE68D3500D727C9 /* Products */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | CB7D6AA01BE68D3500D727C9 /* CrashSymbal.xcplugin */, 64 | ); 65 | name = Products; 66 | sourceTree = ""; 67 | }; 68 | CB7D6AA21BE68D3500D727C9 /* Frameworks */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | CB7D6AA31BE68D3500D727C9 /* AppKit.framework */, 72 | CB7D6AA51BE68D3500D727C9 /* Foundation.framework */, 73 | ); 74 | name = Frameworks; 75 | sourceTree = ""; 76 | }; 77 | CB7D6AA71BE68D3500D727C9 /* CrashSymbal */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | CB7D6AAB1BE68D3500D727C9 /* JFWCrashSymbal.h */, 81 | CB7D6AAC1BE68D3500D727C9 /* JFWCrashSymbal.m */, 82 | CB7D6AC01BE68FD200D727C9 /* JFWSymbolicateViewController.h */, 83 | CB7D6AC11BE68FD200D727C9 /* JFWSymbolicateViewController.m */, 84 | CB7D6ABE1BE68F6500D727C9 /* JFWSymbolicate.storyboard */, 85 | CBB0C5141BE6E2CE00D70563 /* JFWDropPathTextField.h */, 86 | CBB0C5151BE6E2CE00D70563 /* JFWDropPathTextField.m */, 87 | CB7D6AAE1BE68D3500D727C9 /* NSObject_Extension.h */, 88 | CB7D6AAF1BE68D3500D727C9 /* NSObject_Extension.m */, 89 | CBE905AB1BE6B42D00A1B4F6 /* DVTFontAndColorTheme.h */, 90 | CBE905A91BE6B42D00A1B4F6 /* DVTInvalidation-Protocol.h */, 91 | CBE905AA1BE6B42D00A1B4F6 /* DVTPreferenceSet-Protocol.h */, 92 | CB7D6AA81BE68D3500D727C9 /* Supporting Files */, 93 | ); 94 | path = CrashSymbal; 95 | sourceTree = ""; 96 | }; 97 | CB7D6AA81BE68D3500D727C9 /* Supporting Files */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | CB7D6AB11BE68D3500D727C9 /* Info.plist */, 101 | ); 102 | name = "Supporting Files"; 103 | sourceTree = ""; 104 | }; 105 | /* End PBXGroup section */ 106 | 107 | /* Begin PBXNativeTarget section */ 108 | CB7D6A9F1BE68D3500D727C9 /* CrashSymbal */ = { 109 | isa = PBXNativeTarget; 110 | buildConfigurationList = CB7D6AB41BE68D3500D727C9 /* Build configuration list for PBXNativeTarget "CrashSymbal" */; 111 | buildPhases = ( 112 | CB7D6A9C1BE68D3500D727C9 /* Sources */, 113 | CB7D6A9D1BE68D3500D727C9 /* Resources */, 114 | CB7D6A9E1BE68D3500D727C9 /* Frameworks */, 115 | ); 116 | buildRules = ( 117 | ); 118 | dependencies = ( 119 | ); 120 | name = CrashSymbal; 121 | productName = CrashSymbal; 122 | productReference = CB7D6AA01BE68D3500D727C9 /* CrashSymbal.xcplugin */; 123 | productType = "com.apple.product-type.bundle"; 124 | }; 125 | /* End PBXNativeTarget section */ 126 | 127 | /* Begin PBXProject section */ 128 | CB7D6A981BE68D3500D727C9 /* Project object */ = { 129 | isa = PBXProject; 130 | attributes = { 131 | LastUpgradeCheck = 0710; 132 | ORGANIZATIONNAME = "Julian Weinert Softwareentwicklung"; 133 | TargetAttributes = { 134 | CB7D6A9F1BE68D3500D727C9 = { 135 | CreatedOnToolsVersion = 7.1; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = CB7D6A9B1BE68D3500D727C9 /* Build configuration list for PBXProject "CrashSymbal" */; 140 | compatibilityVersion = "Xcode 3.2"; 141 | developmentRegion = English; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | ); 146 | mainGroup = CB7D6A971BE68D3500D727C9; 147 | productRefGroup = CB7D6AA11BE68D3500D727C9 /* Products */; 148 | projectDirPath = ""; 149 | projectRoot = ""; 150 | targets = ( 151 | CB7D6A9F1BE68D3500D727C9 /* CrashSymbal */, 152 | ); 153 | }; 154 | /* End PBXProject section */ 155 | 156 | /* Begin PBXResourcesBuildPhase section */ 157 | CB7D6A9D1BE68D3500D727C9 /* Resources */ = { 158 | isa = PBXResourcesBuildPhase; 159 | buildActionMask = 2147483647; 160 | files = ( 161 | CB7D6ABF1BE68F6500D727C9 /* JFWSymbolicate.storyboard in Resources */, 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | }; 165 | /* End PBXResourcesBuildPhase section */ 166 | 167 | /* Begin PBXSourcesBuildPhase section */ 168 | CB7D6A9C1BE68D3500D727C9 /* Sources */ = { 169 | isa = PBXSourcesBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | CB7D6AAD1BE68D3500D727C9 /* JFWCrashSymbal.m in Sources */, 173 | CB7D6AC21BE68FD200D727C9 /* JFWSymbolicateViewController.m in Sources */, 174 | CB7D6AB01BE68D3500D727C9 /* NSObject_Extension.m in Sources */, 175 | CBB0C5161BE6E2CE00D70563 /* JFWDropPathTextField.m in Sources */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXSourcesBuildPhase section */ 180 | 181 | /* Begin XCBuildConfiguration section */ 182 | CB7D6AB21BE68D3500D727C9 /* Debug */ = { 183 | isa = XCBuildConfiguration; 184 | buildSettings = { 185 | ALWAYS_SEARCH_USER_PATHS = NO; 186 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 187 | CLANG_CXX_LIBRARY = "libc++"; 188 | CLANG_ENABLE_MODULES = YES; 189 | CLANG_ENABLE_OBJC_ARC = YES; 190 | CLANG_WARN_BOOL_CONVERSION = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 193 | CLANG_WARN_EMPTY_BODY = YES; 194 | CLANG_WARN_ENUM_CONVERSION = YES; 195 | CLANG_WARN_INT_CONVERSION = YES; 196 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 197 | CLANG_WARN_UNREACHABLE_CODE = YES; 198 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 199 | COPY_PHASE_STRIP = NO; 200 | DEBUG_INFORMATION_FORMAT = dwarf; 201 | ENABLE_STRICT_OBJC_MSGSEND = YES; 202 | ENABLE_TESTABILITY = YES; 203 | GCC_C_LANGUAGE_STANDARD = gnu99; 204 | GCC_DYNAMIC_NO_PIC = NO; 205 | GCC_NO_COMMON_BLOCKS = YES; 206 | GCC_OPTIMIZATION_LEVEL = 0; 207 | GCC_PREPROCESSOR_DEFINITIONS = ( 208 | "DEBUG=1", 209 | "$(inherited)", 210 | ); 211 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 212 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 213 | GCC_WARN_UNDECLARED_SELECTOR = YES; 214 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 215 | GCC_WARN_UNUSED_FUNCTION = YES; 216 | GCC_WARN_UNUSED_VARIABLE = YES; 217 | MTL_ENABLE_DEBUG_INFO = YES; 218 | ONLY_ACTIVE_ARCH = YES; 219 | }; 220 | name = Debug; 221 | }; 222 | CB7D6AB31BE68D3500D727C9 /* Release */ = { 223 | isa = XCBuildConfiguration; 224 | buildSettings = { 225 | ALWAYS_SEARCH_USER_PATHS = NO; 226 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 227 | CLANG_CXX_LIBRARY = "libc++"; 228 | CLANG_ENABLE_MODULES = YES; 229 | CLANG_ENABLE_OBJC_ARC = YES; 230 | CLANG_WARN_BOOL_CONVERSION = YES; 231 | CLANG_WARN_CONSTANT_CONVERSION = YES; 232 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 237 | CLANG_WARN_UNREACHABLE_CODE = YES; 238 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 239 | COPY_PHASE_STRIP = NO; 240 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 241 | ENABLE_NS_ASSERTIONS = NO; 242 | ENABLE_STRICT_OBJC_MSGSEND = YES; 243 | GCC_C_LANGUAGE_STANDARD = gnu99; 244 | GCC_NO_COMMON_BLOCKS = YES; 245 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 246 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 247 | GCC_WARN_UNDECLARED_SELECTOR = YES; 248 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 249 | GCC_WARN_UNUSED_FUNCTION = YES; 250 | GCC_WARN_UNUSED_VARIABLE = YES; 251 | MTL_ENABLE_DEBUG_INFO = NO; 252 | }; 253 | name = Release; 254 | }; 255 | CB7D6AB51BE68D3500D727C9 /* Debug */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | COMBINE_HIDPI_IMAGES = YES; 259 | DEPLOYMENT_LOCATION = YES; 260 | DSTROOT = "$(HOME)"; 261 | INFOPLIST_FILE = CrashSymbal/Info.plist; 262 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 263 | MACOSX_DEPLOYMENT_TARGET = 10.11; 264 | PRODUCT_BUNDLE_IDENTIFIER = de.julianweinert.CrashSymbal; 265 | PRODUCT_NAME = CrashSymbal; 266 | WRAPPER_EXTENSION = xcplugin; 267 | }; 268 | name = Debug; 269 | }; 270 | CB7D6AB61BE68D3500D727C9 /* Release */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | COMBINE_HIDPI_IMAGES = YES; 274 | DEPLOYMENT_LOCATION = YES; 275 | DSTROOT = "$(HOME)"; 276 | INFOPLIST_FILE = CrashSymbal/Info.plist; 277 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins"; 278 | MACOSX_DEPLOYMENT_TARGET = 10.11; 279 | PRODUCT_BUNDLE_IDENTIFIER = de.julianweinert.CrashSymbal; 280 | PRODUCT_NAME = CrashSymbal; 281 | WRAPPER_EXTENSION = xcplugin; 282 | }; 283 | name = Release; 284 | }; 285 | /* End XCBuildConfiguration section */ 286 | 287 | /* Begin XCConfigurationList section */ 288 | CB7D6A9B1BE68D3500D727C9 /* Build configuration list for PBXProject "CrashSymbal" */ = { 289 | isa = XCConfigurationList; 290 | buildConfigurations = ( 291 | CB7D6AB21BE68D3500D727C9 /* Debug */, 292 | CB7D6AB31BE68D3500D727C9 /* Release */, 293 | ); 294 | defaultConfigurationIsVisible = 0; 295 | defaultConfigurationName = Release; 296 | }; 297 | CB7D6AB41BE68D3500D727C9 /* Build configuration list for PBXNativeTarget "CrashSymbal" */ = { 298 | isa = XCConfigurationList; 299 | buildConfigurations = ( 300 | CB7D6AB51BE68D3500D727C9 /* Debug */, 301 | CB7D6AB61BE68D3500D727C9 /* Release */, 302 | ); 303 | defaultConfigurationIsVisible = 0; 304 | defaultConfigurationName = Release; 305 | }; 306 | /* End XCConfigurationList section */ 307 | }; 308 | rootObject = CB7D6A981BE68D3500D727C9 /* Project object */; 309 | } 310 | -------------------------------------------------------------------------------- /CrashSymbal.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CrashSymbal.xcodeproj/xcshareddata/xcschemes/CrashSymbal.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 61 | 65 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 85 | 87 | 88 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /CrashSymbal/DVTFontAndColorTheme.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2012 by Steve Nygard. 5 | */ 6 | 7 | #import "DVTPreferenceSet-Protocol.h" 8 | 9 | @class DVTCustomDataSpecifier, DVTPointerArray, DVTStackBacktrace, NSColor, NSFont, NSImage, NSString, NSURL; 10 | 11 | @interface DVTFontAndColorTheme : NSObject 12 | { 13 | NSString *_name; 14 | NSImage *_image; 15 | NSURL *_dataURL; 16 | DVTCustomDataSpecifier *_customDataSpecifier; 17 | NSColor *_sourceTextBackgroundColor; 18 | NSColor *_sourceTextSidebarBackgroundColor; 19 | NSColor *_sourceTextSidebarEdgeColor; 20 | NSColor *_sourceTextSidebarNumbersColor; 21 | NSColor *_sourceTextFoldbarBackgroundColor; 22 | NSColor *_sourceTextSelectionColor; 23 | NSColor *_sourceTextSecondarySelectionColor; 24 | NSColor *_sourceTextInsertionPointColor; 25 | NSColor *_sourceTextInvisiblesColor; 26 | NSColor *_sourceTextBlockDimBackgroundColor; 27 | NSColor *_sourceTextTokenizedBorderColor; 28 | NSColor *_sourceTextTokenizedBackgroundColor; 29 | NSColor *_sourceTextTokenizedBorderSelectedColor; 30 | NSColor *_sourceTextTokenizedBackgroundSelectedColor; 31 | NSColor *_consoleTextBackgroundColor; 32 | NSColor *_consoleTextSelectionColor; 33 | NSColor *_consoleTextSecondarySelectionColor; 34 | NSColor *_consoleTextInsertionPointColor; 35 | NSColor *_consoleDebuggerPromptTextColor; 36 | NSColor *_consoleDebuggerInputTextColor; 37 | NSColor *_consoleDebuggerOutputTextColor; 38 | NSColor *_consoleExecutableInputTextColor; 39 | NSColor *_consoleExecutableOutputTextColor; 40 | NSFont *_consoleDebuggerPromptTextFont; 41 | NSFont *_consoleDebuggerInputTextFont; 42 | NSFont *_consoleDebuggerOutputTextFont; 43 | NSFont *_consoleExecutableInputTextFont; 44 | NSFont *_consoleExecutableOutputTextFont; 45 | NSColor *_debuggerInstructionPointerColor; 46 | NSColor *_sourcePlainTextColor; 47 | NSFont *_sourcePlainTextFont; 48 | DVTPointerArray *_syntaxColorsByNodeType; 49 | DVTPointerArray *_syntaxFontsByNodeType; 50 | NSColor *_sourceTextCompletionPreviewColor; 51 | BOOL _builtIn; 52 | BOOL _loadedData; 53 | BOOL _contentNeedsSaving; 54 | BOOL _hasMultipleSourceTextFonts; 55 | } 56 | 57 | + (id)_defaultSourceCodeFont; 58 | + (id)keyPathsForValuesAffectingConsoleTextSecondarySelectionColor; 59 | + (id)keyPathsForValuesAffectingSourceTextSecondarySelectionColor; 60 | + (id)titleForNewPreferenceSetFromTemplate; 61 | + (id)preferenceSetsListHeader; 62 | + (id)preferenceSetsFileExtension; 63 | + (id)defaultKeyForExcludedBuiltInPreferenceSets; 64 | + (id)defaultKeyForCurrentPreferenceSet; 65 | + (id)builtInPreferenceSetsDirectoryURL; 66 | + (id)systemPreferenceSet; 67 | + (id)preferenceSetGroupingName; 68 | + (id)_nodeTypesIncludedInPreferences; 69 | + (id)_stringRepresentationOfFont:(id)arg1; 70 | + (id)_fontWithName:(id)arg1 size:(double)arg2; 71 | + (id)currentTheme; 72 | + (id)preferenceSetsManager; 73 | + (void)initialize; 74 | @property(readonly) BOOL loadedData; // @synthesize loadedData=_loadedData; 75 | @property(readonly) DVTPointerArray *syntaxFontsByNodeType; // @synthesize syntaxFontsByNodeType=_syntaxFontsByNodeType; 76 | @property(readonly) DVTPointerArray *syntaxColorsByNodeType; // @synthesize syntaxColorsByNodeType=_syntaxColorsByNodeType; 77 | @property(nonatomic) BOOL hasMultipleSourceTextFonts; // @synthesize hasMultipleSourceTextFonts=_hasMultipleSourceTextFonts; 78 | @property BOOL contentNeedsSaving; // @synthesize contentNeedsSaving=_contentNeedsSaving; 79 | @property(retain) DVTCustomDataSpecifier *customDataSpecifier; // @synthesize customDataSpecifier=_customDataSpecifier; 80 | @property(readonly, getter=isBuiltIn) BOOL builtIn; // @synthesize builtIn=_builtIn; 81 | @property(retain) NSImage *image; // @synthesize image=_image; 82 | @property(copy) NSString *name; // @synthesize name=_name; 83 | - (void)setFont:(id)arg1 forNodeTypes:(id)arg2; 84 | - (void)setColor:(id)arg1 forNodeTypes:(id)arg2; 85 | - (void)_setColorOrFont:(id)arg1 forNodeTypes:(id)arg2; 86 | - (id)fontForNodeType:(short)arg1; 87 | - (id)colorForNodeType:(short)arg1; 88 | @property(readonly) NSFont *sourcePlainTextFont; 89 | @property(readonly) NSColor *sourcePlainTextColor; 90 | - (void)primitiveSetConsoleDebuggerPromptTextColor:(id)arg1; 91 | - (void)_setColorOrFont:(id)arg1 forKey:(id)arg2 colorOrFontivar:(id *)arg3; 92 | @property NSColor *debuggerInstructionPointerColor; 93 | @property NSFont *consoleExecutableOutputTextFont; 94 | @property NSFont *consoleExecutableInputTextFont; 95 | @property NSFont *consoleDebuggerOutputTextFont; 96 | @property NSFont *consoleDebuggerInputTextFont; 97 | @property NSFont *consoleDebuggerPromptTextFont; 98 | @property NSColor *consoleExecutableOutputTextColor; 99 | @property NSColor *consoleExecutableInputTextColor; 100 | @property NSColor *consoleDebuggerOutputTextColor; 101 | @property NSColor *consoleDebuggerInputTextColor; 102 | @property NSColor *consoleDebuggerPromptTextColor; 103 | @property NSColor *consoleTextInsertionPointColor; 104 | @property NSColor *consoleTextSecondarySelectionColor; 105 | @property NSColor *consoleTextSelectionColor; 106 | @property NSColor *consoleTextBackgroundColor; 107 | @property(readonly) NSColor *sourceTextTokenizedBackgroundSelectedColor; 108 | @property(readonly) NSColor *sourceTextTokenizedBorderSelectedColor; 109 | @property(readonly) NSColor *sourceTextTokenizedBackgroundColor; 110 | @property(readonly) NSColor *sourceTextTokenizedBorderColor; 111 | @property(readonly) NSColor *sourceTextLinkColor; 112 | @property(readonly) NSColor *sourceTextCompletionPreviewColor; 113 | @property(readonly) NSColor *sourceTextBlockDimBackgroundColor; 114 | @property NSColor *sourceTextInvisiblesColor; 115 | @property NSColor *sourceTextInsertionPointColor; 116 | @property(readonly) NSColor *sourceTextSecondarySelectionColor; 117 | @property NSColor *sourceTextSelectionColor; 118 | @property(readonly) NSColor *sourceTextFoldbarBackgroundColor; 119 | @property(readonly) NSColor *sourceTextSidebarNumbersColor; 120 | @property(readonly) NSColor *sourceTextSidebarEdgeColor; 121 | @property(readonly) NSColor *sourceTextSidebarBackgroundColor; 122 | @property NSColor *sourceTextBackgroundColor; 123 | - (id)description; 124 | @property(readonly) NSString *localizedName; 125 | - (void)_updateHasMultipleSourceTextFonts; 126 | - (void)_updateDerivedColors; 127 | - (BOOL)_loadFontsAndColors; 128 | - (id)dataRepresentationWithError:(id *)arg1; 129 | - (void)primitiveInvalidate; 130 | - (id)initWithCustomDataSpecifier:(id)arg1 basePreferenceSet:(id)arg2; 131 | - (id)initWithName:(id)arg1 dataURL:(id)arg2; 132 | - (id)_initWithName:(id)arg1 syntaxColorsByNodeType:(id)arg2 syntaxFontsByNodeType:(id)arg3; 133 | - (void)_themeCommonInit; 134 | - (id)init; 135 | 136 | // Remaining properties 137 | @property(retain) DVTStackBacktrace *creationBacktrace; 138 | @property(readonly) DVTStackBacktrace *invalidationBacktrace; 139 | @property(readonly, nonatomic, getter=isValid) BOOL valid; 140 | 141 | @end 142 | 143 | -------------------------------------------------------------------------------- /CrashSymbal/DVTInvalidation-Protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2012 by Steve Nygard. 5 | */ 6 | 7 | @class DVTStackBacktrace; 8 | 9 | @protocol DVTInvalidation 10 | - (void)primitiveInvalidate; 11 | 12 | @optional 13 | @property(retain) DVTStackBacktrace *creationBacktrace; 14 | @property(readonly) DVTStackBacktrace *invalidationBacktrace; 15 | @property(readonly, nonatomic, getter=isValid) BOOL valid; 16 | - (void)invalidate; 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /CrashSymbal/DVTPreferenceSet-Protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generated by class-dump 3.4 (64 bit). 3 | * 4 | * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2012 by Steve Nygard. 5 | */ 6 | 7 | #import "DVTInvalidation-Protocol.h" 8 | 9 | @class DVTCustomDataSpecifier, NSImage, NSString; 10 | 11 | @protocol DVTPreferenceSet 12 | + (id)titleForNewPreferenceSetFromTemplate; 13 | + (id)preferenceSetsListHeader; 14 | + (id)preferenceSetsFileExtension; 15 | + (id)defaultKeyForExcludedBuiltInPreferenceSets; 16 | + (id)defaultKeyForCurrentPreferenceSet; 17 | + (id)builtInPreferenceSetsDirectoryURL; 18 | + (id)systemPreferenceSet; 19 | + (id)preferenceSetGroupingName; 20 | + (id)preferenceSetsManager; 21 | @property BOOL contentNeedsSaving; 22 | @property(readonly, getter=isBuiltIn) BOOL builtIn; 23 | @property(retain) DVTCustomDataSpecifier *customDataSpecifier; 24 | @property(retain) NSImage *image; 25 | @property(readonly) NSString *localizedName; 26 | @property(copy,readonly) NSString *name; 27 | - (id)dataRepresentationWithError:(id *)arg1; 28 | - (id)initWithCustomDataSpecifier:(id)arg1 basePreferenceSet:(id)arg2; 29 | - (id)initWithName:(id)arg1 dataURL:(id)arg2; 30 | 31 | @optional 32 | + (id)titleForManagePreferenceSets; 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /CrashSymbal/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | DVTPlugInCompatibilityUUIDs 26 | 27 | C4A681B0-4A26-480E-93EC-1218098B9AA0 28 | AD68E85B-441B-4301-B564-A45E4919A6AD 29 | A16FF353-8441-459E-A50C-B071F53F51B7 30 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7 31 | E969541F-E6F9-4D25-8158-72DC3545A6C6 32 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90 33 | 7265231C-39B4-402C-89E1-16167C4CC990 34 | F41BD31E-2683-44B8-AE7F-5F09E919790E 35 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C 36 | 37 | LSMinimumSystemVersion 38 | $(MACOSX_DEPLOYMENT_TARGET) 39 | NSPrincipalClass 40 | CrashSymbal 41 | XC4Compatible 42 | 43 | XCPluginHasUI 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /CrashSymbal/JFWCrashSymbal.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFWCrashSymbal.h 3 | // JFWCrashSymbal 4 | // 5 | // Created by Julian Weinert on 01/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class JFWCrashSymbal; 12 | 13 | static JFWCrashSymbal *sharedPlugin; 14 | 15 | @interface JFWCrashSymbal : NSObject 16 | 17 | + (instancetype)sharedPlugin; 18 | - (id)initWithBundle:(NSBundle *)plugin; 19 | 20 | @property (nonatomic, strong, readonly) NSBundle *bundle; 21 | @end -------------------------------------------------------------------------------- /CrashSymbal/JFWCrashSymbal.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFWCrashSymbal.m 3 | // JFWCrashSymbal 4 | // 5 | // Created by Julian Weinert on 01/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import "JFWCrashSymbal.h" 10 | #import "JFWSymbolicateViewController.h" 11 | 12 | @interface JFWCrashSymbal() 13 | 14 | @property (nonatomic, strong, readwrite) NSBundle *bundle; 15 | @property (nonatomic, retain) NSMenuItem *symbolicationMenuItem; 16 | @property (nonatomic, retain) NSWindowController *symbolicateWindowController; 17 | 18 | @end 19 | 20 | @implementation JFWCrashSymbal 21 | 22 | + (instancetype)sharedPlugin { 23 | return sharedPlugin; 24 | } 25 | 26 | - (id)initWithBundle:(NSBundle *)plugin { 27 | if (self = [super init]) { 28 | [self setBundle:plugin]; 29 | 30 | [[NSNotificationCenter defaultCenter] addObserver:self 31 | selector:@selector(applicationDidFinishLaunching:) 32 | name:NSApplicationDidFinishLaunchingNotification 33 | object:nil]; 34 | } 35 | return self; 36 | } 37 | 38 | - (void)applicationDidFinishLaunching:(NSNotification *)noti { 39 | [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidFinishLaunchingNotification object:nil]; 40 | 41 | NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Debug"]; 42 | 43 | if (menuItem) { 44 | NSString *itemTitle = @"Symbolicate Crashlog..."; 45 | 46 | if (!(symbPathForIdentifier(@"com.apple.dt.DVTFoundation") ?: symbPathForIdentifier(@"com.apple.DTDeviceKitBase"))) { 47 | itemTitle = [itemTitle stringByAppendingString:@" (incompatible)"]; 48 | } 49 | 50 | [self setSymbolicationMenuItem:[[NSMenuItem alloc] initWithTitle:itemTitle action:@selector(openSymbolicationPanel:) keyEquivalent:@""]]; 51 | [[self symbolicationMenuItem] setTarget:self]; 52 | 53 | [[menuItem submenu] addItem:[NSMenuItem separatorItem]]; 54 | [[menuItem submenu] addItem:[self symbolicationMenuItem]]; 55 | } 56 | } 57 | 58 | - (void)openSymbolicationPanel:(id)sender { 59 | if (!(symbPathForIdentifier(@"com.apple.dt.DVTFoundation") ?: symbPathForIdentifier(@"com.apple.DTDeviceKitBase"))) { 60 | [NSApp presentError:[[NSError alloc] initWithDomain:[[NSBundle mainBundle] bundleIdentifier] 61 | code:404 62 | userInfo:@{ 63 | NSLocalizedDescriptionKey: @"Xcode incompatible!", 64 | NSLocalizedRecoverySuggestionErrorKey: @"Could not find `symbolicatecrash`.\nPlease run a different version of Xcode or discuss the absence of symbolicatecrash with the community." 65 | }]]; 66 | 67 | return; 68 | } 69 | 70 | [self setSymbolicateWindowController:[[NSStoryboard storyboardWithName:@"JFWSymbolicate" bundle:[self bundle]] instantiateInitialController]]; 71 | [(JFWSymbolicateViewController *)[[self symbolicateWindowController] contentViewController] setWindowController:[self symbolicateWindowController]]; 72 | 73 | if ([NSApp mainWindow]) { 74 | [[NSApp mainWindow] beginSheet:[[self symbolicateWindowController] window] completionHandler:^(NSModalResponse returnCode) { 75 | if (returnCode == NSModalResponseContinue) { 76 | [[self symbolicateWindowController] performSelector:@selector(showWindow:) withObject:sender afterDelay:0.0]; 77 | } 78 | else { 79 | [self setSymbolicateWindowController:nil]; 80 | } 81 | }]; 82 | } 83 | else { 84 | [[self symbolicateWindowController] showWindow:sender]; 85 | } 86 | } 87 | 88 | - (void)dealloc { 89 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 90 | } 91 | 92 | - (BOOL)validateUserInterfaceItem:(id)anItem { 93 | // if (anItem == [self symbolicationMenuItem]) { 94 | // if (![NSApp mainWindow]) { 95 | // return NO; 96 | // } 97 | // } 98 | return YES; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /CrashSymbal/JFWDropPathTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFWDropPathTextField.h 3 | // CrashSymbal 4 | // 5 | // Created by Julian Weinert on 02/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol JFWDropPathDelegate; 12 | 13 | @interface JFWDropPathTextField : NSTextField 14 | 15 | @property (nonatomic, assign) IBOutlet id pathDropDelegate; 16 | 17 | @end 18 | 19 | @protocol JFWDropPathDelegate 20 | 21 | - (NSArray *)validFileTypesForDropPathTextField:(JFWDropPathTextField *)dropPathTextField; 22 | - (void)dropPathTextField:(JFWDropPathTextField *)dropPathTextField didDropPath:(NSString *)path; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /CrashSymbal/JFWDropPathTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFWDropPathTextField.m 3 | // CrashSymbal 4 | // 5 | // Created by Julian Weinert on 02/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import "JFWDropPathTextField.h" 10 | 11 | @implementation JFWDropPathTextField 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | [self registerForDraggedTypes:@[NSFilenamesPboardType]]; 16 | } 17 | 18 | - (NSDragOperation)draggingEntered:(id)sender { 19 | if ([[[sender draggingPasteboard] types] containsObject:NSFilenamesPboardType]) { 20 | if ([sender draggingSourceOperationMask] & NSDragOperationCopy) { 21 | NSArray *files = [[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType]; 22 | 23 | if ([self firstValidPathInPaths:files]) { 24 | return NSDragOperationCopy; 25 | } 26 | } 27 | } 28 | 29 | return NSDragOperationNone; 30 | } 31 | 32 | - (BOOL)performDragOperation:(id)sender { 33 | NSArray *files = [[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType]; 34 | NSString *filePath = [self firstValidPathInPaths:files]; 35 | 36 | if (filePath) { 37 | if ([[self pathDropDelegate] respondsToSelector:@selector(dropPathTextField:didDropPath:)]) { 38 | [[self pathDropDelegate] dropPathTextField:self didDropPath:filePath]; 39 | } 40 | 41 | return YES; 42 | } 43 | 44 | return NO; 45 | } 46 | 47 | - (NSString *)firstValidPathInPaths:(NSArray *)paths { 48 | NSArray *validTypes; 49 | 50 | if ([[self pathDropDelegate] respondsToSelector:@selector(validFileTypesForDropPathTextField:)]) { 51 | validTypes = [[self pathDropDelegate] validFileTypesForDropPathTextField:self]; 52 | } 53 | else { 54 | return [paths firstObject]; 55 | } 56 | 57 | for (NSString *crashPath in paths) { 58 | NSString *pathExtension = [crashPath pathExtension]; 59 | 60 | for (NSString *fileType in validTypes) { 61 | if ([pathExtension isEqualToString:fileType]) { 62 | return crashPath; 63 | } 64 | } 65 | } 66 | 67 | return nil; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /CrashSymbal/JFWSymbolicate.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 106 | 116 | 126 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 212 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /CrashSymbal/JFWSymbolicateViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JFWSymbolicateViewController.h 3 | // CrashSymbol 4 | // 5 | // Created by Julian Weinert on 01/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JFWSymbolicateViewController : NSViewController 12 | 13 | @property (nonatomic, assign) NSWindowController *windowController; 14 | 15 | NSString * symbPathForIdentifier(NSString *identifier); 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CrashSymbal/JFWSymbolicateViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JFWSymbolicateViewController.m 3 | // CrashSymbol 4 | // 5 | // Created by Julian Weinert on 01/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import "JFWSymbolicateViewController.h" 10 | #import "DVTFontAndColorTheme.h" 11 | 12 | #import "JFWDropPathTextField.h" 13 | 14 | @interface JFWSymbolicateViewController () 15 | 16 | @property (nonatomic, assign) IBOutlet NSTextField *pathTextField; 17 | @property (nonatomic, assign) IBOutlet NSTextView *outputView; 18 | 19 | @property (nonatomic, assign) IBOutlet NSButton *openButton; 20 | @property (nonatomic, assign) IBOutlet NSButton *exportButton; 21 | @property (nonatomic, assign) IBOutlet NSButton *symbolicateButton; 22 | @property (nonatomic, assign) IBOutlet NSButton *closeWindowButton; 23 | @property (nonatomic, assign) IBOutlet NSButton *popOutWindowButton; 24 | @property (nonatomic, assign) IBOutlet NSProgressIndicator *progressBar; 25 | 26 | @property (nonatomic, retain) IBOutlet NSView *openAccessoryView; 27 | @property (nonatomic, retain) IBOutlet NSView *saveAccessoryView; 28 | 29 | @property (nonatomic, retain) IBOutlet NSButton *openAccessoryShowHiddenCheckbox; 30 | @property (nonatomic, retain) IBOutlet NSButton *saveAccessoryShowHiddenCheckbox; 31 | @property (nonatomic, retain) IBOutlet NSButton *saveAccessoryRevealInFinderCheckbox; 32 | 33 | @property (nonatomic, retain) NSString *selectedPath; 34 | @property (nonatomic, retain) NSMutableString *symbolicatedCrash; 35 | 36 | @property (nonatomic, assign) NSOpenPanel *openPanel; 37 | @property (nonatomic, assign) NSSavePanel *savePanel; 38 | 39 | @end 40 | 41 | @implementation JFWSymbolicateViewController 42 | 43 | NSString * symbPathForIdentifier(NSString *identifier) { 44 | return [[NSBundle bundleWithIdentifier:identifier] pathForResource:@"symbolicatecrash" ofType:nil]; 45 | } 46 | 47 | - (void)viewDidLoad { 48 | [super viewDidLoad]; 49 | 50 | Class DVTFontAndColorThemeClass = NSClassFromString(@"DVTFontAndColorTheme"); 51 | DVTFontAndColorTheme *currentTheme = [DVTFontAndColorThemeClass currentTheme]; 52 | 53 | [[self outputView] setRichText:NO]; 54 | [[self outputView] setFont:[currentTheme consoleDebuggerOutputTextFont]]; 55 | [[self outputView] setTextColor:[currentTheme consoleDebuggerOutputTextColor]]; 56 | [[self outputView] setBackgroundColor:[currentTheme consoleTextBackgroundColor]]; 57 | 58 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 59 | 60 | if ([userDefaults boolForKey:@"de.julianweinert.JFWCrashSymbal.openPanelShowHidden"]) { 61 | [[self openAccessoryShowHiddenCheckbox] setState:NSOnState]; 62 | } 63 | if ([userDefaults boolForKey:@"de.julianweinert.JFWCrashSymbal.savePanelShowHidden"]) { 64 | [[self saveAccessoryShowHiddenCheckbox] setState:NSOnState]; 65 | } 66 | if ([userDefaults boolForKey:@"de.julianweinert.JFWCrashSymbal.savePanelReveal"]) { 67 | [[self saveAccessoryRevealInFinderCheckbox] setState:NSOnState]; 68 | } 69 | } 70 | 71 | - (void)viewWillAppear { 72 | [super viewWillAppear]; 73 | 74 | if ([[[self windowController] window] sheetParent]) { 75 | [[self popOutWindowButton] setHidden:NO]; 76 | } 77 | else { 78 | [[self popOutWindowButton] setHidden:YES]; 79 | [[self closeWindowButton] setTitle:@"Close"]; 80 | } 81 | } 82 | 83 | #pragma mark - property accessor overrides 84 | 85 | - (void)setSelectedPath:(NSString *)selectedPath { 86 | if (selectedPath != _selectedPath && [selectedPath length] > 0 && [[selectedPath pathExtension] isEqualToString:@"crash"]) { 87 | _selectedPath = selectedPath; 88 | 89 | [[self pathTextField] setStringValue:selectedPath]; 90 | [[self symbolicateButton] setEnabled:YES]; 91 | [[self progressBar] setDoubleValue:0]; 92 | [[self exportButton] setEnabled:NO]; 93 | } 94 | } 95 | 96 | #pragma mark - implementation 97 | 98 | - (IBAction)closeWindow:(id)sender { 99 | if ([[[self windowController] window] sheetParent]) { 100 | [[[[self windowController] window] sheetParent] endSheet:[[self windowController] window] returnCode:NSModalResponseOK]; 101 | } 102 | else { 103 | [[self windowController] close]; 104 | } 105 | } 106 | 107 | - (IBAction)popOutButWindow:(id)sender { 108 | [[[[self windowController] window] sheetParent] endSheet:[[self windowController] window] returnCode:NSModalResponseContinue]; 109 | } 110 | 111 | - (IBAction)selectFile:(id)sender { 112 | [self setOpenPanel:[NSOpenPanel openPanel]]; 113 | 114 | [[self openPanel] setShowsHiddenFiles:[[self openAccessoryShowHiddenCheckbox] state] == NSOnState]; 115 | [[self openPanel] setAccessoryView:[self openAccessoryView]]; 116 | [[self openPanel] setAllowedFileTypes:@[@"crash"]]; 117 | [[self openPanel] setCanSelectHiddenExtension:YES]; 118 | [[self openPanel] setAllowsMultipleSelection:NO]; 119 | [[self openPanel] setCanCreateDirectories:YES]; 120 | [[self openPanel] setAllowsOtherFileTypes:NO]; 121 | [[self openPanel] setCanChooseDirectories:NO]; 122 | [[self openPanel] setCanChooseFiles:YES]; 123 | 124 | [[self openPanel] beginSheetModalForWindow:[[self windowController] window] completionHandler:^(NSInteger result) { 125 | if (result == NSFileHandlingPanelOKButton) { 126 | [self setSelectedPath:[[[self openPanel] URL] path]]; 127 | } 128 | }]; 129 | } 130 | 131 | - (IBAction)symbolicate:(id)sender { 132 | if ([self selectedPath]) { 133 | [[self outputView] setString:@""]; 134 | 135 | [[self openButton] setEnabled:NO]; 136 | [[self symbolicateButton] setEnabled:NO]; 137 | [[self progressBar] setIndeterminate:YES]; 138 | 139 | [self setSymbolicatedCrash:[NSMutableString string]]; 140 | 141 | dispatch_async(dispatch_queue_create("de.julianweinert.CrashSymbal.symbolicate", 0), ^{ 142 | NSPipe *stdOutPipe = [NSPipe pipe]; 143 | NSPipe *stdErrPipe = [NSPipe pipe]; 144 | 145 | NSFileHandle *stdOut = [stdOutPipe fileHandleForReading]; 146 | NSFileHandle *stdErr = [stdErrPipe fileHandleForReading]; 147 | 148 | void (^appendToLog)(NSString *) = ^(NSString *string) { 149 | dispatch_sync(dispatch_get_main_queue(), ^{ 150 | BOOL scroll = [string length] > 0;//(NSMaxY([[self outputView] visibleRect]) == NSMaxY([[self outputView] bounds])); 151 | 152 | [[self outputView] setString:[[[self outputView] string] stringByAppendingString:string]]; 153 | 154 | if (scroll) { 155 | [[self outputView] scrollRangeToVisible:NSMakeRange([[[self outputView] string] length], 0)]; 156 | } 157 | }); 158 | }; 159 | 160 | [stdOut setReadabilityHandler:^(NSFileHandle *fileHandle) { 161 | NSData *outData = [fileHandle availableData]; 162 | 163 | if (outData) { 164 | NSStringEncoding outEncoding = [NSString stringEncodingForData:outData encodingOptions:nil convertedString:nil usedLossyConversion:nil]; 165 | NSString *outString = [[NSString alloc] initWithData:outData encoding:outEncoding]; 166 | 167 | appendToLog(outString); 168 | [[self symbolicatedCrash] appendString:outString]; 169 | } 170 | }]; 171 | 172 | [stdErr setReadabilityHandler:^(NSFileHandle *fileHandle) { 173 | NSData *errData = [fileHandle availableData]; 174 | 175 | if (errData) { 176 | NSStringEncoding errEncoding = [NSString stringEncodingForData:errData encodingOptions:nil convertedString:nil usedLossyConversion:nil]; 177 | NSString *errString = [[NSString alloc] initWithData:errData encoding:errEncoding]; 178 | 179 | appendToLog(errString); 180 | } 181 | }]; 182 | 183 | NSString *symbolicatecrashPath = symbPathForIdentifier(@"com.apple.dt.DVTFoundation") ?: symbPathForIdentifier(@"com.apple.DTDeviceKitBase"); 184 | 185 | if (symbolicatecrashPath == nil) { 186 | return; 187 | } 188 | 189 | NSString *developerDir = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents/Developer"]; 190 | 191 | NSTask *symbolicationTask = [[NSTask alloc] init]; 192 | 193 | [symbolicationTask setEnvironment:@{@"DEVELOPER_DIR": developerDir}]; 194 | [symbolicationTask setArguments:@[@"-v", [self selectedPath]]]; 195 | [symbolicationTask setLaunchPath:symbolicatecrashPath]; 196 | [symbolicationTask setStandardOutput:stdOutPipe]; 197 | [symbolicationTask setStandardError:stdErrPipe]; 198 | [symbolicationTask launch]; 199 | 200 | [symbolicationTask waitUntilExit]; 201 | 202 | dispatch_async(dispatch_get_main_queue(), ^{ 203 | [self symbolicationDone]; 204 | }); 205 | }); 206 | } 207 | } 208 | 209 | - (IBAction)exportLog:(id)sender { 210 | NSString *fileName = [[self selectedPath] lastPathComponent]; 211 | fileName = [[[fileName stringByDeletingPathExtension] stringByAppendingString:@"_symbolicated"] stringByAppendingPathExtension:[fileName pathExtension]]; 212 | 213 | [self setSavePanel:[NSSavePanel savePanel]]; 214 | 215 | [[self savePanel] setShowsHiddenFiles:[[self saveAccessoryShowHiddenCheckbox] state] == NSOnState]; 216 | [[self savePanel] setMessage:@"Select a location for the symbolicated crash log."]; 217 | [[self savePanel] setAccessoryView:[self saveAccessoryView]]; 218 | [[self savePanel] setNameFieldStringValue:fileName]; 219 | [[self savePanel] setCanCreateDirectories:YES]; 220 | 221 | [[self savePanel] beginSheetModalForWindow:[[self windowController] window] completionHandler:^(NSInteger result) { 222 | if (result == NSFileHandlingPanelOKButton) { 223 | [[[self symbolicatedCrash] dataUsingEncoding:NSUTF8StringEncoding] writeToURL:[[self savePanel] URL] atomically:YES]; 224 | 225 | if ([[self saveAccessoryRevealInFinderCheckbox] state] == NSOnState) { 226 | NSURL *fileURL = [[[self savePanel] URL] copy]; 227 | 228 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 229 | [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:@[fileURL]]; 230 | }); 231 | } 232 | } 233 | }]; 234 | } 235 | 236 | - (IBAction)openAcceccoryShowHidden:(NSButton *)sender { 237 | [[self openPanel] setShowsHiddenFiles:[sender state] == NSOnState]; 238 | 239 | [[NSUserDefaults standardUserDefaults] setBool:[sender state] == NSOnState forKey:@"de.julianweinert.JFWCrashSymbal.openPanelShowHidden"]; 240 | [[NSUserDefaults standardUserDefaults] synchronize]; 241 | } 242 | 243 | - (IBAction)saveAccessoryShowHidden:(NSButton *)sender { 244 | [[self savePanel] setShowsHiddenFiles:[sender state] == NSOnState]; 245 | 246 | [[NSUserDefaults standardUserDefaults] setBool:[sender state] == NSOnState forKey:@"de.julianweinert.JFWCrashSymbal.savePanelShowHidden"]; 247 | [[NSUserDefaults standardUserDefaults] synchronize]; 248 | } 249 | 250 | - (IBAction)saveAccessoryReveal:(NSButton *)sender { 251 | [[NSUserDefaults standardUserDefaults] setBool:[sender state] == NSOnState forKey:@"de.julianweinert.JFWCrashSymbal.savePanelReveal"]; 252 | [[NSUserDefaults standardUserDefaults] synchronize]; 253 | } 254 | 255 | #pragma mark - internal implementation 256 | 257 | - (void)symbolicationDone { 258 | [[self exportButton] setEnabled:[[self symbolicatedCrash] length] > 0]; 259 | [[self symbolicateButton] setEnabled:YES]; 260 | [[self openButton] setEnabled:YES]; 261 | 262 | [[self progressBar] setIndeterminate:NO]; 263 | [[self progressBar] setDoubleValue:100]; 264 | } 265 | 266 | #pragma mark - JFWDropPathDelegate 267 | 268 | - (NSArray *)validFileTypesForDropPathTextField:(JFWDropPathTextField *)dropPathTextField { 269 | return @[@"crash"]; 270 | } 271 | 272 | - (void)dropPathTextField:(JFWDropPathTextField *)dropPathTextField didDropPath:(NSString *)path { 273 | [self setSelectedPath:path]; 274 | } 275 | 276 | @end 277 | -------------------------------------------------------------------------------- /CrashSymbal/NSObject_Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject_Extension.h 3 | // CrashSymbol 4 | // 5 | // Created by Julian Weinert on 01/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Xcode_Plugin_Template_Extension) 12 | 13 | + (void)pluginDidLoad:(NSBundle *)plugin; 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /CrashSymbal/NSObject_Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject_Extension.m 3 | // CrashSymbol 4 | // 5 | // Created by Julian Weinert on 01/11/15. 6 | // Copyright © 2015 Julian Weinert Softwareentwicklung. All rights reserved. 7 | // 8 | 9 | 10 | #import "NSObject_Extension.h" 11 | #import "JFWCrashSymbal.h" 12 | 13 | @implementation NSObject (Xcode_Plugin_Template_Extension) 14 | 15 | + (void)pluginDidLoad:(NSBundle *)plugin 16 | { 17 | static dispatch_once_t onceToken; 18 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"]; 19 | if ([currentApplicationName isEqual:@"Xcode"]) { 20 | dispatch_once(&onceToken, ^{ 21 | sharedPlugin = [[JFWCrashSymbal alloc] initWithBundle:plugin]; 22 | }); 23 | } 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Julian Weinert 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CrashSymbal 2 | An Xcode plugin for manually symbolicating crash logs 3 | 4 | ## Install 5 | 6 | 1. Build the project to install the plugin. The plugin gets installed in `/Library/Application Support/Developer/Shared/Xcode/Plug-ins/CrashSymbal.xcplugin`. 7 | 2. Restart Xcode for the plugin to be activated. 8 | 9 | **Alternatively, install it using [Alcatraz plugin manager](https://github.com/supermarin/Alcatraz).** 10 | 11 | 12 | ## Usage 13 | 14 | Once installed and Xcode relaunched, the `Debug` menu will contain a new menu item labled "Symbolicate Crashlog...". 15 | It will open a dialog that allows you to select or drop a crashlog and smbolicate it. After the process you can export the symbolicated crash to your disk. 16 | 17 | 18 | ## Screenshot 19 | 20 | ![LinkedLog](https://raw.githubusercontent.com/julian-weinert/CrashSymbal/master/Screenshots/CrashSymbal.png) 21 | 22 | 23 | ## Bugs and limitations 24 | 25 | - Xcode needs to bundle the `symbolicatecrash` binary. 26 | - Now supporting newer Xcode versions, where `symbolicatecrash` is known to not be included. 27 | 28 | 29 | ## Contribution 30 | 31 | If you want to contribute, feel free to send me pull requests! But please follow these simple rules: 32 | 33 | - Double-check your code before sending a pull request 34 | - Pull requests should always be made agains `develop` 35 | - Always use tab-indentation! 36 | - Indent properly! 37 | -------------------------------------------------------------------------------- /Screenshots/CrashSymbal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julian-weinert/CrashSymbal/c886850f09397c2a21ac3c84b240ef224f2b1d22/Screenshots/CrashSymbal.png --------------------------------------------------------------------------------