├── .gitignore ├── .hgignore ├── BUILD ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ResumableAssert.h ├── ResumableAssert.podspec ├── Sources └── ResumableAssert │ ├── ResumableAssert.m │ └── include │ ├── ResumableAssert.h │ └── module.modulemap └── WORKSPACE /.gitignore: -------------------------------------------------------------------------------- 1 | # Generic build products 2 | 3 | *.[oa] 4 | [Bb]uild/ 5 | [Pp]re-[Bb]uild/ 6 | [Dd]eliverables/ 7 | [Dd]istribution/ 8 | [Dd]ocumentation/ 9 | [Dd]ocs/ 10 | 11 | # Swift PM 12 | 13 | Packages/ 14 | .build/ 15 | *.xcodeproj 16 | *.resolved 17 | 18 | # Bazel 19 | 20 | bazel-* 21 | 22 | # Other VCS 23 | 24 | .hg 25 | .svn 26 | *.prej 27 | *.mine 28 | CVS 29 | 30 | # OSX 31 | 32 | .DS_Store 33 | .DS_Store? 34 | ._* 35 | .~* 36 | ~$* 37 | *.lock 38 | .AppleDouble 39 | .LSOverride 40 | .DocumentRevisions-V100 41 | .fseventsd 42 | .Spotlight-V100 43 | .TemporaryItems 44 | .Trashes 45 | ehthumbs.db 46 | Thumbs.db 47 | .AppleDB 48 | .AppleDesktop 49 | .apdisk 50 | 51 | # Windows 52 | 53 | Thumbs.db 54 | ehthumbs.db 55 | Desktop.ini 56 | $RECYCLE.BIN/ 57 | *.cab 58 | *.msi 59 | *.msm 60 | *.msp 61 | *.lnk 62 | 63 | # Xcode 64 | 65 | DerivedData/ 66 | xcuserdata/ 67 | project.xcworkspace/ 68 | *.mode1 69 | *.mode1v3 70 | *.mode2v3 71 | *.perspective 72 | *.perspectivev3 73 | *.pbxuser 74 | *.xccheckout 75 | *.moved-aside 76 | *.xcuserstate 77 | *.xctimeline 78 | 79 | # JetBrains 80 | 81 | .idea/ 82 | 83 | # CocoaPods 84 | 85 | !Podfile.lock 86 | !Pods/Manifest.lock 87 | Pods/Documentation 88 | 89 | #Carthage 90 | 91 | Carthage/ 92 | 93 | # SublimeText 94 | 95 | *.tmlanguage.cache 96 | *.tmPreferences.cache 97 | *.stTheme.cache 98 | *.sublime-workspace 99 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | 3 | # Generic build products 4 | 5 | *.[oa] 6 | [Bb]uild/ 7 | [Pp]re-[Bb]uild/ 8 | [Dd]eliverables/ 9 | [Dd]istribution/ 10 | [Dd]ocumentation/ 11 | [Dd]ocs/ 12 | 13 | # Swift PM 14 | 15 | Packages/ 16 | .build/ 17 | *.xcodeproj 18 | *.resolved 19 | 20 | # Bazel 21 | 22 | bazel-* 23 | 24 | # Other VCS 25 | 26 | .hg 27 | .svn 28 | *.prej 29 | *.mine 30 | CVS 31 | 32 | # OSX 33 | 34 | .DS_Store 35 | .DS_Store? 36 | ._* 37 | .~* 38 | ~$* 39 | *.lock 40 | .AppleDouble 41 | .LSOverride 42 | .DocumentRevisions-V100 43 | .fseventsd 44 | .Spotlight-V100 45 | .TemporaryItems 46 | .Trashes 47 | ehthumbs.db 48 | Thumbs.db 49 | .AppleDB 50 | .AppleDesktop 51 | .apdisk 52 | 53 | # Windows 54 | 55 | Thumbs.db 56 | ehthumbs.db 57 | Desktop.ini 58 | $RECYCLE.BIN/ 59 | *.cab 60 | *.msi 61 | *.msm 62 | *.msp 63 | *.lnk 64 | 65 | # Xcode 66 | 67 | DerivedData/ 68 | xcuserdata/ 69 | project.xcworkspace/ 70 | *.mode1 71 | *.mode1v3 72 | *.mode2v3 73 | *.perspective 74 | *.perspectivev3 75 | *.pbxuser 76 | *.xccheckout 77 | *.moved-aside 78 | *.xcuserstate 79 | *.xctimeline 80 | 81 | # JetBrains 82 | 83 | .idea/ 84 | 85 | # CocoaPods 86 | 87 | !Podfile.lock 88 | !Pods/Manifest.lock 89 | Pods/Documentation 90 | 91 | #Carthage 92 | 93 | Carthage/ 94 | 95 | # SublimeText 96 | 97 | *.tmlanguage.cache 98 | *.tmPreferences.cache 99 | *.stTheme.cache 100 | *.sublime-workspace 101 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | licenses(["notice"]) # Apache 2.0 4 | 5 | exports_files(["LICENSE"]) 6 | 7 | OBJC_COPTS = [ 8 | "-Werror", 9 | "-Wextra", 10 | "-Wall", 11 | "-Wstrict-prototypes", 12 | "-Wdocumentation", 13 | ] 14 | 15 | objc_library( 16 | name = "ResumableAssert", 17 | srcs = glob([ 18 | "Sources/ResumableAssert/*.m", 19 | ]), 20 | hdrs = glob([ 21 | "Sources/ResumableAssert/include/*.h", 22 | ]) + [ 23 | "ResumableAssert.h", 24 | ], 25 | copts = OBJC_COPTS, 26 | includes = [ 27 | "Sources/ResumableAssert/include", 28 | ], 29 | module_map = "Sources/ResumableAssert/include/module.modulemap", 30 | ) 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute # 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few guidelines you need to follow. 5 | 6 | ## Contributor License Agreement ## 7 | 8 | Contributions to any Google project must be accompanied by a Contributor 9 | License Agreement. This is not a copyright **assignment**, it simply gives 10 | Google permission to use and redistribute your contributions as part of the 11 | project. 12 | 13 | * If you are an individual writing original source code and you're sure you 14 | own the intellectual property, then you'll need to sign an [individual 15 | CLA][]. 16 | 17 | * If you work for a company that wants to allow you to contribute your work, 18 | then you'll need to sign a [corporate CLA][]. 19 | 20 | You generally only need to submit a CLA once, so if you've already submitted 21 | one (even if it was for a different project), you probably don't need to do it 22 | again. 23 | 24 | [individual CLA]: https://developers.google.com/open-source/cla/individual 25 | [corporate CLA]: https://developers.google.com/open-source/cla/corporate 26 | 27 | 28 | ## Submitting a patch ## 29 | 30 | 1. It's generally best to start by opening a new issue describing the bug or 31 | feature you're intending to fix. Even if you think it's relatively minor, 32 | it's helpful to know what people are working on. Mention in the initial 33 | issue that you are planning to work on that bug or feature so that it can 34 | be assigned to you. 35 | 36 | 1. Follow the normal process of [forking][] the project, and setup a new 37 | branch to work in. It's important that each group of changes be done in 38 | separate branches in order to ensure that a pull request only includes the 39 | commits related to that bug or feature. 40 | 41 | 1. Any significant changes should almost always be accompanied by tests. The 42 | project already has good test coverage, so look at some of the existing 43 | tests if you're unsure how to go about it. 44 | 45 | 1. Do your best to have [well-formed commit messages][] for each change. 46 | This provides consistency throughout the project, and ensures that commit 47 | messages are able to be formatted properly by various git tools. 48 | 49 | 1. Finally, push the commits to your fork and submit a [pull request][]. 50 | 51 | [forking]: https://help.github.com/articles/fork-a-repo 52 | [well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 53 | [pull request]: https://help.github.com/articles/creating-a-pull-request 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Apache 2 | License](https://img.shields.io/github/license/google/resumable-assert.svg)](LICENSE) 3 | 4 | # Resumable Assert 5 | 6 | ![](https://gist.githubusercontent.com/shoumikhin/56ca2bf71e6b469d71488a50eb9f293b/raw/ce1860cfc638fa42247d814863e9abbd680e0edb/demo.gif) 7 | 8 | ## Assert replacement to continue execution in debugger 9 | 10 | In any large app, it sometimes happens that some asserts are failing in code you 11 | don't currently care about, and blocking the entire team from being able to run 12 | the app until the issue is fixed is not the best workflow. So we usually end up 13 | moving the execution marker past the assert line in IDE or debugger, or even 14 | comment the assert out, recompile and relaunch. With Resumable Assert, you can 15 | simply continue execution when an assertion fails in debugger, or even disable 16 | asserts that you are not interested in, so that those never bother you again. 17 | 18 | _Disclaimer: be careful with that power though, since execution of potentially 19 | broken code may lead to unrecoverable errors in future._ 20 | 21 | ## C/C++/Objective-C 22 | 23 | First, include or import the header: 24 | 25 | ```objectivec 26 | #import "ResumableAssert.h" 27 | ``` 28 | 29 | Then, use the `RESUMABLE_ASSERT()` or `RESUMABLE_ASSERT_WITH_FORMAT()` macros 30 | instead of the standard ones: 31 | [`assert()`](http://en.cppreference.com/w/c/error/assert), 32 | [`NSAssert()`](https://developer.apple.com/documentation/foundation/nsassert), 33 | etc. 34 | 35 | Once `RESUMABLE_ASSERT()` variant is hit in debug mode, you can ignore it and 36 | continue execution, or disable it permanently, or even disable all asserts 37 | permanently with corresponding `lldb` commands when prompted. 38 | 39 | For example, the following assert somewhere in `ViewController.viewDidLoad` 40 | method: 41 | 42 | ```c 43 | RESUMABLE_ASSERT(2 + 2 == 5); 44 | ``` 45 | 46 | Or: 47 | 48 | ```c 49 | RESUMABLE_ASSERT_WITH_FORMAT(2 + 2 == 5, "Calculation error"); 50 | ``` 51 | 52 | Leads to the following debugger console output: 53 | 54 | ```sh 55 | ViewController.m:-[ViewController viewDidLoad]:42 56 | Assertion failed: 2 + 2 == 5 57 | Calculation error 58 | Continue execution or issue one of the following lldb commands: 59 | e disable = 1 # disable this assert permanently 60 | e unleash = 1 # disable all asserts permanently 61 | ``` 62 | 63 | Where you can just continue execution, or additionally disable the assert: 64 | 65 | ```sh 66 | (lldb) e disable = 1 67 | (volatile int) $1 = 1 68 | (lldb) c 69 | Process 11193 resuming 70 | ``` 71 | 72 | ## Custom logging 73 | 74 | `RESUMABLE_ASSERT()` macro in C uses `stdout` to print the failure message by 75 | default. To change this behavior and use something else for logging, 76 | (e.g. [`NSLog()`](https://developer.apple.com/documentation/foundation/1395275-nslog)) 77 | redefine the `RESUMABLE_ASSERT_LOG()` macro in C like so: 78 | 79 | ```objectivec 80 | #import 81 | 82 | #include "ResumableAssert.h" 83 | 84 | #undef RESUMABLE_ASSERT_LOG 85 | #define RESUMABLE_ASSERT_LOG(condition, format, ...) \ 86 | do { \ 87 | NSLog(@"%s:%u\nAssertion failed: %s\n" format, \ 88 | __PRETTY_FUNCTION__, __LINE__, condition, ##__VA_ARGS__); \ 89 | } while (0) 90 | ``` 91 | 92 | Similarly, you can define your own assert macro with a custom name: 93 | 94 | ```objectivec 95 | #define ASSERT_WITH_FORMAT(condition, format, ...) \ 96 | RESUMABLE_ASSERT_WITH_FORMAT(condition, format, ##__VA_ARGS__) 97 | #define ASSERT(condition) ASSERT_WITH_FORMAT(condition, "") 98 | ``` 99 | 100 | ## Swift 101 | 102 | For Swift and other languages, we provide `ResumableAssertDebugTrap()` function 103 | that implements the core logic of resumable assert. You can then implement 104 | a custom `assert()` function somewhere in a custom `Diagnostics` module which 105 | would use `ResumableAssertDebugTrap()` internally: 106 | 107 | ```swift 108 | import ResumableAssert // Import the module or use a bridging header and import ResumableAssert.h. 109 | 110 | public func assert( 111 | _ condition: @autoclosure () -> Bool, 112 | _ message: @autoclosure () -> String = "", 113 | file: StaticString = #file, 114 | function: StaticString = #function, 115 | line: UInt = #line 116 | ) { 117 | #ifdef DEBUG 118 | if !condition() { 119 | NSLog("Assertion failed:" + " \(message()):" + 120 | " file \(file.description), function \(function.description), line \(line)") 121 | ResumableAssertDebugTrap() 122 | } 123 | #endif 124 | } 125 | ``` 126 | 127 | Then, you can use the new function as: 128 | 129 | ```swift 130 | Diagnostics.assert(2 + 2 == 5, "Calculation error") 131 | ``` 132 | 133 | ## Setup 134 | 135 | ### Bazel 136 | 137 | In your `BUILD` file, add `ResumableAssert` deps to corresponding targets: 138 | 139 | ```python 140 | objc_library( 141 | # ... 142 | deps = [ 143 | "//path/to/ResumableAssert", 144 | ], 145 | # ... 146 | ) 147 | ``` 148 | 149 | Include or import the header: 150 | 151 | ```objectivec 152 | #import "path/to/ResumableAssert/ResumableAssert.h" 153 | ``` 154 | 155 | ### CocoaPods 156 | 157 | To use `ResumableAssert` for Objective-C, add the following to your `Podfile`: 158 | 159 | ```ruby 160 | pod 'ResumableAssert', '~> 1.0' 161 | ``` 162 | 163 | Then, run `pod install` and import the umbrella header in generated project: 164 | 165 | ```objectivec 166 | #import 167 | ``` 168 | 169 | Or, the module: 170 | 171 | ```objectivec 172 | @import ResumableAssert; 173 | ``` 174 | -------------------------------------------------------------------------------- /ResumableAssert.h: -------------------------------------------------------------------------------- 1 | Sources/ResumableAssert/include/ResumableAssert.h -------------------------------------------------------------------------------- /ResumableAssert.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'ResumableAssert' 3 | s.version = '1.0.0' 4 | s.authors = 'Google Inc.' 5 | s.license = { :type => 'Apache', :file => 'LICENSE' } 6 | s.homepage = 'https://github.com/google/resumable-assert' 7 | s.source = { :git => 'https://github.com/google/resumable-assert.git', :tag => s.version } 8 | s.summary = 'Assert replacement to continue execution in debugger' 9 | s.description = <<-DESC 10 | 11 | ResumableAssert allows to ignore or disable assertion failure and continue execution in debugger. 12 | DESC 13 | 14 | s.ios.deployment_target = '9.0' 15 | s.osx.deployment_target = '10.10' 16 | s.tvos.deployment_target = '9.0' 17 | s.swift_version = '4.0' 18 | 19 | s.prefix_header_file = false 20 | s.public_header_files = "Sources/#{s.name}/include/**/*.h" 21 | s.source_files = "Sources/#{s.name}/**/*.{h,m}" 22 | s.xcconfig = { 23 | 'HEADER_SEARCH_PATHS' => "\"${PODS_TARGET_SRCROOT}/Sources/#{s.name}/include\"" 24 | } 25 | end 26 | -------------------------------------------------------------------------------- /Sources/ResumableAssert/ResumableAssert.m: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2018 Google Inc. All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "ResumableAssert.h" 18 | 19 | #include 20 | #include 21 | 22 | int gResumableAssertsAreAllDisabled; 23 | 24 | void ResumableAssertDebugTrap() { 25 | #ifdef RESUMABLE_ASSERT_DEBUG_TRAP 26 | RESUMABLE_ASSERT_DEBUG_TRAP(); // See the debugger console and continue. 27 | #endif // RESUMABLE_ASSERT_DEBUG_TRAP 28 | } 29 | 30 | int ResumableAssertIsDebuggerAttached() { 31 | // See http://developer.apple.com/library/mac/#qa/qa1361/_index.html 32 | int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; 33 | struct kinfo_proc info; 34 | size_t size = sizeof(info); 35 | return sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) == 0 ? 36 | (info.kp_proc.p_flag & P_TRACED) != 0 : 0; 37 | } 38 | -------------------------------------------------------------------------------- /Sources/ResumableAssert/include/ResumableAssert.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2018 Google Inc. All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef RESUMABLE_ASSERT_H_ 18 | #define RESUMABLE_ASSERT_H_ 19 | 20 | #include 21 | 22 | // Redefine RESUMABLE_ASSERT_LOG with a proper logging implementation if needed. 23 | #define RESUMABLE_ASSERT_LOG(condition, format, ...) \ 24 | do { \ 25 | printf("%s:%s:%u\nAssertion failed: %s\n" format, \ 26 | __FILE__, __PRETTY_FUNCTION__, __LINE__, condition, ##__VA_ARGS__); \ 27 | } while (0) 28 | 29 | extern 30 | #ifdef __cplusplus 31 | "C" 32 | #endif 33 | // Helper function that wraps RESUMABLE_ASSERT_DEBUG_TRAP to use it in other 34 | // languages. 35 | void ResumableAssertDebugTrap(void); 36 | 37 | #ifndef DEBUG 38 | 39 | #define RESUMABLE_ASSERT_WITH_FORMAT(condition, format, ...) \ 40 | do {} while (0) 41 | #define RESUMABLE_ASSERT(condition) \ 42 | do {} while (0) 43 | 44 | #else // #ifndef DEBUG 45 | 46 | extern int gResumableAssertsAreAllDisabled; 47 | 48 | extern 49 | #ifdef __cplusplus 50 | "C" 51 | #endif 52 | int ResumableAssertIsDebuggerAttached(void); 53 | 54 | // RESUMABLE_DEBUG_BREAK is same as __builtin_trap, but allows resuming 55 | // execution after the break. 56 | #if __i386__ || __x86_64__ 57 | #define RESUMABLE_ASSERT_DEBUG_BREAK() asm("int3") 58 | #elif __arm__ 59 | #define RESUMABLE_ASSERT_DEBUG_BREAK() \ 60 | asm("mov r0, %0 \n" /* PID */ \ 61 | "mov r1, 0x11 \n" /* SIGSTOP */ \ 62 | "mov r12, 0x25 \n" /* syscall kill */ \ 63 | "svc 0x80 \n" /* software interrupt */ \ 64 | "mov r0, r0 \n" /* nop to pause debugger here */ \ 65 | ::"r"(getpid()) \ 66 | : "r0", "r1", "r12", "memory") 67 | #elif __arm64__ 68 | #define RESUMABLE_ASSERT_DEBUG_BREAK() \ 69 | asm("mov x0, %x0 \n" /* PID */ \ 70 | "mov x1, 0x11 \n" /* SIGSTOP */ \ 71 | "mov x16, 0x25 \n" /* syscall kill */ \ 72 | "svc 0x80 \n" /* software interrupt */ \ 73 | "mov x0, x0 \n" /* nop to pause debugger here */ \ 74 | ::"r"(getpid()) \ 75 | : "x0", "x1", "x16", "memory") 76 | #else 77 | #error "Unsupported architecture." 78 | #endif // __i386__ || __x86_64__ 79 | 80 | #define RESUMABLE_ASSERT_DEBUG_TRAP() \ 81 | do { \ 82 | static volatile int gResumableAssertIsDisabled; \ 83 | if (gResumableAssertIsDisabled || gResumableAssertsAreAllDisabled) break; \ 84 | if (!ResumableAssertIsDebuggerAttached()) __builtin_trap(); \ 85 | fprintf(stderr, \ 86 | "\nContinue execution or issue one of the following lldb commands:\n" \ 87 | "e disable = 1 # disable this assert permanently\n" \ 88 | "e unleash = 1 # disable all asserts permanently\n\n"); \ 89 | volatile int disable = 0, unleash = 0; \ 90 | RESUMABLE_ASSERT_DEBUG_BREAK(); \ 91 | gResumableAssertIsDisabled = disable; \ 92 | gResumableAssertsAreAllDisabled = unleash; \ 93 | } while (0) 94 | 95 | #define RESUMABLE_ASSERT_WITH_FORMAT(condition, format, ...) \ 96 | do { \ 97 | if (__builtin_expect(!(condition), 0)) { \ 98 | RESUMABLE_ASSERT_LOG(#condition, format, ##__VA_ARGS__); \ 99 | RESUMABLE_ASSERT_DEBUG_TRAP(); \ 100 | } \ 101 | } while (0) 102 | 103 | #define RESUMABLE_ASSERT(condition) \ 104 | RESUMABLE_ASSERT_WITH_FORMAT(condition, "") 105 | 106 | #endif // #ifndef DEBUG 107 | 108 | #endif // RESUMABLE_ASSERT_H_ 109 | -------------------------------------------------------------------------------- /Sources/ResumableAssert/include/module.modulemap: -------------------------------------------------------------------------------- 1 | module ResumableAssert { 2 | umbrella header "ResumableAssert.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | http_archive( 2 | name = "build_bazel_rules_apple", 3 | strip_prefix = "rules_apple-0.2.0", 4 | urls = ["https://github.com/bazelbuild/rules_apple/archive/0.2.0.tar.gz"], 5 | ) 6 | --------------------------------------------------------------------------------