├── .DS_Store ├── .gitignore ├── LICENSE ├── Objective-C ├── .DS_Store ├── DSYMTools.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ ├── Don.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ │ ├── answer.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ │ └── liunianhuaguoyanxi.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ ├── answer.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── DSYMTools.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── liunianhuaguoyanxi.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist └── DSYMTools │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon1024.png │ │ ├── icon128.png │ │ ├── icon16.png │ │ ├── icon256-1.png │ │ ├── icon256.png │ │ ├── icon32-1.png │ │ ├── icon32.png │ │ ├── icon512-1.png │ │ ├── icon512.png │ │ └── icon64.png │ ├── Contents.json │ ├── about.imageset │ │ ├── Contents.json │ │ └── about.png │ ├── avatar.imageset │ │ ├── Contents.json │ │ └── avatar.jpg │ └── export.imageset │ │ ├── Contents.json │ │ └── export.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Controller │ ├── AboutWindowController.h │ ├── AboutWindowController.m │ ├── AboutWindowController.xib │ ├── CustomModalWindowController.h │ ├── CustomModalWindowController.m │ ├── CustomModalWindowController.xib │ ├── MainWindowViewController.h │ ├── MainWindowViewController.m │ └── MainWindowViewController.xib │ ├── DSYMTools.entitlements │ ├── Info.plist │ ├── Model │ ├── ArchiveInfo.h │ ├── ArchiveInfo.m │ ├── UUIDInfo.h │ └── UUIDInfo.m │ ├── NSAttributedString+Hyperlink.h │ ├── NSAttributedString+Hyperlink.m │ ├── View │ ├── ArchiveFilesScrollView.h │ └── ArchiveFilesScrollView.m │ └── main.m ├── Pic ├── crashLog1.png └── crashLog2.png ├── README.md ├── Swift └── README.md └── wxPython ├── AHDropTarget.py ├── MyInfo.py ├── RunScript.py ├── about.png ├── app └── dSYM.app │ └── Contents │ ├── Frameworks │ ├── Python.framework │ │ ├── Python │ │ ├── Resources │ │ └── Versions │ │ │ ├── 2.7 │ │ │ ├── Python │ │ │ ├── Resources │ │ │ │ └── Info.plist │ │ │ └── include │ │ │ │ └── python2.7 │ │ │ │ └── pyconfig.h │ │ │ └── Current │ └── libwx_osx_cocoau-3.0.0.0.0.dylib │ ├── Info.plist │ ├── MacOS │ ├── dSYM │ └── python │ ├── PkgInfo │ └── Resources │ ├── RunScript.py │ ├── __boot__.py │ ├── __error__.sh │ ├── about.png │ ├── avatar.jpg │ ├── dSYM.py │ ├── dSYMIcns.icns │ ├── dsym.db │ ├── include │ └── python2.7 │ │ └── pyconfig.h │ └── lib │ └── python2.7 │ ├── lib-dynload │ ├── MacOS.so │ ├── Nav.so │ ├── _AE.so │ ├── _Ctl.so │ ├── _Dlg.so │ ├── _Evt.so │ ├── _File.so │ ├── _Menu.so │ ├── _Qd.so │ ├── _Res.so │ ├── _Win.so │ ├── _codecs_cn.so │ ├── _codecs_hk.so │ ├── _codecs_iso2022.so │ ├── _codecs_jp.so │ ├── _codecs_kr.so │ ├── _codecs_tw.so │ ├── _collections.so │ ├── _functools.so │ ├── _hashlib.so │ ├── _heapq.so │ ├── _io.so │ ├── _locale.so │ ├── _multibytecodec.so │ ├── _random.so │ ├── _scproxy.so │ ├── _socket.so │ ├── _sqlite3.so │ ├── _ssl.so │ ├── _struct.so │ ├── array.so │ ├── binascii.so │ ├── bz2.so │ ├── cPickle.so │ ├── cStringIO.so │ ├── datetime.so │ ├── fcntl.so │ ├── gestalt.so │ ├── grp.so │ ├── itertools.so │ ├── math.so │ ├── operator.so │ ├── parser.so │ ├── pyexpat.so │ ├── resource.so │ ├── select.so │ ├── strop.so │ ├── termios.so │ ├── time.so │ ├── unicodedata.so │ ├── wx │ │ ├── _controls_.so │ │ ├── _core_.so │ │ ├── _gdi_.so │ │ ├── _misc_.so │ │ └── _windows_.so │ └── zlib.so │ └── site-packages.zip ├── avatar.jpg ├── dSYM.py ├── dSYMIcns.icns ├── donate.png ├── dsym.db └── setup.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | build/ 3 | dist/ 4 | test*.py 5 | *.pyc 6 | *.psd 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 answer-huang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Objective-C/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/.DS_Store -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8057382A1D47C79000CEBA84 /* MainWindowViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 805738281D47C79000CEBA84 /* MainWindowViewController.m */; }; 11 | 8057382B1D47C79000CEBA84 /* MainWindowViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 805738291D47C79000CEBA84 /* MainWindowViewController.xib */; }; 12 | 8057382F1D486B4D00CEBA84 /* ArchiveInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8057382E1D486B4D00CEBA84 /* ArchiveInfo.m */; }; 13 | 805738321D4878F300CEBA84 /* UUIDInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 805738311D4878F300CEBA84 /* UUIDInfo.m */; }; 14 | 80817F2C1D45F4D500CD2A11 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 80817F2B1D45F4D500CD2A11 /* AppDelegate.m */; }; 15 | 80817F2F1D45F4D500CD2A11 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 80817F2E1D45F4D500CD2A11 /* main.m */; }; 16 | 80817F311D45F4D500CD2A11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 80817F301D45F4D500CD2A11 /* Assets.xcassets */; }; 17 | 80817F341D45F4D500CD2A11 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 80817F321D45F4D500CD2A11 /* MainMenu.xib */; }; 18 | 80A47DD31D4B343F00626266 /* ArchiveFilesScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 80A47DD21D4B343F00626266 /* ArchiveFilesScrollView.m */; }; 19 | 80B88CA31D476C5000B2B83D /* AboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 80B88CA11D476C5000B2B83D /* AboutWindowController.m */; }; 20 | 80B88CA41D476C5000B2B83D /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 80B88CA21D476C5000B2B83D /* AboutWindowController.xib */; }; 21 | 80D250631DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.m in Sources */ = {isa = PBXBuildFile; fileRef = 80D250621DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 805738271D47C79000CEBA84 /* MainWindowViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainWindowViewController.h; sourceTree = ""; }; 26 | 805738281D47C79000CEBA84 /* MainWindowViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainWindowViewController.m; sourceTree = ""; }; 27 | 805738291D47C79000CEBA84 /* MainWindowViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainWindowViewController.xib; sourceTree = ""; }; 28 | 8057382D1D486B4D00CEBA84 /* ArchiveInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveInfo.h; sourceTree = ""; }; 29 | 8057382E1D486B4D00CEBA84 /* ArchiveInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArchiveInfo.m; sourceTree = ""; }; 30 | 805738301D4878F300CEBA84 /* UUIDInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UUIDInfo.h; sourceTree = ""; }; 31 | 805738311D4878F300CEBA84 /* UUIDInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UUIDInfo.m; sourceTree = ""; }; 32 | 80817F271D45F4D500CD2A11 /* DSYMTools.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DSYMTools.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 80817F2A1D45F4D500CD2A11 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | 80817F2B1D45F4D500CD2A11 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | 80817F2E1D45F4D500CD2A11 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 36 | 80817F301D45F4D500CD2A11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 37 | 80817F331D45F4D500CD2A11 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 38 | 80817F351D45F4D500CD2A11 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 80817F3B1D45F77500CD2A11 /* DSYMTools.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = DSYMTools.entitlements; sourceTree = ""; }; 40 | 80A47DD11D4B343F00626266 /* ArchiveFilesScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveFilesScrollView.h; sourceTree = ""; }; 41 | 80A47DD21D4B343F00626266 /* ArchiveFilesScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArchiveFilesScrollView.m; sourceTree = ""; }; 42 | 80B88CA01D476C5000B2B83D /* AboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutWindowController.h; sourceTree = ""; }; 43 | 80B88CA11D476C5000B2B83D /* AboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutWindowController.m; sourceTree = ""; }; 44 | 80B88CA21D476C5000B2B83D /* AboutWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AboutWindowController.xib; sourceTree = ""; }; 45 | 80D250611DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+Hyperlink.h"; sourceTree = ""; }; 46 | 80D250621DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+Hyperlink.m"; sourceTree = ""; }; 47 | /* End PBXFileReference section */ 48 | 49 | /* Begin PBXFrameworksBuildPhase section */ 50 | 80817F241D45F4D500CD2A11 /* Frameworks */ = { 51 | isa = PBXFrameworksBuildPhase; 52 | buildActionMask = 2147483647; 53 | files = ( 54 | ); 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXFrameworksBuildPhase section */ 58 | 59 | /* Begin PBXGroup section */ 60 | 8057382C1D486AE900CEBA84 /* Model */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 8057382D1D486B4D00CEBA84 /* ArchiveInfo.h */, 64 | 8057382E1D486B4D00CEBA84 /* ArchiveInfo.m */, 65 | 805738301D4878F300CEBA84 /* UUIDInfo.h */, 66 | 805738311D4878F300CEBA84 /* UUIDInfo.m */, 67 | ); 68 | path = Model; 69 | sourceTree = ""; 70 | }; 71 | 80817F1E1D45F4D500CD2A11 = { 72 | isa = PBXGroup; 73 | children = ( 74 | 80817F291D45F4D500CD2A11 /* DSYMTools */, 75 | 80817F281D45F4D500CD2A11 /* Products */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | 80817F281D45F4D500CD2A11 /* Products */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 80817F271D45F4D500CD2A11 /* DSYMTools.app */, 83 | ); 84 | name = Products; 85 | sourceTree = ""; 86 | }; 87 | 80817F291D45F4D500CD2A11 /* DSYMTools */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 80A47DD01D4B340A00626266 /* View */, 91 | 8057382C1D486AE900CEBA84 /* Model */, 92 | 80B88C9A1D4767F700B2B83D /* Controller */, 93 | 80817F3B1D45F77500CD2A11 /* DSYMTools.entitlements */, 94 | 80817F2A1D45F4D500CD2A11 /* AppDelegate.h */, 95 | 80817F2B1D45F4D500CD2A11 /* AppDelegate.m */, 96 | 80817F301D45F4D500CD2A11 /* Assets.xcassets */, 97 | 80817F321D45F4D500CD2A11 /* MainMenu.xib */, 98 | 80817F351D45F4D500CD2A11 /* Info.plist */, 99 | 80817F2D1D45F4D500CD2A11 /* Supporting Files */, 100 | 80D250611DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.h */, 101 | 80D250621DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.m */, 102 | ); 103 | path = DSYMTools; 104 | sourceTree = ""; 105 | }; 106 | 80817F2D1D45F4D500CD2A11 /* Supporting Files */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 80817F2E1D45F4D500CD2A11 /* main.m */, 110 | ); 111 | name = "Supporting Files"; 112 | sourceTree = ""; 113 | }; 114 | 80A47DD01D4B340A00626266 /* View */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 80A47DD11D4B343F00626266 /* ArchiveFilesScrollView.h */, 118 | 80A47DD21D4B343F00626266 /* ArchiveFilesScrollView.m */, 119 | ); 120 | path = View; 121 | sourceTree = ""; 122 | }; 123 | 80B88C9A1D4767F700B2B83D /* Controller */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 805738271D47C79000CEBA84 /* MainWindowViewController.h */, 127 | 805738281D47C79000CEBA84 /* MainWindowViewController.m */, 128 | 805738291D47C79000CEBA84 /* MainWindowViewController.xib */, 129 | 80B88CA01D476C5000B2B83D /* AboutWindowController.h */, 130 | 80B88CA11D476C5000B2B83D /* AboutWindowController.m */, 131 | 80B88CA21D476C5000B2B83D /* AboutWindowController.xib */, 132 | ); 133 | path = Controller; 134 | sourceTree = ""; 135 | }; 136 | /* End PBXGroup section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | 80817F261D45F4D500CD2A11 /* DSYMTools */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = 80817F381D45F4D500CD2A11 /* Build configuration list for PBXNativeTarget "DSYMTools" */; 142 | buildPhases = ( 143 | 80817F231D45F4D500CD2A11 /* Sources */, 144 | 80817F241D45F4D500CD2A11 /* Frameworks */, 145 | 80817F251D45F4D500CD2A11 /* Resources */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | ); 151 | name = DSYMTools; 152 | productName = DSYMTools; 153 | productReference = 80817F271D45F4D500CD2A11 /* DSYMTools.app */; 154 | productType = "com.apple.product-type.application"; 155 | }; 156 | /* End PBXNativeTarget section */ 157 | 158 | /* Begin PBXProject section */ 159 | 80817F1F1D45F4D500CD2A11 /* Project object */ = { 160 | isa = PBXProject; 161 | attributes = { 162 | LastUpgradeCheck = 1130; 163 | ORGANIZATIONNAME = answer; 164 | TargetAttributes = { 165 | 80817F261D45F4D500CD2A11 = { 166 | CreatedOnToolsVersion = 7.3.1; 167 | SystemCapabilities = { 168 | com.apple.Sandbox = { 169 | enabled = 0; 170 | }; 171 | }; 172 | }; 173 | }; 174 | }; 175 | buildConfigurationList = 80817F221D45F4D500CD2A11 /* Build configuration list for PBXProject "DSYMTools" */; 176 | compatibilityVersion = "Xcode 3.2"; 177 | developmentRegion = en; 178 | hasScannedForEncodings = 0; 179 | knownRegions = ( 180 | en, 181 | Base, 182 | ); 183 | mainGroup = 80817F1E1D45F4D500CD2A11; 184 | productRefGroup = 80817F281D45F4D500CD2A11 /* Products */; 185 | projectDirPath = ""; 186 | projectRoot = ""; 187 | targets = ( 188 | 80817F261D45F4D500CD2A11 /* DSYMTools */, 189 | ); 190 | }; 191 | /* End PBXProject section */ 192 | 193 | /* Begin PBXResourcesBuildPhase section */ 194 | 80817F251D45F4D500CD2A11 /* Resources */ = { 195 | isa = PBXResourcesBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | 80B88CA41D476C5000B2B83D /* AboutWindowController.xib in Resources */, 199 | 80817F311D45F4D500CD2A11 /* Assets.xcassets in Resources */, 200 | 80817F341D45F4D500CD2A11 /* MainMenu.xib in Resources */, 201 | 8057382B1D47C79000CEBA84 /* MainWindowViewController.xib in Resources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | /* End PBXResourcesBuildPhase section */ 206 | 207 | /* Begin PBXSourcesBuildPhase section */ 208 | 80817F231D45F4D500CD2A11 /* Sources */ = { 209 | isa = PBXSourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | 80B88CA31D476C5000B2B83D /* AboutWindowController.m in Sources */, 213 | 80A47DD31D4B343F00626266 /* ArchiveFilesScrollView.m in Sources */, 214 | 80D250631DD1C5A8009D7EEC /* NSAttributedString+Hyperlink.m in Sources */, 215 | 80817F2F1D45F4D500CD2A11 /* main.m in Sources */, 216 | 805738321D4878F300CEBA84 /* UUIDInfo.m in Sources */, 217 | 8057382F1D486B4D00CEBA84 /* ArchiveInfo.m in Sources */, 218 | 80817F2C1D45F4D500CD2A11 /* AppDelegate.m in Sources */, 219 | 8057382A1D47C79000CEBA84 /* MainWindowViewController.m in Sources */, 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | }; 223 | /* End PBXSourcesBuildPhase section */ 224 | 225 | /* Begin PBXVariantGroup section */ 226 | 80817F321D45F4D500CD2A11 /* MainMenu.xib */ = { 227 | isa = PBXVariantGroup; 228 | children = ( 229 | 80817F331D45F4D500CD2A11 /* Base */, 230 | ); 231 | name = MainMenu.xib; 232 | sourceTree = ""; 233 | }; 234 | /* End PBXVariantGroup section */ 235 | 236 | /* Begin XCBuildConfiguration section */ 237 | 80817F361D45F4D500CD2A11 /* Debug */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 242 | CLANG_ANALYZER_NONNULL = YES; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_MODULES = YES; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 248 | CLANG_WARN_BOOL_CONVERSION = YES; 249 | CLANG_WARN_COMMA = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 253 | CLANG_WARN_EMPTY_BODY = YES; 254 | CLANG_WARN_ENUM_CONVERSION = YES; 255 | CLANG_WARN_INFINITE_RECURSION = YES; 256 | CLANG_WARN_INT_CONVERSION = YES; 257 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 258 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 259 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 260 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 261 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 262 | CLANG_WARN_STRICT_PROTOTYPES = YES; 263 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 264 | CLANG_WARN_UNREACHABLE_CODE = YES; 265 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 266 | CODE_SIGN_IDENTITY = "-"; 267 | COPY_PHASE_STRIP = NO; 268 | DEBUG_INFORMATION_FORMAT = dwarf; 269 | ENABLE_STRICT_OBJC_MSGSEND = YES; 270 | ENABLE_TESTABILITY = YES; 271 | GCC_C_LANGUAGE_STANDARD = gnu99; 272 | GCC_DYNAMIC_NO_PIC = NO; 273 | GCC_NO_COMMON_BLOCKS = YES; 274 | GCC_OPTIMIZATION_LEVEL = 0; 275 | GCC_PREPROCESSOR_DEFINITIONS = ( 276 | "DEBUG=1", 277 | "$(inherited)", 278 | ); 279 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 280 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 281 | GCC_WARN_UNDECLARED_SELECTOR = YES; 282 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 283 | GCC_WARN_UNUSED_FUNCTION = YES; 284 | GCC_WARN_UNUSED_VARIABLE = YES; 285 | MACOSX_DEPLOYMENT_TARGET = 10.11; 286 | MTL_ENABLE_DEBUG_INFO = YES; 287 | ONLY_ACTIVE_ARCH = YES; 288 | SDKROOT = macosx; 289 | }; 290 | name = Debug; 291 | }; 292 | 80817F371D45F4D500CD2A11 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | ALWAYS_SEARCH_USER_PATHS = NO; 296 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 297 | CLANG_ANALYZER_NONNULL = YES; 298 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 299 | CLANG_CXX_LIBRARY = "libc++"; 300 | CLANG_ENABLE_MODULES = YES; 301 | CLANG_ENABLE_OBJC_ARC = YES; 302 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 303 | CLANG_WARN_BOOL_CONVERSION = YES; 304 | CLANG_WARN_COMMA = YES; 305 | CLANG_WARN_CONSTANT_CONVERSION = YES; 306 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 307 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 308 | CLANG_WARN_EMPTY_BODY = YES; 309 | CLANG_WARN_ENUM_CONVERSION = YES; 310 | CLANG_WARN_INFINITE_RECURSION = YES; 311 | CLANG_WARN_INT_CONVERSION = YES; 312 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 313 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 314 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 315 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 316 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 317 | CLANG_WARN_STRICT_PROTOTYPES = YES; 318 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 319 | CLANG_WARN_UNREACHABLE_CODE = YES; 320 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 321 | CODE_SIGN_IDENTITY = "-"; 322 | COPY_PHASE_STRIP = NO; 323 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 324 | ENABLE_NS_ASSERTIONS = NO; 325 | ENABLE_STRICT_OBJC_MSGSEND = YES; 326 | GCC_C_LANGUAGE_STANDARD = gnu99; 327 | GCC_NO_COMMON_BLOCKS = YES; 328 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 329 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 330 | GCC_WARN_UNDECLARED_SELECTOR = YES; 331 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 332 | GCC_WARN_UNUSED_FUNCTION = YES; 333 | GCC_WARN_UNUSED_VARIABLE = YES; 334 | MACOSX_DEPLOYMENT_TARGET = 10.11; 335 | MTL_ENABLE_DEBUG_INFO = NO; 336 | SDKROOT = macosx; 337 | }; 338 | name = Release; 339 | }; 340 | 80817F391D45F4D500CD2A11 /* Debug */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 344 | CODE_SIGN_IDENTITY = "-"; 345 | COMBINE_HIDPI_IMAGES = YES; 346 | INFOPLIST_FILE = DSYMTools/Info.plist; 347 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 348 | PRODUCT_BUNDLE_IDENTIFIER = com.eku001.DSYMTools; 349 | PRODUCT_NAME = "$(TARGET_NAME)"; 350 | }; 351 | name = Debug; 352 | }; 353 | 80817F3A1D45F4D500CD2A11 /* Release */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | CODE_SIGN_IDENTITY = "-"; 358 | COMBINE_HIDPI_IMAGES = YES; 359 | INFOPLIST_FILE = DSYMTools/Info.plist; 360 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 361 | PRODUCT_BUNDLE_IDENTIFIER = com.eku001.DSYMTools; 362 | PRODUCT_NAME = "$(TARGET_NAME)"; 363 | }; 364 | name = Release; 365 | }; 366 | /* End XCBuildConfiguration section */ 367 | 368 | /* Begin XCConfigurationList section */ 369 | 80817F221D45F4D500CD2A11 /* Build configuration list for PBXProject "DSYMTools" */ = { 370 | isa = XCConfigurationList; 371 | buildConfigurations = ( 372 | 80817F361D45F4D500CD2A11 /* Debug */, 373 | 80817F371D45F4D500CD2A11 /* Release */, 374 | ); 375 | defaultConfigurationIsVisible = 0; 376 | defaultConfigurationName = Release; 377 | }; 378 | 80817F381D45F4D500CD2A11 /* Build configuration list for PBXNativeTarget "DSYMTools" */ = { 379 | isa = XCConfigurationList; 380 | buildConfigurations = ( 381 | 80817F391D45F4D500CD2A11 /* Debug */, 382 | 80817F3A1D45F4D500CD2A11 /* Release */, 383 | ); 384 | defaultConfigurationIsVisible = 0; 385 | defaultConfigurationName = Release; 386 | }; 387 | /* End XCConfigurationList section */ 388 | }; 389 | rootObject = 80817F1F1D45F4D500CD2A11 /* Project object */; 390 | } 391 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/Don.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/Don.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/answer.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/answer.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/answer.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/liunianhuaguoyanxi.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools.xcodeproj/project.xcworkspace/xcuserdata/liunianhuaguoyanxi.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/xcuserdata/answer.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/xcuserdata/answer.xcuserdatad/xcschemes/DSYMTools.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 78 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/xcuserdata/answer.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DSYMTools.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 80817F261D45F4D500CD2A11 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/xcuserdata/liunianhuaguoyanxi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 22 | 23 | 24 | 26 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools.xcodeproj/xcuserdata/liunianhuaguoyanxi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DSYMTools.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/25/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/25/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MainWindowViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | 15 | @property (strong) MainWindowViewController *mainWindowViewController; 16 | 17 | @end 18 | 19 | @implementation AppDelegate 20 | 21 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 22 | // Insert code here to initialize your application 23 | self.mainWindowViewController = [[MainWindowViewController alloc] initWithWindowNibName:@"MainWindowViewController"]; 24 | [self.mainWindowViewController showWindow:self]; 25 | } 26 | 27 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 28 | // Insert code here to tear down your application 29 | } 30 | 31 | /** 32 | * 关闭最后一个 window 的时候关闭应用 33 | * 34 | * @param sender 35 | * 36 | * @return 37 | */ 38 | //- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender{ 39 | // return YES; 40 | //} 41 | 42 | /** 43 | * 监听窗口关闭的通知,关闭程序。 44 | * 45 | * @param notification 46 | */ 47 | //- (void) receiveWindowWillCloseMsg:(NSNotification *)notification{ 48 | // NSWindow *window = notification.object; 49 | // if(window == self.window){ 50 | // [NSApp terminate:self]; 51 | // } 52 | //} 53 | 54 | //- (IBAction)openFilePanel:(id)sender { 55 | // NSOpenPanel *openDlg = [NSOpenPanel openPanel]; 56 | // openDlg.canChooseFiles = YES; 57 | // openDlg.canChooseDirectories = YES; 58 | // openDlg.allowsMultipleSelection = YES; 59 | // openDlg.allowedFileTypes = @[@"txt"]; 60 | // [openDlg beginWithCompletionHandler:^(NSInteger result) { 61 | // if (result == NSFileHandlingPanelOKButton) { 62 | // NSArray *fileURLs = [openDlg URLs]; 63 | // for (NSURL *url in fileURLs) { 64 | // NSError *error; 65 | // NSString *string = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; 66 | // if (!error) { 67 | // self.textView.string = string; 68 | // } 69 | // } 70 | // } 71 | // }]; 72 | // 73 | //} 74 | // 75 | //- (IBAction)saveFileAction:(id)sender { 76 | // NSSavePanel *saveDlg = [[NSSavePanel alloc]init]; 77 | // saveDlg.title = @"Save File"; 78 | // saveDlg.message = @"Save My File"; 79 | // saveDlg.allowedFileTypes = @[@"txt"]; 80 | // saveDlg.nameFieldStringValue = @"my"; 81 | // [saveDlg beginWithCompletionHandler: ^(NSInteger result){ 82 | // if(result==NSFileHandlingPanelOKButton){ 83 | // NSURL *url =[saveDlg URL]; 84 | // NSLog(@"filePath url%@",url); 85 | // NSString *text = self.textView.string; 86 | // NSError *error; 87 | // [text writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:&error]; 88 | // if(error){ 89 | // NSLog(@"save file error %@",error); 90 | // } 91 | // } 92 | // }]; 93 | //} 94 | 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon32-1.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon256-1.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon512-1.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon1024.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon128.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon16.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon256-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon256-1.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon256.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon32-1.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon32.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon512-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon512-1.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon512.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/AppIcon.appiconset/icon64.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/about.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "about.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/about.imageset/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/about.imageset/about.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/avatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "avatar.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/avatar.imageset/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/avatar.imageset/avatar.jpg -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/export.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "export.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Assets.xcassets/export.imageset/export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Objective-C/DSYMTools/Assets.xcassets/export.imageset/export.png -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/AboutWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AboutWindowController.h 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/26/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AboutWindowController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/AboutWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AboutWindowController.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/26/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import "AboutWindowController.h" 10 | #import "NSAttributedString+Hyperlink.h" 11 | 12 | @interface AboutWindowController () 13 | @property (weak) IBOutlet NSTextField *blog; 14 | 15 | @property (weak) IBOutlet NSTextField *weibo; 16 | @property (weak) IBOutlet NSTextField *gitHub; 17 | @end 18 | 19 | @implementation AboutWindowController 20 | 21 | - (void)windowDidLoad { 22 | [super windowDidLoad]; 23 | 24 | [self.weibo setAllowsEditingTextAttributes:YES]; 25 | [self.weibo setSelectable:YES]; 26 | 27 | [self.blog setAllowsEditingTextAttributes:YES]; 28 | [self.blog setSelectable:YES]; 29 | 30 | [self.gitHub setAllowsEditingTextAttributes:YES]; 31 | [self.gitHub setSelectable:YES]; 32 | 33 | 34 | NSURL* url1 = [NSURL URLWithString:@"http://weibo.com/u/1623064627"]; 35 | NSMutableAttributedString* string1 = [[NSMutableAttributedString alloc] init]; 36 | [string1 appendAttributedString: [NSAttributedString hyperlinkFromString:@"answer-huang" withURL:url1]]; 37 | [self.weibo setAttributedStringValue: string1]; 38 | 39 | NSURL* url2 = [NSURL URLWithString:@"http://answerhuang.duapp.com"]; 40 | NSMutableAttributedString* string2 = [[NSMutableAttributedString alloc] init]; 41 | [string2 appendAttributedString: [NSAttributedString hyperlinkFromString:@"answerhuang.duapp.com" withURL:url2]]; 42 | [self.blog setAttributedStringValue: string2]; 43 | 44 | NSURL* url3 = [NSURL URLWithString:@"https://github.com/answer-huang/dSYMTools"]; 45 | NSMutableAttributedString* string3 = [[NSMutableAttributedString alloc] init]; 46 | [string3 appendAttributedString: [NSAttributedString hyperlinkFromString:@"dSYMTools" withURL:url3]]; 47 | [self.gitHub setAttributedStringValue: string3]; 48 | } 49 | - (IBAction)close:(id)sender { 50 | [self.window.sheetParent endSheet:self.window returnCode:NSModalResponseOK]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/AboutWindowController.xib: -------------------------------------------------------------------------------- 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 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 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 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/CustomModalWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomModalWindowViewController.h 3 | // CustomModalWindow 4 | // 5 | // Created by Nick Kuh on 16/01/2015. 6 | // Copyright (c) 2015 Mumbo Apps Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CustomModalWindowController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/CustomModalWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomModalWindowViewController.m 3 | // CustomModalWindow 4 | // 5 | // Created by Nick Kuh on 16/01/2015. 6 | // Copyright (c) 2015 Mumbo Apps Ltd. All rights reserved. 7 | // 8 | 9 | #import "CustomModalWindowController.h" 10 | 11 | @interface CustomModalWindowController () 12 | @property (weak) IBOutlet NSTextField *label1; 13 | 14 | @end 15 | 16 | @implementation CustomModalWindowController 17 | 18 | - (void)windowDidLoad { 19 | [super windowDidLoad]; 20 | 21 | 22 | } 23 | 24 | - (IBAction)didTapCancelButton:(id)sender { 25 | [self.window.sheetParent endSheet:self.window returnCode:NSModalResponseCancel]; 26 | } 27 | 28 | - (IBAction)didTapDoneButton:(id)sender { 29 | [self.window.sheetParent endSheet:self.window returnCode:NSModalResponseOK]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/CustomModalWindowController.xib: -------------------------------------------------------------------------------- 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 | 38 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/MainWindowViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainWindowViewController.h 3 | // CustomModalWindow 4 | // 5 | // Created by answer on 7/26/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MainWindowViewController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/MainWindowViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainWindowViewController.m 3 | // CustomModalWindow 4 | // 5 | // Created by answer on 7/26/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import "MainWindowViewController.h" 10 | #import "AboutWindowController.h" 11 | #import "ArchiveInfo.h" 12 | #import "UUIDInfo.h" 13 | #import "ArchiveFilesScrollView.h" 14 | 15 | 16 | @interface MainWindowViewController () 17 | 18 | 19 | @property (strong) AboutWindowController *aboutWindowController; 20 | 21 | /** 22 | * 显示 archive 文件的 tableView 23 | */ 24 | @property (weak) IBOutlet NSTableView *archiveFilesTableView; 25 | 26 | /** 27 | * 存放 radio 的 box 28 | */ 29 | @property (weak) IBOutlet NSBox *radioBox; 30 | 31 | /** 32 | * archive 文件信息数组 33 | */ 34 | @property (copy) NSMutableArray *archiveFilesInfo; 35 | 36 | /** 37 | * 选中的 archive 文件信息 38 | */ 39 | @property (strong) ArchiveInfo *selectedArchiveInfo; 40 | 41 | /** 42 | * 选中的 UUID 信息 43 | */ 44 | @property (strong) UUIDInfo *selectedUUIDInfo; 45 | 46 | /** 47 | * 显示选中的 CPU 类型对应可执行文件的 UUID 48 | */ 49 | @property (weak) IBOutlet NSTextField *selectedUUIDLabel; 50 | 51 | /** 52 | * 显示默认的 Slide Address 53 | */ 54 | @property (weak) IBOutlet NSTextField *defaultSlideAddressLabel; 55 | 56 | /** 57 | * 显示错误内存地址 58 | */ 59 | @property (weak) IBOutlet NSTextField *errorMemoryAddressLabel; 60 | 61 | /** 62 | * 错误信息 63 | */ 64 | @property (unsafe_unretained) IBOutlet NSTextView *errorMessageView; 65 | 66 | @property (weak) IBOutlet NSTextField *errorTextField; 67 | 68 | 69 | @property (weak) IBOutlet ArchiveFilesScrollView *archiveFilesScrollView; 70 | 71 | @end 72 | 73 | @implementation MainWindowViewController 74 | 75 | 76 | - (void)windowDidLoad{ 77 | [super windowDidLoad]; 78 | 79 | [self.window registerForDraggedTypes:@[NSColorPboardType, NSFilenamesPboardType]]; 80 | 81 | self.archiveFilesTableView.doubleAction = @selector(doubleActionMethod); 82 | 83 | NSArray *archiveFilePaths = [self allDSYMFilePath]; 84 | [self handleArchiveFileWithPath:archiveFilePaths]; 85 | } 86 | 87 | /** 88 | * 处理给定archive文件路径,获取 archiveinfo 对象 89 | * 90 | * @param filePaths archvie 文件路径 91 | */ 92 | - (void)handleArchiveFileWithPath:(NSArray *)filePaths { 93 | _archiveFilesInfo = [NSMutableArray arrayWithCapacity:1]; 94 | for(NSString *filePath in filePaths){ 95 | ArchiveInfo *archiveInfo = [[ArchiveInfo alloc] init]; 96 | 97 | NSString *fileName = filePath.lastPathComponent; 98 | //支持 xcarchive 文件和 dSYM 文件。 99 | if ([fileName hasSuffix:@".xcarchive"]){ 100 | archiveInfo.archiveFilePath = filePath; 101 | archiveInfo.archiveFileName = fileName; 102 | archiveInfo.archiveFileType = ArchiveFileTypeXCARCHIVE; 103 | [self formatArchiveInfo:archiveInfo]; 104 | }else if([fileName hasSuffix:@".app.dSYM"]){ 105 | archiveInfo.dSYMFilePath = filePath; 106 | archiveInfo.dSYMFileName = fileName; 107 | archiveInfo.archiveFileType = ArchiveFileTypeDSYM; 108 | [self formatDSYM:archiveInfo]; 109 | }else{ 110 | continue; 111 | } 112 | 113 | [_archiveFilesInfo addObject:archiveInfo]; 114 | } 115 | 116 | [self.archiveFilesTableView reloadData]; 117 | } 118 | 119 | /** 120 | * 从 archive 文件中获取 dsym 文件信息 121 | * 122 | * @param archiveInfo archive info 对象 123 | */ 124 | - (void)formatArchiveInfo:(ArchiveInfo *)archiveInfo{ 125 | NSString *dSYMsDirectoryPath = [NSString stringWithFormat:@"%@/dSYMs", archiveInfo.archiveFilePath]; 126 | NSArray *keys = @[@"NSURLPathKey",@"NSURLFileResourceTypeKey",@"NSURLIsDirectoryKey",@"NSURLIsPackageKey"]; 127 | NSArray *dSYMSubFiles= [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:dSYMsDirectoryPath] includingPropertiesForKeys:keys options:(NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsPackageDescendants) error:nil]; 128 | for(NSURL *fileURLs in dSYMSubFiles){ 129 | if ([[fileURLs.relativePath lastPathComponent] hasSuffix:@"app.dSYM"]){ 130 | archiveInfo.dSYMFilePath = fileURLs.relativePath; 131 | archiveInfo.dSYMFileName = fileURLs.relativePath.lastPathComponent; 132 | } 133 | } 134 | [self formatDSYM:archiveInfo]; 135 | 136 | } 137 | 138 | /** 139 | * 根据 dSYM 文件获取 UUIDS。 140 | * @param archiveInfo 141 | */ 142 | - (void)formatDSYM:(ArchiveInfo *)archiveInfo{ 143 | //匹配 () 里面内容 144 | NSString *pattern = @"(?<=\\()[^}]*(?=\\))"; 145 | NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil]; 146 | NSString *commandString = [NSString stringWithFormat:@"dwarfdump --uuid \"%@\"",archiveInfo.dSYMFilePath]; 147 | NSString *uuidsString = [self runCommand:commandString]; 148 | NSArray *uuids = [uuidsString componentsSeparatedByString:@"\n"]; 149 | 150 | NSMutableArray *uuidInfos = [NSMutableArray arrayWithCapacity:1]; 151 | for(NSString *uuidString in uuids){ 152 | NSArray* match = [reg matchesInString:uuidString options:NSMatchingReportCompletion range:NSMakeRange(0, [uuidString length])]; 153 | if (match.count == 0) { 154 | continue; 155 | } 156 | for (NSTextCheckingResult *result in match) { 157 | NSRange range = [result range]; 158 | UUIDInfo *uuidInfo = [[UUIDInfo alloc] init]; 159 | uuidInfo.arch = [uuidString substringWithRange:range]; 160 | uuidInfo.uuid = [uuidString substringWithRange:NSMakeRange(6, range.location-6-2)]; 161 | uuidInfo.executableFilePath = [uuidString substringWithRange:NSMakeRange(range.location+range.length+2, [uuidString length]-(range.location+range.length+2))]; 162 | [uuidInfos addObject:uuidInfo]; 163 | } 164 | archiveInfo.uuidInfos = uuidInfos; 165 | } 166 | } 167 | 168 | /** 169 | * 获取所有 dSYM 文件目录. 170 | */ 171 | - (NSMutableArray *)allDSYMFilePath { 172 | NSFileManager *fileManager = [NSFileManager defaultManager]; 173 | 174 | NSString *archivesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Developer/Xcode/Archives/"]; 175 | NSURL *bundleURL = [NSURL fileURLWithPath:archivesPath]; 176 | NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:bundleURL 177 | includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey] 178 | options:NSDirectoryEnumerationSkipsHiddenFiles 179 | errorHandler:^BOOL(NSURL *url, NSError *error) 180 | { 181 | if (error) { 182 | NSLog(@"[Error] %@ (%@)", error, url); 183 | return NO; 184 | } 185 | 186 | return YES; 187 | }]; 188 | 189 | NSMutableArray *mutableFileURLs = [NSMutableArray array]; 190 | for (NSURL *fileURL in enumerator) { 191 | NSString *filename; 192 | [fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil]; 193 | 194 | NSNumber *isDirectory; 195 | [fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; 196 | 197 | if ([filename hasPrefix:@"_"] && [isDirectory boolValue]) { 198 | [enumerator skipDescendants]; 199 | continue; 200 | } 201 | 202 | //TODO:过滤部分没必要遍历的目录 203 | 204 | if ([filename hasSuffix:@".xcarchive"] && [isDirectory boolValue]){ 205 | [mutableFileURLs addObject:fileURL.relativePath]; 206 | [enumerator skipDescendants]; 207 | } 208 | } 209 | return mutableFileURLs; 210 | } 211 | 212 | - (NSString *)runCommand:(NSString *)commandToRun 213 | { 214 | NSTask *task = [[NSTask alloc] init]; 215 | [task setLaunchPath:@"/bin/sh"]; 216 | 217 | NSArray *arguments = @[@"-c", 218 | [NSString stringWithFormat:@"%@", commandToRun]]; 219 | // NSLog(@"run command:%@", commandToRun); 220 | [task setArguments:arguments]; 221 | 222 | NSPipe *pipe = [NSPipe pipe]; 223 | [task setStandardOutput:pipe]; 224 | 225 | NSFileHandle *file = [pipe fileHandleForReading]; 226 | 227 | [task launch]; 228 | 229 | NSData *data = [file readDataToEndOfFile]; 230 | 231 | NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 232 | return output; 233 | } 234 | 235 | 236 | /** 237 | * 导出 ipa 文件 238 | xcodebuild -exportArchive -exportFormat ipa -archivePath "/path/to/archiveFile" -exportPath "/path/to/ipaFile" 239 | */ 240 | - (IBAction)exportIPA:(id)sender { 241 | if(!_selectedArchiveInfo){ 242 | NSLog(@"还未选中 archive 文件"); 243 | return; 244 | } 245 | 246 | if(_selectedArchiveInfo.archiveFileType == ArchiveFileTypeDSYM){ 247 | NSLog(@"archive 文件才可导出 ipa 文件"); 248 | return; 249 | } 250 | 251 | 252 | NSString *ipaFileName = [_selectedArchiveInfo.archiveFileName stringByReplacingOccurrencesOfString:@"xcarchive" withString:@"ipa"]; 253 | 254 | NSSavePanel *saveDlg = [[NSSavePanel alloc]init]; 255 | saveDlg.title = ipaFileName; 256 | saveDlg.message = @"Save My File"; 257 | saveDlg.allowedFileTypes = @[@"ipa"]; 258 | saveDlg.nameFieldStringValue = ipaFileName; 259 | [saveDlg beginWithCompletionHandler: ^(NSInteger result){ 260 | if(result == NSFileHandlingPanelOKButton){ 261 | NSURL *url =[saveDlg URL]; 262 | NSLog(@"filePath url%@",url); 263 | NSString *exportCmd = [NSString stringWithFormat:@"/usr/bin/xcodebuild -exportArchive -exportFormat ipa -archivePath \"%@\" -exportPath \"%@\"", _selectedArchiveInfo.archiveFilePath, url.relativePath]; 264 | [self runCommand:exportCmd]; 265 | } 266 | }]; 267 | } 268 | 269 | 270 | - (IBAction)aboutMe:(id)sender { 271 | self.aboutWindowController = [[AboutWindowController alloc] initWithWindowNibName:@"AboutWindowController"]; 272 | [self.window beginSheet:self.aboutWindowController.window completionHandler:^(NSModalResponse returnCode) { 273 | switch (returnCode) { 274 | case NSModalResponseOK: 275 | NSLog(@"Done button tapped in Custom Sheet"); 276 | break; 277 | case NSModalResponseCancel: 278 | NSLog(@"Cancel button tapped in Custom Sheet"); 279 | break; 280 | 281 | default: 282 | break; 283 | } 284 | self.aboutWindowController = nil; 285 | }]; 286 | } 287 | 288 | #pragma mark - NSTableViewDataSources 289 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{ 290 | return [_archiveFilesInfo count]; 291 | } 292 | 293 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ 294 | ArchiveInfo *archiveInfo= _archiveFilesInfo[row]; 295 | if(archiveInfo.archiveFileType == ArchiveFileTypeXCARCHIVE){ 296 | return archiveInfo.archiveFileName; 297 | }else if(archiveInfo.archiveFileType == ArchiveFileTypeDSYM){ 298 | return archiveInfo.dSYMFileName; 299 | } 300 | return archiveInfo.archiveFileName; 301 | } 302 | 303 | - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ 304 | 305 | ArchiveInfo *archiveInfo= _archiveFilesInfo[row]; 306 | NSString *identifier = tableColumn.identifier; 307 | NSView *view = [tableView makeViewWithIdentifier:identifier owner:self]; 308 | NSArray *subviews = view.subviews; 309 | if (subviews.count > 0) { 310 | if ([identifier isEqualToString:@"name"]) { 311 | NSTextField *textField = subviews[0]; 312 | if(archiveInfo.archiveFileType == ArchiveFileTypeXCARCHIVE){ 313 | textField.stringValue = archiveInfo.archiveFileName; 314 | }else if(archiveInfo.archiveFileType == ArchiveFileTypeDSYM){ 315 | textField.stringValue = archiveInfo.dSYMFileName; 316 | } 317 | } 318 | } 319 | return view; 320 | } 321 | 322 | - (void)tableViewSelectionDidChange:(NSNotification *)notification{ 323 | NSInteger row = [notification.object selectedRow]; 324 | _selectedArchiveInfo= _archiveFilesInfo[row]; 325 | [self resetPreInformation]; 326 | 327 | CGFloat radioButtonWidth = CGRectGetWidth(self.radioBox.contentView.frame); 328 | CGFloat radioButtonHeight = 18; 329 | [_selectedArchiveInfo.uuidInfos enumerateObjectsUsingBlock:^(UUIDInfo *uuidInfo, NSUInteger idx, BOOL *stop) { 330 | CGFloat space = (CGRectGetHeight(self.radioBox.contentView.frame) - _selectedArchiveInfo.uuidInfos.count * radioButtonHeight) / (_selectedArchiveInfo.uuidInfos.count + 1); 331 | CGFloat y = space * (idx + 1) + idx * radioButtonHeight; 332 | NSButton *radioButton = [[NSButton alloc] initWithFrame:NSMakeRect(10,y,radioButtonWidth,radioButtonHeight)]; 333 | [radioButton setButtonType:NSRadioButton]; 334 | [radioButton setTitle:uuidInfo.arch]; 335 | radioButton.tag = idx + 1; 336 | [radioButton setAction:@selector(radioButtonAction:)]; 337 | [self.radioBox.contentView addSubview:radioButton]; 338 | }]; 339 | } 340 | 341 | /** 342 | * 重置之前显示的信息 343 | */ 344 | - (void)resetPreInformation { 345 | [self.radioBox.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 346 | _selectedUUIDInfo = nil; 347 | self.selectedUUIDLabel.stringValue = @""; 348 | self.defaultSlideAddressLabel.stringValue = @""; 349 | self.errorMemoryAddressLabel.stringValue = @""; 350 | [self.errorMessageView setString:@""]; 351 | } 352 | 353 | - (void)radioButtonAction:(id)sender{ 354 | NSButton *radioButton = sender; 355 | NSInteger tag = radioButton.tag; 356 | _selectedUUIDInfo = _selectedArchiveInfo.uuidInfos[tag - 1]; 357 | _selectedUUIDLabel.stringValue = _selectedUUIDInfo.uuid; 358 | _defaultSlideAddressLabel.stringValue = _selectedUUIDInfo.defaultSlideAddress; 359 | } 360 | 361 | - (void)doubleActionMethod{ 362 | NSLog(@"double action"); 363 | } 364 | 365 | - (IBAction)analyse:(id)sender { 366 | if(self.selectedArchiveInfo == nil){ 367 | return; 368 | } 369 | 370 | if(self.selectedUUIDInfo == nil){ 371 | return; 372 | } 373 | 374 | if([self.defaultSlideAddressLabel.stringValue isEqualToString:@""]){ 375 | return; 376 | } 377 | 378 | if([self.errorMemoryAddressLabel.stringValue isEqualToString:@""]){ 379 | return; 380 | } 381 | NSString *result = @""; 382 | NSString *slidValueStr = self.defaultSlideAddressLabel.stringValue; 383 | if (slidValueStr.length > 0) { 384 | if (![slidValueStr hasPrefix:@"0x"] && ![slidValueStr hasPrefix:@"0X"]) { 385 | NSString *memoryAddressToTen = [self sixtyToTen:self.errorMemoryAddressLabel.stringValue]; 386 | NSInteger memoryAddressTenInt = memoryAddressToTen.integerValue; 387 | 388 | NSInteger slideAddressTenInt = memoryAddressTenInt - slidValueStr.integerValue; 389 | NSString *slideAddressSixTyStr = [self tenToSixTy:slideAddressTenInt]; 390 | 391 | NSString *commandString = [NSString stringWithFormat:@"xcrun atos -arch %@ -o \"%@\" -l %@ %@", self.selectedUUIDInfo.arch, self.selectedUUIDInfo.executableFilePath, slideAddressSixTyStr, self.errorMemoryAddressLabel.stringValue]; 392 | result = [self runCommand:commandString]; 393 | 394 | }else{ 395 | NSString *memoryAddressToTen = [self sixtyToTen:self.errorMemoryAddressLabel.stringValue]; 396 | NSInteger memoryAddressTenInt = memoryAddressToTen.integerValue + self.errorTextField.stringValue.integerValue; 397 | NSString *slideAddressSixTyStr = [self tenToSixTy:memoryAddressTenInt]; 398 | 399 | NSString *commandString = [NSString stringWithFormat:@"xcrun atos -arch %@ -o \"%@\" -l %@ %@", self.selectedUUIDInfo.arch, self.selectedUUIDInfo.executableFilePath, self.defaultSlideAddressLabel.stringValue, slideAddressSixTyStr]; 400 | result = [self runCommand:commandString]; 401 | } 402 | } 403 | [self.errorMessageView setString:result]; 404 | } 405 | 406 | 407 | 408 | 409 | //将十进制转化为十六进制 410 | -(NSString *)tenToSixTy:(long long int)tmpid 411 | { 412 | NSString *nLetterValue; 413 | NSString *str =@""; 414 | long long int ttmpig; 415 | for (int i = 0; i<9; i++) { 416 | ttmpig=tmpid%16; 417 | tmpid=tmpid/16; 418 | switch (ttmpig) 419 | { 420 | case 10: 421 | nLetterValue =@"A";break; 422 | case 11: 423 | nLetterValue =@"B";break; 424 | case 12: 425 | nLetterValue =@"C";break; 426 | case 13: 427 | nLetterValue =@"D";break; 428 | case 14: 429 | nLetterValue =@"E";break; 430 | case 15: 431 | nLetterValue =@"F";break; 432 | default:nLetterValue=[[NSString alloc]initWithFormat:@"%lli",ttmpig]; 433 | 434 | } 435 | str = [nLetterValue stringByAppendingString:str]; 436 | if (tmpid == 0) { 437 | break; 438 | } 439 | 440 | } 441 | return str; 442 | } 443 | //十六进制->十进制 444 | -(NSString *)sixtyToTen:(NSString *)sixTyStr{ 445 | NSString *temp10 = [NSString stringWithFormat:@"%lu",strtoul([sixTyStr UTF8String],0,16)]; 446 | return temp10; 447 | } 448 | 449 | 450 | 451 | - (NSDragOperation)draggingEntered:(id )sender{ 452 | 453 | NSPasteboard *pboard; 454 | NSDragOperation sourceDragMask; 455 | 456 | sourceDragMask = [sender draggingSourceOperationMask]; 457 | pboard = [sender draggingPasteboard]; 458 | 459 | if ( [[pboard types] containsObject:NSColorPboardType] ) { 460 | if (sourceDragMask & NSDragOperationGeneric) { 461 | return NSDragOperationGeneric; 462 | } 463 | } 464 | if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { 465 | if (sourceDragMask & NSDragOperationLink) { 466 | return NSDragOperationLink; 467 | } else if (sourceDragMask & NSDragOperationCopy) { 468 | return NSDragOperationCopy; 469 | } 470 | } 471 | return NSDragOperationNone; 472 | } 473 | 474 | - (void)draggingExited:(id)sender{ 475 | 476 | } 477 | 478 | - (BOOL)performDragOperation:(id )sender 479 | { 480 | NSPasteboard *pboard = [sender draggingPasteboard]; 481 | 482 | if ([[pboard types] containsObject:NSURLPboardType] ) { 483 | NSURL *fileURL = [NSURL URLFromPasteboard:pboard]; 484 | NSLog(@"%@",fileURL); 485 | } 486 | 487 | if([[pboard types] containsObject:NSFilenamesPboardType]){ 488 | NSArray *files = [pboard propertyListForType:NSFilenamesPboardType]; 489 | NSMutableArray *archiveFilePaths = [NSMutableArray arrayWithCapacity:1]; 490 | for(NSString *filePath in files){ 491 | if([filePath.pathExtension isEqualToString:@"xcarchive"]){ 492 | NSLog(@"%@", filePath); 493 | [archiveFilePaths addObject:filePath]; 494 | } 495 | 496 | if([filePath.pathExtension isEqualToString:@"dSYM"]){ 497 | [archiveFilePaths addObject:filePath]; 498 | } 499 | } 500 | 501 | if(archiveFilePaths.count == 0){ 502 | NSLog(@"没有包含任何 xcarchive 文件"); 503 | return NO; 504 | } 505 | 506 | [self resetPreInformation]; 507 | 508 | [self handleArchiveFileWithPath:archiveFilePaths]; 509 | 510 | 511 | } 512 | 513 | return YES; 514 | } 515 | 516 | @end 517 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Controller/MainWindowViewController.xib: -------------------------------------------------------------------------------- 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 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 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 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 100 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 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 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/DSYMTools.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | APPL 19 | CFBundleShortVersionString 20 | 1.0.5 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2016 answer. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Model/ArchiveInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArchiveInfo.h 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/27/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * 文件类型 13 | */ 14 | typedef NS_ENUM(NSInteger, ArchiveFileType){ 15 | // archive 文件 16 | ArchiveFileTypeXCARCHIVE = 1, 17 | //dsym 文件 18 | ArchiveFileTypeDSYM = 2 19 | }; 20 | 21 | @class UUIDInfo; 22 | 23 | @interface ArchiveInfo : NSObject 24 | 25 | /** 26 | * dSYM 路径 27 | */ 28 | @property (copy) NSString *dSYMFilePath; 29 | 30 | /** 31 | * dSYM 文件名 32 | */ 33 | @property (copy) NSString *dSYMFileName; 34 | 35 | /** 36 | * archive 文件名 37 | */ 38 | @property (copy) NSString *archiveFileName; 39 | 40 | /** 41 | * archive 文件路径 42 | */ 43 | @property (copy) NSString *archiveFilePath; 44 | 45 | /** 46 | * uuids 47 | */ 48 | @property (copy) NSArray *uuidInfos; 49 | 50 | /** 51 | * 文件类型 52 | */ 53 | @property (assign) ArchiveFileType archiveFileType; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Model/ArchiveInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // ArchiveInfo.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/27/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import "ArchiveInfo.h" 10 | 11 | @implementation ArchiveInfo 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Model/UUIDInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // UUIDInfo.h 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/27/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UUIDInfo : NSObject 12 | 13 | /** 14 | * arch 类型 15 | */ 16 | @property (nonatomic, copy) NSString *arch; 17 | 18 | /** 19 | * 默认的 Slide Address 20 | */ 21 | @property (nonatomic, readonly) NSString *defaultSlideAddress; 22 | 23 | /** 24 | * uuid 值 25 | */ 26 | @property (nonatomic, copy) NSString *uuid; 27 | 28 | /** 29 | * 可执行文件路径 30 | */ 31 | @property (nonatomic, copy) NSString *executableFilePath; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/Model/UUIDInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // UUIDInfo.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/27/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import "UUIDInfo.h" 10 | 11 | @interface UUIDInfo() 12 | 13 | /** 14 | * 默认的 Slide Address 15 | */ 16 | @property (nonatomic, readwrite) NSString *defaultSlideAddress; 17 | 18 | @end 19 | 20 | @implementation UUIDInfo 21 | 22 | - (void)setArch:(NSString *)arch { 23 | _arch = arch; 24 | if([arch isEqualToString:@"arm64"]){ 25 | _defaultSlideAddress = @"0x0000000100000000"; 26 | }else if([arch isEqualToString:@"armv7"]){ 27 | _defaultSlideAddress = @"0x00004000"; 28 | }else{ 29 | _defaultSlideAddress = @""; 30 | } 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/NSAttributedString+Hyperlink.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+Hyperlink.h 3 | // DSYMTools 4 | // 5 | // Created by answer on 2016/11/8. 6 | // Copyright © 2016年 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSAttributedString (Hyperlink) 12 | 13 | +(id)hyperlinkFromString:(NSString*)inString withURL:(NSURL*)aURL; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/NSAttributedString+Hyperlink.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+Hyperlink.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 2016/11/8. 6 | // Copyright © 2016年 answer. All rights reserved. 7 | // 8 | 9 | #import "NSAttributedString+Hyperlink.h" 10 | #import 11 | 12 | @implementation NSAttributedString (Hyperlink) 13 | 14 | +(id)hyperlinkFromString:(NSString*)inString withURL:(NSURL*)aURL 15 | { 16 | NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString: inString]; 17 | NSRange range = NSMakeRange(0, [attrString length]); 18 | 19 | [attrString beginEditing]; 20 | [attrString addAttribute:NSLinkAttributeName value:[aURL absoluteString] range:range]; 21 | 22 | // make the text appear in blue 23 | [attrString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:range]; 24 | 25 | // next make the text appear with an underline 26 | [attrString addAttribute: 27 | NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:range]; 28 | 29 | [attrString endEditing]; 30 | 31 | return attrString; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/View/ArchiveFilesScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArchiveFilesScrollView.h 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/29/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ArchiveFilesScrollView : NSScrollView 12 | { 13 | BOOL highlight; 14 | } 15 | 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/View/ArchiveFilesScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ArchiveFilesScrollView.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/29/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import "ArchiveFilesScrollView.h" 10 | 11 | @implementation ArchiveFilesScrollView 12 | 13 | 14 | 15 | - (NSDragOperation)draggingEntered:(id )sender{ 16 | 17 | 18 | highlight=YES; 19 | 20 | [self setNeedsDisplay: YES]; 21 | 22 | NSPasteboard *pboard; 23 | NSDragOperation sourceDragMask; 24 | 25 | sourceDragMask = [sender draggingSourceOperationMask]; 26 | pboard = [sender draggingPasteboard]; 27 | 28 | if ( [[pboard types] containsObject:NSColorPboardType] ) { 29 | if (sourceDragMask & NSDragOperationGeneric) { 30 | return NSDragOperationGeneric; 31 | } 32 | } 33 | if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { 34 | if (sourceDragMask & NSDragOperationLink) { 35 | return NSDragOperationLink; 36 | } else if (sourceDragMask & NSDragOperationCopy) { 37 | return NSDragOperationCopy; 38 | } 39 | } 40 | return NSDragOperationNone; 41 | } 42 | 43 | - (void)draggingExited:(id)sender{ 44 | highlight=NO; 45 | 46 | [self setNeedsDisplay: YES]; 47 | } 48 | 49 | - (BOOL)performDragOperation:(id )sender 50 | { 51 | NSPasteboard *pboard = [sender draggingPasteboard]; 52 | 53 | if ( [[pboard types] containsObject:NSURLPboardType] ) { 54 | NSURL *fileURL = [NSURL URLFromPasteboard:pboard]; 55 | // Perform operation using the file’s URL 56 | NSLog(@"%@",fileURL); 57 | } 58 | return YES; 59 | } 60 | 61 | - (void)drawRect:(NSRect)dirtyRect { 62 | [super drawRect:dirtyRect]; 63 | 64 | if ( highlight ) { 65 | [[NSColor redColor] set]; 66 | [NSBezierPath setDefaultLineWidth: 5]; 67 | [NSBezierPath strokeRect: dirtyRect]; 68 | } 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Objective-C/DSYMTools/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DSYMTools 4 | // 5 | // Created by answer on 7/25/16. 6 | // Copyright © 2016 answer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /Pic/crashLog1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Pic/crashLog1.png -------------------------------------------------------------------------------- /Pic/crashLog2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Pic/crashLog2.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 优化代码,快速根据友盟反馈定位崩溃信息 2 | ### 操作方法:将下图中友盟检测崩溃日志中红框内的地址填入,即可快速定位奔溃信息 3 | ![image](https://github.com/liunianhuaguoyanxi/dSYMTools/blob/master/Pic/crashLog1.png) 4 | ![image](https://github.com/liunianhuaguoyanxi/dSYMTools/blob/master/Pic/crashLog2.png) 5 | 6 | # Star History 7 | [![Star History Chart](https://api.star-history.com/svg?repos=answer-huang/dSYMTools&type=Date)](https://star-history.com/#answer-huang/dSYMTools&Date) 8 | 9 | # 更新: 10 | ### Version 1.0.5 2016-11-28 11 | 1.支持拖入 dSYM 文件。 12 | ### Version 1.0.4 2016-11-08 13 | 1.使用 Objective-C 重写应用。 14 | 2.建议都使用此版本。 15 | ### Version 1.0.3 2015-05-16 16 | 1.解决文件路径中不能包含空格的 bug。 17 | 18 | ### Version 1.0.2 2015-05-05 19 | 1.由于在 arm64 上 Slide address 变化,现需要提供 Slide address,不然得不到异常地址。 20 | 21 | ### Version 1.0.1 2014-07-29 22 | 23 | 1.增加对 dSYM 文件的支持,直接将 xcarchive 或 dSYM 文件拖入窗口中即可。 24 | 25 | 26 | 2.修复 dSYM 根据和版本管理软件冲突的 bug。 27 | 28 | 29 | ### Version 1.0.0 2014-06-26 30 | 31 | 32 | 1.软件基本功能完成(仅支持 xcarchive 文件)。 33 | 34 | 35 | # 项目简介 36 | 37 | 来到新公司后,前段时间就一直在忙,前不久 [项目](https://itunes.apple.com/cn/app/kang-da-yu-zhen-nu-ren-bao/id707364888?l=en&mt=8) 终于成功发布上线了,最近就在给项目做优化,并排除一些线上软件的 bug,因为项目中使用了友盟统计,所以在友盟给出的错误信息统计中能比较方便的找出客户端异常的信息,可是很多像数组越界却只给出了 `*** -[__NSArrayM objectAtIndex:]: index 50 beyond bounds [0 .. 39]'` 这类错误信息,如下图所示: 38 | 39 | ![errorInfo](http://answerhuang.bj.bcebos.com/blog/errorInfo.png) 40 | 41 | 遇到这种问题如果通过 `objectAtIndex` 去检索错误的地方那将会是一个巨大的工作量。 42 | 43 | # dSYM 文件 44 | 45 | ### 什么是 dSYM 文件 46 | Xcode编译项目后,我们会看到一个同名的 dSYM 文件,dSYM 是保存 16 进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,并且每次编译项目的时候都会生成一个新的 dSYM 文件,位于 `/Users/<用户名>/Library/Developer/Xcode/Archives` 目录下,对于每一个发布版本我们都很有必要保存对应的 Archives 文件 ( [AUTOMATICALLY SAVE THE DSYM FILES](http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/) 这篇文章介绍了通过脚本每次编译后都自动保存 dSYM 文件)。 47 | 48 | 49 | ### dSYM 文件有什么作用 50 | 当我们软件 release 模式打包或上线后,不会像我们在 Xcode 中那样直观的看到用崩溃的错误,这个时候我们就需要分析 crash report 文件了,iOS 设备中会有日志文件保存我们每个应用出错的函数内存地址,通过 Xcode 的 Organizer 可以将 iOS 设备中的 DeviceLog 导出成 crash 文件,这个时候我们就可以通过出错的函数地址去查询 dSYM 文件中程序对应的函数名和文件名。大前提是我们需要有软件版本对应的 dSYM 文件,这也是为什么我们很有必要保存每个发布版本的 Archives 文件了。 51 | 52 | ### 如何将文件一一对应 53 | 每一个 xx.app 和 xx.app.dSYM 文件都有对应的 UUID,crash 文件也有自己的 UUID,只要这三个文件的 UUID 一致,我们就可以通过他们解析出正确的错误函数信息了。 54 | 55 | 1.查看 xx.app 文件的 UUID,terminal 中输入命令 : 56 | 57 | dwarfdump --uuid xx.app/xx (xx代表你的项目名) 58 | 59 | 2.查看 xx.app.dSYM 文件的 UUID ,在 terminal 中输入命令: 60 | dwarfdump --uuid xx.app.dSYM 61 | 62 | 3.crash 文件内 Binary Images: 下面一行中 <> 内的 e86bcc8875b230279c962186b80b466d 就是该 crash 文件的 UUID,而第一个地址 0x1000ac000 便是 slide address: 63 | Binary Images: 64 | 0x1000ac000 - 0x100c13fff Example arm64 /var/containers/Bundle/Application/99EE6ECE-4CEA-4ADD-AE8D-C4B498886D22/Example.app/Example 65 | 66 | 67 | # dSYM工具 68 | 于是我抽了几个小时的时间将这些命令封装到一个应用中,也为以后解决bug提供了便利。 69 | 70 | 使用步骤: 71 | 72 | 1.将打包发布软件时的xcarchive文件拖入软件窗口内的任意位置(支持多个文件同时拖入,注意:`文件名不要包含空格`) 73 | 74 | 2.选中任意一个版本的xcarchive文件,右边会列出该xcarchive文件支持的CPU类型,选中错误对应的CPU类型。 75 | 76 | 3.对比错误给出的UUID和工具界面中给出的UUID是否一致。 77 | 78 | 4.将错误地址以及 Slide Address 输入工具的文本框中,点击分析。 79 | 80 | ![dSYMToos](http://answerhuang.bj.bcebos.com/blog/dsymTool.png) 81 | 82 | 83 | [项目源码地址](https://github.com/answer-huang/dSYMTools) 84 | 85 | 86 | [1]: https://itunes.apple.com/cn/app/kang-da-yu-zhen-nu-ren-bao/id707364888?l=en&mt=8 87 | [2]: http://answerhuang.bj.bcebos.com/blog/errorInfo.png 88 | [3]: http://answerhuang.bj.bcebos.com/blog/dsymTool.png 89 | [4]: http://answerhuang.bj.bcebos.com/blog/crashUUID.png 90 | [5]: http://www.cimgf.com/2009/12/23/automatically-save-the-dsym-files/ 91 | [6]: https://github.com/answer-huang/dSYMTools 92 | 93 | 94 | -------------------------------------------------------------------------------- /Swift/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/Swift/README.md -------------------------------------------------------------------------------- /wxPython/AHDropTarget.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | __author__ = 'answer-huang' 3 | 4 | import wx 5 | import os 6 | 7 | 8 | class AHDropTarget(wx.FileDropTarget): 9 | def __init__(self, window): 10 | wx.FileDropTarget.__init__(self) 11 | self.window = window 12 | 13 | def OnDropFiles(self, x, y, filenames): 14 | self.fileList = [] 15 | for filename in filenames: 16 | print os.path.basename(filename) 17 | #TODO: 增加对dSYM文件的支持 18 | if filename.endswith(('xcarchive', 'dSYM')): 19 | self.fileList.append(filename) 20 | 21 | self.window.filesList = self.fileList 22 | self.window.ShowFileType() 23 | 24 | #def OnEnter(self, x, y, z): 25 | # print x, y, z 26 | # print 'OnEnter x:%d, y:%d' % (x, y) 27 | # 28 | #def OnLeave(self): 29 | # print 'leave windows' 30 | # 31 | #def OnDrop(self, x, y): 32 | # print 'OnDrop x:%d, y:%d' % (x, y) 33 | # print x, y 34 | # 35 | #def OnData(self, x, y, z): 36 | # print 'OnData x:%d, y:%d' % (x, y) -------------------------------------------------------------------------------- /wxPython/MyInfo.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | __author__ = 'answer-huang' 3 | 4 | import wx 5 | import sys 6 | reload(sys) 7 | sys.setdefaultencoding('utf8') 8 | 9 | """ 10 | 关于我 11 | """ 12 | 13 | 14 | class AboutMe(wx.Dialog): 15 | def __init__(self, parent): 16 | wx.Dialog.__init__(self, parent, -1, '关于我', size=(250, 300)) 17 | bitmap = wx.Image("avatar.jpg", wx.BITMAP_TYPE_JPEG).Rescale(150, 150, quality=wx.IMAGE_QUALITY_HIGH).ConvertToBitmap() 18 | mask = self._create_round_corner_mask(bitmap.GetSize(), radius=75, border=5) 19 | bitmap.SetMask(mask) 20 | wx.StaticBitmap(self, bitmap=bitmap, pos=(50, 10), size=(150, 150)) 21 | 22 | wx.StaticText(self, -1, '微博:', pos=(45, 170)) 23 | wx.HyperlinkCtrl(self, -1, 'answer-huang', 'http://weibo.com/u/1623064627', pos=(85, 170)) 24 | 25 | # wx.StaticText(self, -1, '邮箱:', pos=(45, 200)) 26 | # wx.HyperlinkCtrl(self, -1, 'aihoo91@gmail.com', 'mailto:aihoo91@gmail.com', pos=(85, 200)) 27 | 28 | wx.StaticText(self, -1, '博客:', pos=(45, 200)) 29 | wx.HyperlinkCtrl(self, -1, 'answerhuang.duapp.com', 'http://answerhuang.duapp.com', pos=(85, 200)) 30 | 31 | wx.StaticText(self, -1, 'GitHub:', pos=(28, 230)) 32 | wx.HyperlinkCtrl(self, -1, 'dSYMTools', 'https://github.com/answer-huang/dSYMTools', pos=(85, 230)) 33 | 34 | def _create_round_corner_mask(self, size, radius, border=0): 35 | (w, h) = size 36 | maskBitmap = wx.EmptyBitmap(w, h) 37 | mdc = wx.MemoryDC() 38 | mdc.SelectObject(maskBitmap) 39 | mdc.SetPen(wx.RED_PEN) 40 | mdc.SetBrush(wx.RED_BRUSH) 41 | mdc.DrawRoundedRectangle(border, border, w - border*2, h - border*2, radius) 42 | mdc.SelectObject(wx.NullBitmap) 43 | return wx.Mask(maskBitmap) -------------------------------------------------------------------------------- /wxPython/RunScript.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | """ 4 | * User: answer.huang 5 | * Email: aihoo91@gmail.com 6 | * Date: 14-7-28 7 | * Time: 23:36 8 | * Blog: answerhuang.duapp.com 9 | """ 10 | 11 | 12 | import os 13 | import sys 14 | import time 15 | import shutil 16 | import sqlite3 17 | 18 | print os.environ["EFFECTIVE_PLATFORM_NAME"] 19 | print os.environ["DWARF_DSYM_FOLDER_PATH"] 20 | 21 | if os.environ["BUILD_STYLE"] == "Debug": 22 | print "跳过debug模式" 23 | sys.exit() 24 | 25 | if os.environ["EFFECTIVE_PLATFORM_NAME"] == "-iphonesimulator": 26 | print "跳过模拟器编译情况" 27 | sys.exit() 28 | 29 | dsym_folder_path = os.environ["DWARF_DSYM_FOLDER_PATH"] 30 | dsym_file_name = os.environ["DWARF_DSYM_FILE_NAME"] 31 | src_path = os.path.join(dsym_folder_path, dsym_file_name) 32 | 33 | 34 | 35 | executable_name = os.environ["EXECUTABLE_NAME"] 36 | relative_dest_path = "dSYM/%s.%s.app.dSYM" % (executable_name, time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))) 37 | dest_path = os.path.join(os.environ["PROJECT_DIR"], relative_dest_path) 38 | 39 | print "moving %s to %s" % (src_path, dest_path) 40 | shutil.move(src_path, dest_path) 41 | 42 | if os.path.exists(dest_path): 43 | sqlitedb = "/Applications/DSYMTools.app/Contents/Resources/dsym.db" 44 | cx = sqlite3.connect(sqlitedb) 45 | cu = cx.cursor() 46 | cu.execute("""create table if not exists archives (file_path varchar(10) unique)""") 47 | cu.execute("insert into archives values (?)", (dest_path, )) 48 | cx.commit() 49 | -------------------------------------------------------------------------------- /wxPython/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/about.png -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Frameworks/Python.framework/Python: -------------------------------------------------------------------------------- 1 | Versions/Current/Python -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Frameworks/Python.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Frameworks/Python.framework/Versions/2.7/Python: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Frameworks/Python.framework/Versions/2.7/Python -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Frameworks/Python.framework/Versions/2.7/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | Python 9 | CFBundleGetInfoString 10 | Python Runtime and Library 11 | CFBundleIdentifier 12 | org.python.python 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Python 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 2.7.6, (c) 2004-2013 Python Software Foundation. 21 | CFBundleLongVersionString 22 | 2.7.6, (c) 2004-2013 Python Software Foundation. 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 2.7.6 27 | 28 | 29 | -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Frameworks/Python.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | 2.7 -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Frameworks/libwx_osx_cocoau-3.0.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Frameworks/libwx_osx_cocoau-3.0.0.0.0.dylib -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | dSYM 9 | CFBundleExecutable 10 | dSYM 11 | CFBundleIconFile 12 | dSYMIcns.icns 13 | CFBundleIdentifier 14 | org.pythonmac.unspecified.dSYM 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | dSYM 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0.1 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 0.0.0 27 | LSHasLocalizedDisplayName 28 | 29 | NSAppleScriptEnabled 30 | 31 | NSHumanReadableCopyright 32 | Copyright not specified 33 | NSMainNibFile 34 | MainMenu 35 | NSPrincipalClass 36 | NSApplication 37 | PyMainFileNames 38 | 39 | __boot__ 40 | 41 | PyOptions 42 | 43 | alias 44 | 45 | argv_emulation 46 | 47 | emulate_shell_environment 48 | 49 | no_chdir 50 | 51 | prefer_ppc 52 | 53 | site_packages 54 | 55 | use_faulthandler 56 | 57 | use_pythonpath 58 | 59 | verbose 60 | 61 | 62 | PyResourcePackages 63 | 64 | 65 | PyRuntimeLocations 66 | 67 | @executable_path/../Frameworks/Python.framework/Versions/2.7/Python 68 | 69 | PythonInfoDict 70 | 71 | PythonExecutable 72 | /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python 73 | PythonLongVersion 74 | 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 75 | [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] 76 | PythonShortVersion 77 | 2.7 78 | py2app 79 | 80 | alias 81 | 82 | template 83 | app 84 | version 85 | 0.8.1 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/MacOS/dSYM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/MacOS/dSYM -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/MacOS/python: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/MacOS/python -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/RunScript.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | """ 4 | * User: answer.huang 5 | * Email: aihoo91@gmail.com 6 | * Date: 14-7-28 7 | * Time: 23:36 8 | * Blog: answerhuang.duapp.com 9 | """ 10 | 11 | 12 | import os 13 | import sys 14 | import time 15 | import shutil 16 | import sqlite3 17 | 18 | print os.environ["EFFECTIVE_PLATFORM_NAME"] 19 | print os.environ["DWARF_DSYM_FOLDER_PATH"] 20 | 21 | if os.environ["BUILD_STYLE"] == "Debug": 22 | print "跳过debug模式" 23 | sys.exit() 24 | 25 | if os.environ["EFFECTIVE_PLATFORM_NAME"] == "-iphonesimulator": 26 | print "跳过模拟器编译情况" 27 | sys.exit() 28 | 29 | dsym_folder_path = os.environ["DWARF_DSYM_FOLDER_PATH"] 30 | dsym_file_name = os.environ["DWARF_DSYM_FILE_NAME"] 31 | src_path = os.path.join(dsym_folder_path, dsym_file_name) 32 | 33 | 34 | 35 | executable_name = os.environ["EXECUTABLE_NAME"] 36 | relative_dest_path = "dSYM/%s.%s.app.dSYM" % (executable_name, time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))) 37 | dest_path = os.path.join(os.environ["PROJECT_DIR"], relative_dest_path) 38 | 39 | print "moving %s to %s" % (src_path, dest_path) 40 | shutil.move(src_path, dest_path) 41 | 42 | if os.path.exists(dest_path): 43 | sqlitedb = "/Applications/dSYM.app/Contents/Resources/dsym.db" 44 | cx = sqlite3.connect(sqlitedb) 45 | cu = cx.cursor() 46 | cu.execute("""create table if not exists archives (file_path varchar(10) unique)""") 47 | cu.execute("insert into archives values (?)", (dest_path, )) 48 | cx.commit() -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/__boot__.py: -------------------------------------------------------------------------------- 1 | def _reset_sys_path(): 2 | # Clear generic sys.path[0] 3 | import sys, os 4 | resources = os.environ['RESOURCEPATH'] 5 | while sys.path[0] == resources: 6 | del sys.path[0] 7 | _reset_sys_path() 8 | 9 | 10 | def _chdir_resource(): 11 | import os 12 | os.chdir(os.environ['RESOURCEPATH']) 13 | _chdir_resource() 14 | 15 | 16 | def _disable_linecache(): 17 | import linecache 18 | def fake_getline(*args, **kwargs): 19 | return '' 20 | linecache.orig_getline = linecache.getline 21 | linecache.getline = fake_getline 22 | _disable_linecache() 23 | 24 | 25 | import re, sys 26 | cookie_re = re.compile(b"coding[:=]\s*([-\w.]+)") 27 | if sys.version_info[0] == 2: 28 | default_encoding = 'ascii' 29 | else: 30 | default_encoding = 'utf-8' 31 | 32 | def guess_encoding(fp): 33 | for i in range(2): 34 | ln = fp.readline() 35 | 36 | m = cookie_re.search(ln) 37 | if m is not None: 38 | return m.group(1).decode('ascii') 39 | 40 | return default_encoding 41 | 42 | def _run(): 43 | global __file__ 44 | import os, site 45 | sys.frozen = 'macosx_app' 46 | base = os.environ['RESOURCEPATH'] 47 | 48 | argv0 = os.path.basename(os.environ['ARGVZERO']) 49 | script = SCRIPT_MAP.get(argv0, DEFAULT_SCRIPT) 50 | 51 | path = os.path.join(base, script) 52 | sys.argv[0] = __file__ = path 53 | if sys.version_info[0] == 2: 54 | with open(path, 'rU') as fp: 55 | source = fp.read() + "\n" 56 | else: 57 | with open(path, 'rb') as fp: 58 | encoding = guess_encoding(fp) 59 | 60 | with open(path, 'r', encoding=encoding) as fp: 61 | source = fp.read() + '\n' 62 | exec(compile(source, path, 'exec'), globals(), globals()) 63 | 64 | 65 | DEFAULT_SCRIPT='dSYM.py' 66 | SCRIPT_MAP={} 67 | _run() 68 | -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/__error__.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This is the default apptemplate error script 4 | # 5 | if ( test -n "$2" ) ; then 6 | echo "$1 Error" 7 | echo "An unexpected error has occurred during execution of the main script" 8 | echo "" 9 | echo "$2: $3" 10 | echo "" 11 | echo "See the Console for a detailed traceback." 12 | else 13 | echo "$1 Error" 14 | 15 | # Usage: ERRORURL , this is used by the 16 | # bundle runner to put up a dialog. 17 | #echo "ERRORURL: http://www.python.org/ Visit the Python Website 18 | # echo "ERRORURL: http://homepages.cwi.nl/~jack/macpython/index.html Visit the MacPython Website" 19 | fi 20 | -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/about.png -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/avatar.jpg -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/dSYM.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | __author__ = 'answer-huang' 3 | 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | 8 | import wx 9 | from MyInfo import AboutMe 10 | from AHDropTarget import AHDropTarget 11 | import os 12 | import subprocess 13 | import sqlite3 14 | 15 | class AHFrame(wx.Frame): 16 | def __init__(self, parent, title): 17 | wx.Frame.__init__(self, 18 | parent, 19 | -1, 20 | title, 21 | wx.DefaultPosition, 22 | wx.Size(500, 500) 23 | #style=wx.DEFAULT_FRAME_STYLE 24 | #style=wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) 25 | ) 26 | #style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX) 27 | #拖进到窗口中的文件列表 28 | self.filesList = [] 29 | 30 | #创建状态栏 31 | self.statusbar = self.CreateStatusBar() 32 | self.statusbar.SetForegroundColour('red') 33 | self.statusbar.SetFieldsCount(2) 34 | self.statusbar.SetStatusWidths([-2, -1]) #大小比例2:1 35 | 36 | #创建工具栏 37 | toolbar = self.CreateToolBar() 38 | toolbar.AddSimpleTool(1, wx.Image('./about.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), "关于我", "") 39 | toolbar.AddSeparator() 40 | toolbar.Realize() #准备显示工具栏 41 | wx.EVT_TOOL(self, 1, self.OnAboutMe) 42 | 43 | #创建panel 44 | self.panel = wx.Panel(self) 45 | self.panel.SetDropTarget(AHDropTarget(self)) 46 | 47 | #self.font = wx.Font(18, wx.SCRIPT, wx.BOLD, wx.LIGHT) 48 | #self.selectedPath = wx.StaticText(self.panel, -1, u'请将xcarchive文件拖拽到窗口中!', pos=(138, 300)) 49 | #self.selectedPath.SetFont(self.font) 50 | 51 | self.vbox = wx.BoxSizer(wx.VERTICAL) 52 | 53 | 54 | self.description = wx.StaticText(self.panel, -1, u'请将dSYM文件拖拽到窗口中并选中任意一个版本进行分析', style=wx.TE_WORDWRAP | wx.TE_MULTILINE) 55 | self.fileTypeLB = wx.ListBox(self.panel, -1, style = wx.LB_EXTENDED) 56 | self.fileTypeLB.SetBackgroundColour(wx.Colour(232, 232, 232, 255)) 57 | #TODO: 从sqlite中读取文件路径 58 | self.getdSYMFileFromSqlite() 59 | self.Bind(wx.EVT_LISTBOX, self.ListBoxClick, self.fileTypeLB) 60 | self.Bind(wx.EVT_LISTBOX_DCLICK, self.ListBoxClick, self.fileTypeLB) 61 | 62 | self.fileTypeLBhbox = wx.BoxSizer(wx.HORIZONTAL) 63 | self.fileTypeLBhbox.Add(self.fileTypeLB, 1, wx.EXPAND) 64 | self.vbox.Add(self.description, 0, wx.EXPAND | wx.ALL, 5) 65 | self.vbox.Add(self.fileTypeLBhbox, 1, wx.EXPAND | wx.ALL, 5) 66 | self.vbox.SetItemMinSize(self.fileTypeLBhbox, (200, 100)) 67 | self.vbox.Add((-1, 10)) 68 | 69 | self.UUIDString = wx.StaticText(self.panel, -1, u'选中dSYM文件的UUID:') 70 | self.vbox.Add(self.UUIDString, 0, wx.EXPAND | wx.ALL, 5) 71 | 72 | self.UUIDStringText = wx.TextCtrl(self.panel, -1) 73 | hbox2 = wx.BoxSizer(wx.HORIZONTAL) 74 | hbox2.Add(self.UUIDStringText, 1, wx.EXPAND) 75 | self.vbox.Add(hbox2, 0, wx.EXPAND | wx.ALL, 5) 76 | 77 | self.vbox.Add((-1, 10)) 78 | 79 | self.memAddressStr = wx.StaticText(self.panel, -1, u'请输入错误信息的内存地址:') 80 | self.vbox.Add(self.memAddressStr, 0, wx.ALL, 5) 81 | 82 | self.memAddress = wx.TextCtrl(self.panel, -1) 83 | hbox3 = wx.BoxSizer(wx.HORIZONTAL) 84 | hbox3.Add(self.memAddress, 1, wx.EXPAND) 85 | self.vbox.Add(hbox3, 0, wx.EXPAND | wx.ALL, 5) 86 | 87 | self.fileBtn = wx.Button(self.panel, -1, u'分析') 88 | self.fileBtn.Bind(wx.EVT_BUTTON, self.startCalc) 89 | hbox4 = wx.BoxSizer(wx.HORIZONTAL) 90 | hbox4.Add(self.fileBtn, 1, wx.EXPAND) 91 | self.vbox.Add(hbox4, 0, wx.EXPAND | wx.ALL, 5) 92 | 93 | 94 | self.vbox.Add((-1, 10)) 95 | 96 | self.maybeReason = wx.StaticText(self.panel, -1, u'有可能错误的地方:', style=wx.TE_WORDWRAP|wx.TE_MULTILINE)#size=(170, 30), pos=(5, 250), 97 | self.vbox.Add(self.maybeReason, 0, wx.EXPAND | wx.ALL, 5) 98 | self.maybeReasonContent = wx.TextCtrl(self.panel, -1, u'', style=wx.TE_WORDWRAP|wx.TE_MULTILINE)#size=(500, 60), pos=(5, 270), 99 | hbox5 = wx.BoxSizer(wx.HORIZONTAL) 100 | hbox5.Add(self.maybeReasonContent, 1, wx.EXPAND) 101 | 102 | self.vbox.Add(hbox5, 1, wx.EXPAND | wx.ALL, 5) 103 | self.vbox.SetItemMinSize(hbox5, (200, 100)) 104 | 105 | self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) 106 | self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) 107 | self.panel.Bind(wx.EVT_MOTION, self.OnMotion) 108 | self.panel.SetSizer(self.vbox) 109 | 110 | #文件列表单击事件 111 | def ListBoxClick(self, event): 112 | self.selectedArchiveFilePath = self.filesList[event.GetSelection()] 113 | self.getFilePath(self.selectedArchiveFilePath) 114 | self.getArchiveUUID() 115 | 116 | #获取文件UUID 117 | def getArchiveUUID(self): 118 | comString = 'dwarfdump --uuid ' + self.dsymFilePath 119 | lines = os.popen(comString).readlines() 120 | self.archiveUUIDDic = {} 121 | for line in lines: 122 | uuidString = line.split(' ')[1] 123 | archiveType = line.split(' ')[2][1:-1] 124 | self.archiveUUIDDic[archiveType] = uuidString 125 | if hasattr(self, 'archiveType'): 126 | self.fileTypeLBhbox.Remove(self.fileTypeLBhbox.GetItemIndex(self.archivebox)) 127 | self.archiveType.Destroy() 128 | self.archiveType = wx.RadioBox(self.panel, -1, "请选择该archive文件对应的编译类型", choices=self.archiveUUIDDic.keys(), majorDimension=1) 129 | self.archivebox = wx.BoxSizer(wx.HORIZONTAL) 130 | self.archivebox.Add(self.archiveType, 0, wx.ALL, 5) 131 | self.fileTypeLBhbox.Add(self.archivebox, 0, wx.ALL, 5) 132 | self.fileTypeLBhbox.Layout() 133 | self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, self.archiveType) 134 | self.UUIDStringText.SetValue(self.archiveUUIDDic[self.archiveType.GetStringSelection()]) 135 | self.selectedArchiveType = self.archiveType.GetStringSelection() 136 | 137 | 138 | #选择编译器事件 139 | def EvtRadioBox(self, event): 140 | self.selectedArchiveType = event.GetString() 141 | self.UUIDStringText.SetValue(self.archiveUUIDDic[self.selectedArchiveType]) 142 | 143 | 144 | def startCalc(self, event): 145 | if self.memAddress.GetValue(): 146 | comString = 'xcrun atos -arch ' + self.selectedArchiveType + ' -o ' + str(self.appFilePath) + ' ' + self.memAddress.GetValue() 147 | tmp = os.popen(comString).readlines() 148 | self.maybeReasonContent.SetValue(tmp[0]) 149 | 150 | def OnEnterWindow(self, event): 151 | event.Skip() 152 | 153 | def OnLeaveWindow(self, event): 154 | event.Skip() 155 | 156 | def OnMotion(self, event): 157 | if event.Dragging() and event.LeftIsDown(): 158 | print '按住了鼠标移动' 159 | event.Skip() 160 | 161 | def ShowFileType(self): 162 | self.fileTypeLB.Set(list([os.path.basename(filepath) for filepath in self.filesList])) 163 | 164 | def getdSYMFileFromSqlite(self): 165 | if os.path.exists('dsym.db'): 166 | cx = sqlite3.connect('dsym.db') 167 | cu = cx.cursor() 168 | ##查询 169 | cu.execute("select * from archives") 170 | self.filesList = [dsym[0] for dsym in cu.fetchall()] 171 | self.ShowFileType() 172 | 173 | #获取最后需要的文件地址 174 | def getFilePath(self, rootPath): 175 | if rootPath.endswith("dSYM"): 176 | self.dsymFilePath = rootPath 177 | fileName = os.path.basename(rootPath) 178 | else: 179 | dsymsPath = os.path.join(rootPath,'dSYMs') 180 | listFiles = os.listdir(dsymsPath) 181 | for fileName in listFiles: 182 | if fileName.endswith('dSYM'): 183 | #dsym文件路径 184 | self.dsymFilePath = os.path.join(dsymsPath, fileName) 185 | 186 | appPath = os.path.join(self.dsymFilePath,'Contents/Resources/DWARF') 187 | if os.path.isdir(appPath): 188 | if len(os.listdir(appPath)) is not 0: 189 | #命令行中需要的文件路径 190 | self.appFilePath = os.path.join(appPath,fileName.split(".")[0]) 191 | 192 | #显示关于我的界面 193 | def OnAboutMe(self, event): 194 | aboutMe = AboutMe(self) 195 | aboutMe.ShowModal() 196 | aboutMe.Destroy() 197 | 198 | versions = '1.0.1' 199 | if __name__ == '__main__': 200 | app = wx.App(redirect=False) 201 | frame = AHFrame(None, 'dSYM文件分析工具' + versions) 202 | frame.ShowWithEffect(True) 203 | app.MainLoop() 204 | -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/dSYMIcns.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/dSYMIcns.icns -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/dsym.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/dsym.db -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/MacOS.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/MacOS.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/Nav.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/Nav.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_AE.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_AE.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Ctl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Ctl.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Dlg.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Dlg.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Evt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Evt.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_File.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_File.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Menu.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Menu.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Qd.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Qd.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Res.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Res.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Win.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_Win.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_cn.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_cn.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_hk.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_hk.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_iso2022.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_iso2022.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_jp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_jp.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_kr.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_kr.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_tw.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_tw.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_collections.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_collections.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_functools.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_functools.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_hashlib.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_hashlib.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_heapq.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_heapq.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_io.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_io.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_locale.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_locale.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_multibytecodec.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_multibytecodec.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_random.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_random.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_scproxy.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_scproxy.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_socket.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_socket.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_sqlite3.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_sqlite3.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_ssl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_ssl.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_struct.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/_struct.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/array.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/array.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/binascii.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/binascii.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/bz2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/bz2.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/cPickle.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/cPickle.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/cStringIO.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/cStringIO.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/datetime.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/datetime.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/fcntl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/fcntl.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/gestalt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/gestalt.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/grp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/grp.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/itertools.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/itertools.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/math.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/math.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/operator.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/operator.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/parser.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/parser.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/pyexpat.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/pyexpat.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/resource.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/resource.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/select.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/select.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/strop.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/strop.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/termios.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/termios.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/time.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/time.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/unicodedata.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/unicodedata.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_controls_.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_controls_.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_core_.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_core_.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_gdi_.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_gdi_.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_misc_.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_misc_.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_windows_.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_windows_.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/zlib.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/lib-dynload/zlib.so -------------------------------------------------------------------------------- /wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/site-packages.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/app/dSYM.app/Contents/Resources/lib/python2.7/site-packages.zip -------------------------------------------------------------------------------- /wxPython/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/avatar.jpg -------------------------------------------------------------------------------- /wxPython/dSYM.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | __author__ = 'answer-huang' 3 | 4 | import sys 5 | reload(sys) 6 | sys.setdefaultencoding('utf8') 7 | 8 | import wx 9 | from MyInfo import AboutMe 10 | from AHDropTarget import AHDropTarget 11 | import os 12 | import subprocess 13 | import sqlite3 14 | 15 | class AHFrame(wx.Frame): 16 | def __init__(self, parent, title): 17 | wx.Frame.__init__(self, 18 | parent, 19 | -1, 20 | title, 21 | wx.DefaultPosition, 22 | wx.Size(500, 500) 23 | #style=wx.DEFAULT_FRAME_STYLE 24 | #style=wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX) 25 | ) 26 | #style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX) 27 | #拖进到窗口中的文件列表 28 | self.filesList = [] 29 | 30 | #创建状态栏 31 | self.statusbar = self.CreateStatusBar() 32 | self.statusbar.SetForegroundColour('red') 33 | self.statusbar.SetFieldsCount(2) 34 | self.statusbar.SetStatusWidths([-2, -1]) #大小比例2:1 35 | 36 | #创建工具栏 37 | toolbar = self.CreateToolBar() 38 | toolbar.AddSimpleTool(1, wx.Image('./about.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), "关于我", "") 39 | toolbar.AddSeparator() 40 | toolbar.Realize() #准备显示工具栏 41 | wx.EVT_TOOL(self, 1, self.OnAboutMe) 42 | 43 | #创建panel 44 | self.panel = wx.Panel(self) 45 | self.panel.SetDropTarget(AHDropTarget(self)) 46 | 47 | #self.font = wx.Font(18, wx.SCRIPT, wx.BOLD, wx.LIGHT) 48 | #self.selectedPath = wx.StaticText(self.panel, -1, u'请将xcarchive文件拖拽到窗口中!', pos=(138, 300)) 49 | #self.selectedPath.SetFont(self.font) 50 | 51 | self.vbox = wx.BoxSizer(wx.VERTICAL) 52 | 53 | 54 | self.description = wx.StaticText(self.panel, -1, u'请将dSYM文件拖拽到窗口中并选中任意一个版本进行分析', style=wx.TE_WORDWRAP | wx.TE_MULTILINE) 55 | self.fileTypeLB = wx.ListBox(self.panel, -1, style = wx.LB_EXTENDED) 56 | self.fileTypeLB.SetBackgroundColour(wx.Colour(232, 232, 232, 255)) 57 | #TODO: 从sqlite中读取文件路径 58 | self.getdSYMFileFromSqlite() 59 | self.Bind(wx.EVT_LISTBOX, self.ListBoxClick, self.fileTypeLB) 60 | self.Bind(wx.EVT_LISTBOX_DCLICK, self.ListBoxClick, self.fileTypeLB) 61 | 62 | self.fileTypeLBhbox = wx.BoxSizer(wx.HORIZONTAL) 63 | self.fileTypeLBhbox.Add(self.fileTypeLB, 1, wx.EXPAND) 64 | self.vbox.Add(self.description, 0, wx.EXPAND | wx.ALL, 5) 65 | self.vbox.Add(self.fileTypeLBhbox, 1, wx.EXPAND | wx.ALL, 5) 66 | self.vbox.SetItemMinSize(self.fileTypeLBhbox, (200, 100)) 67 | self.vbox.Add((-1, 10)) 68 | 69 | self.UUIDString = wx.StaticText(self.panel, -1, u'选中dSYM文件的UUID:') 70 | self.vbox.Add(self.UUIDString, 0, wx.EXPAND | wx.ALL, 5) 71 | 72 | self.UUIDStringText = wx.TextCtrl(self.panel, -1) 73 | hbox2 = wx.BoxSizer(wx.HORIZONTAL) 74 | hbox2.Add(self.UUIDStringText, 1, wx.EXPAND) 75 | self.vbox.Add(hbox2, 0, wx.EXPAND | wx.ALL, 5) 76 | 77 | self.vbox.Add((-1, 10)) 78 | 79 | self.memAddressStr = wx.StaticText(self.panel, -1, u'请输入错误信息的内存地址:') 80 | self.vbox.Add(self.memAddressStr, 0, wx.ALL, 5) 81 | 82 | self.memAddress = wx.TextCtrl(self.panel, -1) 83 | hbox3 = wx.BoxSizer(wx.HORIZONTAL) 84 | hbox3.Add(self.memAddress, 1, wx.EXPAND) 85 | self.vbox.Add(hbox3, 0, wx.EXPAND | wx.ALL, 5) 86 | 87 | self.slideAddressStr = wx.StaticText(self.panel, -1, u'请输入 Slide Address:') 88 | self.vbox.Add(self.slideAddressStr, 0, wx.ALL, 5) 89 | 90 | self.slideAddress = wx.TextCtrl(self.panel, -1) 91 | hbox3 = wx.BoxSizer(wx.HORIZONTAL) 92 | hbox3.Add(self.slideAddress, 1, wx.EXPAND) 93 | self.vbox.Add(hbox3, 0, wx.EXPAND | wx.ALL, 5) 94 | 95 | self.fileBtn = wx.Button(self.panel, -1, u'分析') 96 | self.fileBtn.Bind(wx.EVT_BUTTON, self.startCalc) 97 | hbox4 = wx.BoxSizer(wx.HORIZONTAL) 98 | hbox4.Add(self.fileBtn, 1, wx.EXPAND) 99 | self.vbox.Add(hbox4, 0, wx.EXPAND | wx.ALL, 5) 100 | 101 | 102 | self.vbox.Add((-1, 10)) 103 | 104 | self.maybeReason = wx.StaticText(self.panel, -1, u'有可能错误的地方:', style=wx.TE_WORDWRAP|wx.TE_MULTILINE)#size=(170, 30), pos=(5, 250), 105 | self.vbox.Add(self.maybeReason, 0, wx.EXPAND | wx.ALL, 5) 106 | self.maybeReasonContent = wx.TextCtrl(self.panel, -1, u'', style=wx.TE_WORDWRAP|wx.TE_MULTILINE)#size=(500, 60), pos=(5, 270), 107 | hbox5 = wx.BoxSizer(wx.HORIZONTAL) 108 | hbox5.Add(self.maybeReasonContent, 1, wx.EXPAND) 109 | 110 | self.vbox.Add(hbox5, 1, wx.EXPAND | wx.ALL, 5) 111 | self.vbox.SetItemMinSize(hbox5, (200, 100)) 112 | 113 | self.panel.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow) 114 | self.panel.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow) 115 | self.panel.Bind(wx.EVT_MOTION, self.OnMotion) 116 | self.panel.SetSizer(self.vbox) 117 | 118 | #文件列表单击事件 119 | def ListBoxClick(self, event): 120 | self.selectedArchiveFilePath = self.filesList[event.GetSelection()] 121 | self.getFilePath(self.selectedArchiveFilePath) 122 | self.getArchiveUUID() 123 | 124 | #获取文件UUID 125 | def getArchiveUUID(self): 126 | comString = 'dwarfdump --uuid ' + '"' +self.dsymFilePath + '"' 127 | lines = os.popen(comString).readlines() 128 | self.archiveUUIDDic = {} 129 | for line in lines: 130 | uuidString = line.split(' ')[1] 131 | archiveType = line.split(' ')[2][1:-1] 132 | self.archiveUUIDDic[archiveType] = uuidString 133 | if hasattr(self, 'archiveType'): 134 | self.fileTypeLBhbox.Remove(self.fileTypeLBhbox.GetItemIndex(self.archivebox)) 135 | self.archiveType.Destroy() 136 | self.archiveType = wx.RadioBox(self.panel, -1, "请选择该archive文件对应的编译类型", choices=self.archiveUUIDDic.keys(), majorDimension=1) 137 | self.archivebox = wx.BoxSizer(wx.HORIZONTAL) 138 | self.archivebox.Add(self.archiveType, 0, wx.ALL, 5) 139 | self.fileTypeLBhbox.Add(self.archivebox, 0, wx.ALL, 5) 140 | self.fileTypeLBhbox.Layout() 141 | self.Bind(wx.EVT_RADIOBOX, self.EvtRadioBox, self.archiveType) 142 | self.UUIDStringText.SetValue(self.archiveUUIDDic[self.archiveType.GetStringSelection()]) 143 | self.selectedArchiveType = self.archiveType.GetStringSelection() 144 | 145 | 146 | #选择编译器事件 147 | def EvtRadioBox(self, event): 148 | self.selectedArchiveType = event.GetString() 149 | self.UUIDStringText.SetValue(self.archiveUUIDDic[self.selectedArchiveType]) 150 | 151 | 152 | def startCalc(self, event): 153 | if self.memAddress.GetValue(): 154 | comString = 'xcrun atos -arch ' + self.selectedArchiveType + ' -o "' + str(self.appFilePath) + '" -l ' + self.slideAddress.GetValue() + ' ' + self.memAddress.GetValue() 155 | tmp = os.popen(comString).readlines() 156 | self.maybeReasonContent.SetValue(tmp[0]) 157 | 158 | def OnEnterWindow(self, event): 159 | event.Skip() 160 | 161 | def OnLeaveWindow(self, event): 162 | event.Skip() 163 | 164 | def OnMotion(self, event): 165 | if event.Dragging() and event.LeftIsDown(): 166 | print '按住了鼠标移动' 167 | event.Skip() 168 | 169 | def ShowFileType(self): 170 | self.fileTypeLB.Set(list([os.path.basename(filepath) for filepath in self.filesList])) 171 | 172 | def getdSYMFileFromSqlite(self): 173 | if os.path.exists('dsym.db'): 174 | cx = sqlite3.connect('dsym.db') 175 | cu = cx.cursor() 176 | ##查询 177 | cu.execute("select * from archives") 178 | for dsym in cu.fetchall(): 179 | if not os.path.exists(dsym[0]): 180 | execSql = "delete from archives where file_path ='%s'" % dsym[0] 181 | cu.execute(execSql) 182 | cx.commit() 183 | else: 184 | self.filesList.append(dsym[0])#[dsym[0] for dsym in cu.fetchall() if os.path.exists(dsym[0])] 185 | print self.filesList 186 | self.ShowFileType() 187 | 188 | #获取最后需要的文件地址 189 | def getFilePath(self, rootPath): 190 | if rootPath.endswith("dSYM"): 191 | self.dsymFilePath = rootPath 192 | fileName = os.path.basename(rootPath) 193 | else: 194 | dsymsPath = os.path.join(rootPath,'dSYMs') 195 | listFiles = os.listdir(dsymsPath) 196 | for fileName in listFiles: 197 | if fileName.endswith('dSYM'): 198 | #dsym文件路径 199 | self.dsymFilePath = os.path.join(dsymsPath, fileName) 200 | 201 | appPath = os.path.join(self.dsymFilePath,'Contents/Resources/DWARF') 202 | if os.path.isdir(appPath): 203 | if len(os.listdir(appPath)) is not 0: 204 | #命令行中需要的文件路径 205 | self.appFilePath = os.path.join(appPath,os.listdir(appPath)[0]) 206 | 207 | #显示关于我的界面 208 | def OnAboutMe(self, event): 209 | aboutMe = AboutMe(self) 210 | aboutMe.ShowModal() 211 | aboutMe.Destroy() 212 | 213 | versions = '1.0.3' 214 | if __name__ == '__main__': 215 | app = wx.App(redirect=False) 216 | frame = AHFrame(None, 'dSYM文件分析工具' + versions) 217 | frame.ShowWithEffect(True) 218 | app.MainLoop() 219 | -------------------------------------------------------------------------------- /wxPython/dSYMIcns.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/dSYMIcns.icns -------------------------------------------------------------------------------- /wxPython/donate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/donate.png -------------------------------------------------------------------------------- /wxPython/dsym.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/answer-huang/dSYMTools/ec7637f44a23e5854433c92fb10f1b48c15794e8/wxPython/dsym.db -------------------------------------------------------------------------------- /wxPython/setup.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | #打包命令 : python setup.py py2app 4 | 5 | __author__ = 'answer-huang' 6 | 7 | import sys 8 | reload(sys) 9 | sys.setdefaultencoding('utf8') 10 | 11 | 12 | from setuptools import setup 13 | 14 | APP = ['dSYM.py'] 15 | OPTIONS = { 16 | #'includes': ['about.png'], 17 | 'iconfile': 'dSYMIcns.icns', 18 | 'plist': {'CFBundleShortVersionString': '1.0.1', } 19 | } 20 | DATA_FILES = ['about.png', 'avatar.jpg', 'dsym.db', 'RunScript.py'] 21 | 22 | setup( 23 | app = APP, 24 | name= 'dSYM', 25 | data_files = DATA_FILES, 26 | options = {'py2app' : OPTIONS}, 27 | setup_requires=['py2app'] 28 | ) --------------------------------------------------------------------------------