• Stars
    star
    395
  • Rank 109,040 (Top 3 %)
  • Language Objective-C++
  • License
    MIT License
  • Created over 10 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Live Memory Browser for Apps & Xcode

Icon Xprobe Realtime Memory Browser

Update: This former Xcode plugin has been re-organised into a Swift Package for use in other apps. Use the Xprobe product in client applications and the XprobeUI product at the server side.

The XprobePlugin gives you a view of the objects inside your application either in detail down to the level of ivars or globally as a graph of the principal objects and how they are connected. This display can be animated in real time, highlighting in red objects as they are messaged and the paths down which messages are flowing. This is done automatically by performing a "sweep" to find all objects referred to by a set of seeds, the objects they refer to, the objects those refer to and so forth to build up the list of live objects which can be displayed in Xcode:

Icon

In the simulator, the memory sweeper is loaded from a bundle inside the plugin using lldb requiring no changes to the app's project source. To use the plugin, build this project and restart Xcode. Once your application is running, use menu item "Product/Xprobe/Load" to load the initial view of the memory sweep of your app. If you are a plugin developer you use "Product/Xprobe/Xcode" to inspect the objects of the Xcode application itself.

You can then filter the objects listed into the app or their methods using a pattern. If there are no objects matching the pattern and it is a class name it will be displayed. Patterns prefixed with '+' or '-' will search all classes linked into the application for methods matching the pattern. A raw pointer prefixed with "0x" can be entered to inspect an object passed as an argument to a trace. You can also enter an object "path" starting "seed." from the paths logged as you browse your application so you can find your way back to objects easily.

If you have the injectionforxcode plugin installed Xprobe will allow you to evaluate Objective-C or Swift against a selected instance for which you have the source to log or modify any aspect of the object's state at run time.

Stop Press:

Xprobe.mm can now snapshot your app to a standalone html file in the event of an error. This performs a sweep and can document the state of your app at the time the error occured for later analysis. An example snapshot file for a ReactNative example project "TickTackToe" can be viewed here.

To take a snapshot, include Xprobe.mm in your app and use the following call:

    [Xprobe snapshot:@"/path/to/snapshot.html.gz" seeds:@[app delegate, rootViewController]];

If you run into difficulties you can alter the pattern of classe names not to capture with an additional excluding:(NSString *)pattern argument. The default value for this is:

    @"^(?:UI|NS((Object|URL|Proxy)$|Text|Layout|Index|.*(Map|Data|Font))|Web|WAK|SwiftObject|XC|IDE|DVT|Xcode3|IB|VK)"

The remaining features are most easily rolled off as a series of bullet points:

Icon

Click on an object's link to view it's ivar contents.

Click the link again to close the detail view.

Click on the superclass link to view it's ivars

Click on an ivar name to refresh it's value from the app

Click on an ivar value to edit and set it's value in the app

The class' properties, methods and any protocols can be viewed.

The method lists can be searched (also finding superclass methods)

Use the "trace" link to start logging calls to methods on that instance.

To see all methods traced for an object, click trace against each class.

Trace output can be filtered using a regular expression

The subviews link will recursively display the tree of subviews under a view.

The "render" link will capture an image when the object is a view.

The siblings link will display all objects found that share the object's class.

Refresh the object list by typing enter in the Search Field to force a new sweep.

Pressing the Graph button will open the summary view of the most important objects and any "kit" objects directly linked to them taken from the last sweep.

The object is represented as a square if is it a view (responds to "subviews".)

Graph display requires an installation of "Graphviz/dot" on your computer.

Click on an object to view it's current contents as discussed above.

Differing filtering of which objects to include can be applied.

"Animate Messages" puts a trace on objects having them display "red" when messaged.

Graphs can be exported to Graphviz or .png format for printing.

Alas, Swift support is limited at the moment as ivar_getTypeEncoding() returns NULL for ivar fields preventing them taking part in the "sweep".

Use on a device.

Xprobe works by loading a bundle in the simulator which connects to Xcode when it is loaded. An application makes its list of seed nodes known to Xprobe by implementing the following category:

    @implementation Xprobe(Seeding)

    + (NSArray *)xprobeSeeds {
        UIApplication *app = [UIApplication sharedApplication];
        NSMutableArray *seeds = [NSMutableArray arrayWithObject:app];
        [seeds addObjectsFromArray:[app windows]];

        // support for cocos2d
        Class ccDirectorClass = NSClassFromString(@"CCDirector");
        CCDirector *ccDirector = [ccDirectorClass sharedDirector];
        if ( ccDirector )
            [seeds addObject:ccDirector];

        return seeds;
    }

    @end

Or for OSX:

    + (NSArray *)xprobeSeeds {
        NSApplication *app = [NSApplication sharedApplication];
        NSMutableArray *seeds = [[app windows] mutableCopy];
        if ( app.delegate )
            [seeds insertObject:app.delegate atIndex:0];
        return seeds;
    }

Once an app is initialised call [Xprobe connectTo:"your.ip.address" retainObjects:YES] to connect to the TCP server running inside Xcode. The retainObjects: argument specifies whether to retain objects found in the sweep. This will make Xprobe more reliable but it will affect object life-cycles in your app. After this, call [Xprobe search:@""] to perform the initial sweep starting at these objects looking for root objects. Each time "search:" is called or the object class filter is changed the sweep is performed anew. The application will need to be built with Xprobe and Xtrace.{h,mm}.

In this day and age of nice clean "strong" and "weak" pointers the sweep seems very reliable if objects are somehow visible to the seeds. Some legacy classes are not well behaved and use "assign" properties which can contain pointers to deallocated objects. To avoid sweeping the ivars of these classes Xprobe has an exclusion filter which can be overridden (with a warning) in a category:

    static NSString *swiftPrefix = @"_TtC";

    @implementation Xprobe(ExclusionOverride)

    + (BOOL)xprobeExclude:(NSString *)className {
        static NSRegularExpression *excluded;
        if ( !excluded )
            excluded = [NSRegularExpression xsimpleRegexp:@"^(_|NS|XC|IDE|DVT|Xcode3|IB|VK|WebHistory)"];
        return [excluded xmatches:className] && ![className hasPrefix:swiftPrefix];
    }
    
    @end

These exclusions allow Xprobe to work cleanly inside Xcode itself which comes in handy if you're a plugin dev. For any suggestions or feedback you can contact the author on xprobe at johnholdsworth.com. Major releases will be announced on twitter @Injection4Xcode.

With Swift 2.3+, Xprobe is no longer able to scan ivars that do not have properties i.e. classes that do not inherit from NSObject.

Source files

Xprobe.{h,mm} - core Xprobe functionality required for snapshots IvarAccess.h - required routines for access to class ivars by name Xprobe+Service.mm - optional interactive service connecting to Xcode

License

Copyright (c) 2014-5 John Holdsworth. Licensed for download, modification and any use during development of Objectice-C applications, re-distribution may only be through a public repo github however including this copyright notice. For binary redistribution with your app get in touch!

This release includes a very slightly modified version of the excellent canviz library to render "dot" files in an HTML canvas which is subject to an MIT license. The changes are to pass through the ID of the node to the node label tag (line 212), to reverse the rendering of nodes and the lines linking them (line 406) and to store edge paths so they can be colored (line 66 and 303) in "canviz-0.1/canviz.js".

It now also includes CodeMirror JavaScript editor for the code to be evaluated using injection under an MIT license.

As ever:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

More Repositories

1

injectionforxcode

Runtime Code Injection for Objective-C & Swift
Objective-C
6,551
star
2

InjectionIII

Re-write of Injection for Xcode in (mostly) Swift
Objective-C
3,995
star
3

Xtrace

Trace Objective-C method calls by class or instance
Objective-C++
1,832
star
4

Refactorator

Xcode Plugin that Refactors Swift & Objective-C
Swift
991
star
5

GitDiff

Highlights deltas against git repo in Xcode
Objective-C
891
star
6

Remote

Control your iPhone from inside Xcode for end-to-end testing.
Objective-C
853
star
7

SwiftTrace

Trace Swift and Objective-C method invocations
Swift
695
star
8

HotReloading

Hot reloading as a Swift Package
Swift
536
star
9

RefactoratorApp

App version of Refactorator plugin
Swift
255
star
10

Accelerator

Inline frameworks of Swift CocoaPods projects for faster launch
Ruby
174
star
11

InjectionApp

Issue Tracking Repo for Injection as an App
Swift
111
star
12

Fortify

Making Swift more robust
Swift
95
star
13

HotSwiftUI

Utilities for Hot Reloading SwiftUI apps.
Swift
94
star
14

Diamond

Diamond - Swift scripting made easy
Objective-C
94
star
15

SwiftPython

Experiments in bridging Swift to Python
Swift
88
star
16

Dynamo

High Performance (nearly)100% Swift Web server supporting dynamic content.
Swift
68
star
17

SwiftRegex

Some regular expression operators for Swift
Swift
67
star
18

NSLinux

NSString and libdispatch compatibility code for Swift on Linux
Swift
47
star
19

InstantSyntax

SwiftSyntax binary frameworks
Swift
47
star
20

InjectionNext

Fourth evolution of Code Injection for Xcode
Swift
47
star
21

WatchkitCurrency

Swift Currency Convertor for iWatch with flexible interface
Swift
40
star
22

TwoWayMirror

Adapt Swift’s Mirror functionality to make it bidirectional.
Swift
38
star
23

InjectionLite

Swift package re-write of InjectionIII app
Swift
34
star
24

Smuggler

Smuggle code bundles into an app running in the Simulator
Objective-C++
32
star
25

SwiftRegex5

5th incarnation of Swift Regex library using generic subscripts
Swift
32
star
26

SwiftAspects

Experiments in Aspects with Swift (Xtrace for Swift)
Assembly
30
star
27

unhide

export symbols with “hidden” visibility for Swift frameworks
Objective-C++
25
star
28

Symbolicate

Symbolicate for OS X
Objective-C
23
star
29

DLKit

A rather subscript oriented interface to the dynamic linker.
Swift
22
star
30

SwiftTryCatch

Try/Catch for Swift?
Swift
15
star
31

ApportablePlugin

Simple Plugin for work with Apportable
Objective-C
14
star
32

Compilertron

InjectionIII for the Swift compiler
C++
14
star
33

SearchLight

SpotLight on Steroids
Objective-C++
14
star
34

siteify

Build web site from a project’s Swift sources.
HTML
13
star
35

SwiftPlugin

A way to import classes from plugins
Swift
12
star
36

SwiftKeyPath

valueForKeyPath: for Swift
Swift
12
star
37

DynamoLinux

100% Swift Linux Web Server
Swift
11
star
38

ProfileSwiftUI

InstrumentSwiftUI
Swift
10
star
39

SwiftUIPlaygrounds

Alternative to Xcode previews.
Swift
9
star
40

SwiftRegex4

Basic regex operations for Swift4
Swift
9
star
41

StringIndex

Sensible indexing into Swift Strings
Swift
8
star
42

SwiftView

Curated Xcode Project as a means of navigating Swift Sources
7
star
43

Parallel

Some primitives for concurrent processing
Swift
6
star
44

Popen

Reading and writing processes and files
Swift
6
star
45

WatchkitSundial

Sundial for Apple Watch
Objective-C
6
star
46

SwiftierJSON

Memory efficient version of SwiftyJSON
Swift
6
star
47

objectivecpp

HTML
5
star
48

YieldGenerator

Python's "yield" generators for Swift
Swift
5
star
49

opaqueify

Greater use of Opaque types (SE0335)
Swift
5
star
50

SwiftMock

Mock structs and classes without code modification for testing.
Swift
4
star
51

Unwrap

Self documenting alternatives to force unwrap operator.
Swift
4
star
52

InjectionScratch

InjectionScratch
Objective-C++
3
star
53

EasyPointer

Rounding off some of the rough edges of Swift's pointer model
Swift
2
star
54

TestRunner

Example of calling Swift methods using name pattern (XCTest?)
Swift
2
star
55

binary-Swallow0

Swift
1
star
56

Character

Integer conversions and operators for Swift Characters.
Swift
1
star
57

ASCII

Facilitating operations on ASCII in Swift
Swift
1
star