├── .gitignore ├── .lldbinit ├── CHANGES ├── DataProviders ├── AppKit │ ├── NSImage+LLDBQuickLook.h │ ├── NSImage+LLDBQuickLook.m │ ├── NSView+LLDBQuickLook.h │ └── NSView+LLDBQuickLook.m ├── NSData+LLDBQuickLook.h ├── NSData+LLDBQuickLook.m ├── NSObject+LLDBQuickLook.h ├── NSObject+LLDBQuickLook.m ├── NSString+LLDBQuickLook.h ├── NSString+LLDBQuickLook.m └── UIKit │ ├── UIImage+LLDBQuickLook.h │ ├── UIImage+LLDBQuickLook.m │ ├── UIView+LLDBQuickLook.h │ └── UIView+LLDBQuickLook.m ├── LICENSE ├── LLDBQuickLook.podspec ├── README.md └── lldb_quick_look.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | -------------------------------------------------------------------------------- /.lldbinit: -------------------------------------------------------------------------------- 1 | # This file goes in your home directory and is run every time LLDB starts. 2 | # Importing the script below will make the 'ql' and 'qlf' available to you in LLDB. 3 | # IMPORTANT: Update the path to the script depending on where you decide place it. 4 | 5 | command script import ~/Library/lldbScripts/lldb_quick_look.py 6 | command alias ql quicklook 7 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | = 0.1.2 (2013-09-22) 2 | * Update podspec 3 | 4 | = 0.1.1 (2013-09-22) 5 | * Warning and error fixes to pass cocoapods validation 6 | 7 | = 0.1 (2013-09-22) 8 | 9 | * Add podspec (@gfontenot) 10 | 11 | * Initial version of tool 12 | -------------------------------------------------------------------------------- /DataProviders/AppKit/NSImage+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+LLDBQuickLook.h 3 | // Sweeper 4 | // 5 | // Created by Jay Chae on 7/18/14. 6 | // Copyright (c) 2014 JCLab. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSImage (LLDBQuickLook) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DataProviders/AppKit/NSImage+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage+LLDBQuickLook.m 3 | // Sweeper 4 | // 5 | // Created by Jay Chae on 7/18/14. 6 | // Copyright (c) 2014 JCLab. All rights reserved. 7 | // 8 | 9 | #import "NSImage+LLDBQuickLook.h" 10 | #import "NSObject+LLDBQuickLook.h" 11 | 12 | @implementation NSImage (LLDBQuickLook) 13 | 14 | - (NSData *)quickLookDebugData 15 | { 16 | NSBitmapImageRep *imageRepresentation = [[NSBitmapImageRep imageRepsWithData:[self TIFFRepresentation]] firstObject]; 17 | return [imageRepresentation representationUsingType:NSPNGFileType properties:nil]; 18 | } 19 | 20 | - (NSString *)quickLookDebugFilename 21 | { 22 | return [[super quickLookDebugFilename] stringByAppendingPathExtension:@"png"]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /DataProviders/AppKit/NSView+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+LLDBQuickLook.h 3 | // Sweeper 4 | // 5 | // Created by Jay Chae on 7/18/14. 6 | // Copyright (c) 2014 JCLab. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSView (LLDBQuickLook) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DataProviders/AppKit/NSView+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+LLDBQuickLook.m 3 | // Sweeper 4 | // 5 | // Created by Jay Chae on 7/18/14. 6 | // Copyright (c) 2014 JCLab. All rights reserved. 7 | // 8 | 9 | #import "NSView+LLDBQuickLook.h" 10 | #import "NSObject+LLDBQuickLook.h" 11 | 12 | @implementation NSView (LLDBQuickLook) 13 | 14 | - (NSData *)quickLookDebugData 15 | { 16 | NSBitmapImageRep *imageRepresentation = [self bitmapImageRepForCachingDisplayInRect:self.bounds]; 17 | [self cacheDisplayInRect:self.bounds toBitmapImageRep:imageRepresentation]; 18 | return [imageRepresentation representationUsingType:NSPNGFileType properties:nil]; 19 | } 20 | 21 | - (NSString *)quickLookDebugFilename 22 | { 23 | NSString *filename = [super quickLookDebugFilename]; 24 | return [filename stringByAppendingPathExtension:@"png"]; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /DataProviders/NSData+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+LLDBQuickLook.h 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | @interface NSData (LLDBQuickLook) 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /DataProviders/NSData+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+LLDBQuickLook.m 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "NSData+LLDBQuickLook.h" 30 | #import "NSObject+LLDBQuickLook.h" 31 | 32 | @implementation NSData (LLDBQuickLook) 33 | 34 | - (NSData *)quickLookDebugData 35 | { 36 | return self; 37 | } 38 | 39 | - (NSString *)quickLookDebugFilename 40 | { 41 | return [super quickLookDebugFilename]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /DataProviders/NSObject+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+LLDBQuickLook.h 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | // An informal protocol that objects can choose to implement if they will benefit from Quick Look debugging. 32 | // Default implementations are provided on NSObject to keep the debugger from barfing when it calls the selectors. 33 | @interface NSObject (LLDBQuickLook) 34 | 35 | // The data returned by this method will be saved to a tmp file by the lldb commands 'ql' and 'qlf'. 36 | // The tmp file will then be opened with Quick Look. 37 | - (NSData *)quickLookDebugData; 38 | 39 | // The filename returned by this method will be used for the tmp file. 40 | // Specifying a propper extension for the file helps Quick Look display the file 41 | // and choose an appropriate application to open the file. 42 | - (NSString *)quickLookDebugFilename; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /DataProviders/NSObject+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+LLDBQuickLook.m 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "NSObject+LLDBQuickLook.h" 30 | 31 | @implementation NSObject (LLDBQuickLook) 32 | 33 | // A default implementation so the debugger doesn't barf when calling the selector. 34 | - (NSData *)quickLookDebugData 35 | { 36 | return nil; 37 | } 38 | 39 | // The default filename consists of the class name of the object and a string of digits from the timestamp 40 | // There is no extension, as we don't have a good way to know what kind of file we're saving. 41 | // NSObject subclasses can use this base implementation, but should at least append an appropriate file extension. 42 | - (NSString *)quickLookDebugFilename 43 | { 44 | // By putting this into an unsigned int, we might loose the most significant digits. 45 | // That's ok, we really just care about a reasonably unique string for the filename. 46 | unsigned int timestampInMilliseconds = (unsigned int)([NSDate timeIntervalSinceReferenceDate] * 1000); 47 | NSString *className = NSStringFromClass([self class]); 48 | return [NSString stringWithFormat:@"%@_%u", className, timestampInMilliseconds]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DataProviders/NSString+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+LLDBQuickLook.h 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | @interface NSString (LLDBQuickLook) 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /DataProviders/NSString+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+LLDBQuickLook.m 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "NSString+LLDBQuickLook.h" 30 | #import "NSObject+LLDBQuickLook.h" 31 | 32 | @implementation NSString (LLDBQuickLook) 33 | 34 | - (NSData *)quickLookDebugData 35 | { 36 | return [NSData dataWithBytes:[self UTF8String] length:[self length]]; 37 | } 38 | 39 | - (NSString *)quickLookDebugFilename 40 | { 41 | return [[super quickLookDebugFilename] stringByAppendingPathExtension:@"txt"]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /DataProviders/UIKit/UIImage+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+LLDBQuickLook.h 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | @interface UIImage (LLDBQuickLook) 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /DataProviders/UIKit/UIImage+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+LLDBQuickLook.m 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "UIImage+LLDBQuickLook.h" 30 | #import "NSObject+LLDBQuickLook.h" 31 | 32 | @implementation UIImage (LLDBQuickLook) 33 | 34 | - (NSData *)quickLookDebugData 35 | { 36 | return UIImagePNGRepresentation(self); 37 | } 38 | 39 | - (NSString *)quickLookDebugFilename 40 | { 41 | return [[super quickLookDebugFilename] stringByAppendingPathExtension:@"png"]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /DataProviders/UIKit/UIView+LLDBQuickLook.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+LLDBQuickLook.h 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | @interface UIView (LLDBQuickLook) 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /DataProviders/UIKit/UIView+LLDBQuickLook.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+LLDBQuickLook.m 3 | // SlyBits 4 | // 5 | // Created by Ryan Olson on 9/15/13. 6 | // 7 | // The MIT License (MIT) 8 | // 9 | // Copyright (c) 2013 Ryan Olson 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | // this software and associated documentation files (the "Software"), to deal in 13 | // the Software without restriction, including without limitation the rights to 14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | // the Software, and to permit persons to whom the Software is furnished to do so, 16 | // subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in all 19 | // copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "UIView+LLDBQuickLook.h" 30 | #import "NSObject+LLDBQuickLook.h" 31 | #import 32 | 33 | @implementation UIView (LLDBQuickLook) 34 | 35 | - (NSData *)quickLookDebugData 36 | { 37 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0); 38 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 39 | UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 40 | UIGraphicsEndImageContext(); 41 | 42 | return UIImagePNGRepresentation(viewImage); 43 | } 44 | 45 | - (NSString *)quickLookDebugFilename 46 | { 47 | NSString *filename = [super quickLookDebugFilename]; 48 | return [filename stringByAppendingPathExtension:@"png"]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Ryan Olson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /LLDBQuickLook.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "LLDBQuickLook" 3 | s.version = "0.1.3" 4 | s.summary = "Quicklook support from the lldb console" 5 | 6 | s.description = <<-DESC 7 | Add Quicklook support to the LLDB Console. 8 | From the console use the `quicklook` or `ql` commands to generate a quicklook preview of the object 9 | 10 | Note that this only adds the data provider categories to the project. 11 | See the homepage for the rest of the installation instructions. 12 | DESC 13 | 14 | s.homepage = "https://github.com/ryanolsonk/LLDB-QuickLook" 15 | s.license = { :type => 'MIT', :file => 'LICENSE' } 16 | s.author = 'Ryan Olson' 17 | s.source = { :git => "https://github.com/ryanolsonk/LLDB-QuickLook.git", :tag => "#{s.version}" } 18 | s.source_files = 'DataProviders/**/*.{m,h}' 19 | s.ios.exclude_files = 'DataProviders/AppKit/*.{m,h}' 20 | s.osx.exclude_files = 'DataProviders/UIKit/*.{m,h}' 21 | s.framework = 'QuartzCore' 22 | s.requires_arc = true 23 | end 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LLDB-QuickLook 2 | ============== 3 | 4 | ![LLDB-QuickLook Example 1](http://f.cl.ly/items/2q2t253L3w130Q0Z3i1D/calendar.png) 5 | 6 | ![LLDB-QuickLook Example 2](http://f.cl.ly/items/0F381J0i2z3l291A1Q3U/background.png) 7 | 8 | LLDB-QuickLook is a debugger command to open images, views, and more using Quick Look. This command is great for inspecting any object that is not well represented by a string in the debugging console. The command is inspired by Xcode's new Quick Look feature, but is better in two ways: 9 | 10 | 1.) You can inspect any object accessible by an lldb expression, not just objects available in the Xcode GUI. 11 | 2.) Any type of object can be inspected by implementing a simple data provider protocol, not just UIImages. 12 | 13 | The command is quite simple. It asks an object in your program for debug data, saves the data to a tmp file on your computer, and opens the file using Finder and Quick Look. 14 | 15 | ## Getting Started 16 | 17 | 1. Clone the repository. 18 | 2. Copy the `.lldbinit` file to your home directory (or append the lines to your existing `.lldbinit`). 19 | 3. Update the path to `lldb_quick_look.py` in the `.lldbinit` file to match the script's location on your machine. 20 | 4. Add the `DataProviders` directory to your Xcode project. **LLDB-QuickLook requires Xcode 5 or later.** 21 | 5. To use the full version of quick look, ensure that "Enable access for assistive devices" setting is checked in System Preferences. 22 | 23 | ![Enable access for assistive devices](http://f.cl.ly/items/1Y060S3c2W0f321m3H1Y/enable-access-for-assistive-devices.png) 24 | 25 | ## Using the Command 26 | 27 | When your program is paused on a breakpoint in lldb, calling the command: 28 | 29 | `quicklook ` or `ql ` 30 | 31 | will ask the object for its `quickLookDebugData` and save that data to the object's `quickLookFilename`. The file will be saved under `/tmp/` and opened using Finder + Quick Look. You can make any object into a Quick Look data provider by simply implementing the `quickLookDebugData` and `quickLookFilename` methods. Simple implementations of data providers for `NSObject`, `UIImage`, `UIView`, `NSData`, and `NSString` can be found in the `DataProviders` directory. 32 | 33 | ## Examples 34 | 35 | `(lldb) quicklook self.imageView.image` 36 | 37 | `(lldb) ql [[UIApplication sharedApplication] keyWindow]` 38 | 39 | `(lldb) quicklook -f some_object.json -- [self jsonString]` 40 | 41 | `(lldb) ql -l self.view` 42 | 43 | ## Some use cases 44 | 45 | * Debugging images not accessible from the Xcode GUI. 46 | * Debugging views that are not on screen or obscured by another view. 47 | * Saving images for screenshots or to watch a view change over time. 48 | * Opening text in a proper editor without having to copy/paste from the console. 49 | 50 | Tip: type `help quicklook` from the lldb prompt to see the options for the command. 51 | 52 | ## About 53 | 54 | `quicklook` uses lldb's powerful (but poorly documented) python scripting bridge. I don't typically write in python, so apologies if I've mixed in some objective-c style conventions. If you have any ideas, comments, or feedback, I'm [@ryanolsonk](http://twitter.com/ryanolsonk) on twitter, and pull requests are welcome! 55 | -------------------------------------------------------------------------------- /lldb_quick_look.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | # Copyright (c) 2013 Ryan Olson 4 | 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | # this software and associated documentation files (the "Software"), to deal in 7 | # the Software without restriction, including without limitation the rights to 8 | # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | # the Software, and to permit persons to whom the Software is furnished to do so, 10 | # 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, FITNESS 17 | # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 23 | import lldb 24 | import os 25 | import subprocess 26 | import optparse 27 | import shlex 28 | 29 | 30 | class DebuggerError(Exception): 31 | """ 32 | Exception raised when when a debugger command cannot proceed due to bad state or invalid input 33 | """ 34 | pass 35 | 36 | 37 | def create_quick_look_options(): 38 | usage = "usage: %prog -- " 39 | parser = optparse.OptionParser(prog='quicklook', usage=usage) 40 | parser.add_option('-f', '--filename', type='string', dest='filename', help='Override filename for saving the data', metavar='filename.ext') 41 | parser.add_option('-l', '--lite', action='store_true', dest='lite', help='Use the stripped down version of Quick Look (qlmanage)', default=False) 42 | return parser 43 | 44 | 45 | def quick_look_command(debugger, command, result, internal_dict): 46 | """ 47 | Overview: 48 | 49 | A command to inspect objects that are not well represented by strings in the debug console. 50 | The command will ask an object for its quickLookDebugData and save that data to the object's 51 | quickLookFilename or a custom filename passed using the -f option. The file will be saved under /tmp/ 52 | You can make any object into a quick look data provider by simply implementing the quickLookDebugData and quickLookFilename methods. 53 | 54 | Examples: 55 | 56 | quicklook self.imageView.image 57 | quicklook [[UIApplication sharedApplication] keyWindow] 58 | 59 | Some use cases: 60 | 61 | Debugging images not accessible from the Xcode GUI. 62 | Debugging views that are not on screen or obscured by another view. 63 | Saving images for screenshots or to watch a view change over time. 64 | Opening text in a propper editor without having to copy/paste. 65 | 66 | IMPORTANT NOTE: 67 | 68 | Because this command takes 'raw' input, if you use any 69 | command options you must use ' -- ' between the end of the command options 70 | and the beginning of the raw input. 71 | 72 | 73 | """ 74 | 75 | # Separate the options from the expression 76 | command_list = shlex.split(command) 77 | try: 78 | # "--" indicates the end of the arguments and beginning of the expression 79 | dashdash_idx = command_list.index("--") 80 | arguments = command_list[:dashdash_idx] 81 | # strip everything up to and including the "-- " to get the expression 82 | expression = command[(command.rindex("--") + 3):] 83 | except ValueError: 84 | # no "--" found, assume no arguments 85 | arguments = [] 86 | expression = command 87 | 88 | 89 | # Parse the options 90 | parser = create_quick_look_options() 91 | try: 92 | (options, args) = parser.parse_args(arguments) 93 | except: 94 | result.SetError("Option parsing failed") 95 | return 96 | 97 | 98 | # Save the data 99 | try: 100 | savedFilePath = get_data_and_save(debugger, expression, options.filename) 101 | print >> result, "Data written to {0!s}".format(savedFilePath) 102 | except DebuggerError, err: 103 | result.SetError(str(err)) 104 | return 105 | 106 | 107 | # Open with Quick Look 108 | if options.lite: 109 | open_with_quick_look_lite(savedFilePath) 110 | else: 111 | open_with_quick_look(savedFilePath) 112 | 113 | 114 | def open_with_quick_look(filePath): 115 | """ 116 | If "Enable access for assistive devices" is checked in system preferences, this method 117 | will use AppleScript to open the finder and trigger Quick Look. Otherwise, it falls 118 | back to the lightweight "qlmanage" program (intended for debugging Quick Look, 119 | but invokable from the command line). 120 | filePath must be absolute 121 | e.g. open_with_quick_look("/tmp/file.png") 122 | """ 123 | 124 | # Use the full quick look if GUI scripting is enabled 125 | if os.path.exists("/private/var/db/.AccessibilityAPIEnabled"): 126 | 127 | qlAppleScript = """ 128 | set theFile to ("{0}" as POSIX file) 129 | tell application "Finder" 130 | activate 131 | open (container of file theFile) 132 | select theFile 133 | end tell 134 | 135 | tell application "System Events" to keystroke "y" using command down 136 | """.format(filePath) 137 | 138 | osaProcess = subprocess.Popen(["osascript", "-"], stdin=subprocess.PIPE) 139 | osaProcess.communicate(qlAppleScript) 140 | 141 | # Fall back to the pseudo quick look 142 | else: 143 | open_with_quick_look_lite(filePath) 144 | 145 | 146 | def open_with_quick_look_lite(filePath): 147 | subprocess.Popen(["qlmanage", "-p", filePath]) 148 | 149 | 150 | def get_data_and_save(debugger, expression, overrideFilename): 151 | """ 152 | Asks the object passed in expression for its debugData and debugFilename. 153 | Saves the data to the filename under /tmp/{target} 154 | Raises DebuggerError exceptions for bad state or invalid commands 155 | Returns the path of the saved file in the success case. 156 | """ 157 | target = debugger.GetSelectedTarget() 158 | process = target.GetProcess() 159 | thread = process.GetSelectedThread() 160 | frame = thread.GetSelectedFrame() 161 | 162 | if not target.IsValid() or not process.IsValid(): 163 | raise DebuggerError("Unable to get target/process") 164 | 165 | options = lldb.SBExpressionOptions() 166 | options.SetIgnoreBreakpoints() 167 | 168 | dataCommand = "(NSData *)[({0!s}) quickLookDebugData]".format(expression) 169 | if frame.IsValid(): 170 | data = frame.EvaluateExpression(dataCommand, options) 171 | else: 172 | data = target.EvaluateExpression(dataCommand, options) 173 | 174 | if data.GetValueAsUnsigned() == 0: 175 | raise DebuggerError("Can't get debug data from {0!s}. Make sure the object has a non-nil response to the selector quickLookDebugData".format(expression)) 176 | 177 | lengthCommand = "(NSUInteger)[({0!s}) length]".format(data.path) 178 | length = target.EvaluateExpression(lengthCommand, options).GetValueAsUnsigned() 179 | 180 | bytesCommand = "(const void *)[({0!s}) bytes]".format(data.path) 181 | bytes = target.EvaluateExpression(bytesCommand, options).GetValueAsUnsigned() 182 | 183 | error = lldb.SBError() 184 | memoryBuffer = process.ReadMemory(bytes, length, error) 185 | if error.Fail(): 186 | raise DebuggerError("Couldn't read memory: {0!s}".format(error)) 187 | 188 | directory = os.path.join("/tmp", str(target)) 189 | if not os.path.exists(directory): 190 | os.makedirs(directory) 191 | 192 | # If a filename was not specfied with the command, ask the expression for it 193 | if overrideFilename is None: 194 | filenameCommand = "(NSString *)[({0!s}) quickLookDebugFilename]".format(expression) 195 | if frame.IsValid(): 196 | filename = frame.EvaluateExpression(filenameCommand, options).GetObjectDescription() 197 | else: 198 | filename = target.EvaluateExpression(filenameCommand, options).GetObjectDescription() 199 | else: 200 | filename = overrideFilename 201 | 202 | if filename is None: 203 | raise DebuggerError("No filename provided. Please specify one in quickLookDebugFilename or by passing a name in the -f option") 204 | 205 | path = os.path.join(directory, str(filename)) 206 | with open(path, "w") as dataFile: 207 | dataFile.write(memoryBuffer) 208 | 209 | return path 210 | 211 | 212 | def __lldb_init_module(debugger, internal_dict): 213 | parser = create_quick_look_options() 214 | quick_look_command.__doc__ = quick_look_command.__doc__ + parser.format_help() 215 | debugger.HandleCommand('command script add --function lldb_quick_look.quick_look_command quicklook') 216 | 217 | --------------------------------------------------------------------------------