{"id":16682795,"url":"https://github.com/johnno1962/xprobeplugin","last_synced_at":"2025-06-13T02:41:24.916Z","repository":{"id":17179067,"uuid":"19946423","full_name":"johnno1962/XprobePlugin","owner":"johnno1962","description":"Live Memory Browser for Apps \u0026 Xcode","archived":false,"fork":false,"pushed_at":"2024-09-24T18:53:00.000Z","size":5234,"stargazers_count":397,"open_issues_count":0,"forks_count":30,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-05-15T21:04:44.628Z","etag":null,"topics":["reverse-engineering","xcode-plugin"],"latest_commit_sha":null,"homepage":"","language":"Objective-C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnno1962.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-05-19T15:09:02.000Z","updated_at":"2025-03-23T00:56:40.000Z","dependencies_parsed_at":"2024-03-28T19:10:02.460Z","dependency_job_id":null,"html_url":"https://github.com/johnno1962/XprobePlugin","commit_stats":{"total_commits":182,"total_committers":3,"mean_commits":"60.666666666666664","dds":0.01098901098901095,"last_synced_commit":"069a8c03ae6663175c369e3858a8372ea3ee95f4"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/johnno1962/XprobePlugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FXprobePlugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FXprobePlugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FXprobePlugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FXprobePlugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnno1962","download_url":"https://codeload.github.com/johnno1962/XprobePlugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FXprobePlugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259568152,"owners_count":22877858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["reverse-engineering","xcode-plugin"],"created_at":"2024-10-12T14:08:34.746Z","updated_at":"2025-06-13T02:41:24.873Z","avatar_url":"https://github.com/johnno1962.png","language":"Objective-C++","funding_links":[],"categories":["\u003ca id=\"977cef2fc942ac125fa395254ab70eea\"\u003e\u003c/a\u003eXCode"],"sub_categories":["\u003ca id=\"7037d96c1017978276cb920f65be2297\"\u003e\u003c/a\u003e工具"],"readme":"## ![Icon](http://injectionforxcode.johnholdsworth.com/swiss1.jpg)  Xprobe Realtime Memory Browser\n\n**Update:** This former Xcode plugin has been re-organised into a\nSwift Package for use in other apps. Use the `Xprobe` product in\nclient applications and the `XprobeUI` product at the server side.\n\nThe XprobePlugin gives you a view of the objects inside your application either\nin detail down to the level of ivars or globally as a graph of the principal objects\nand how they are connected. This display can be animated in real time, highlighting in\nred objects as they are messaged and the paths down which messages are flowing.\nThis is done automatically by performing a \"sweep\" to find all objects referred to\nby a set of seeds, the objects they refer to, the objects those refer to and so \nforth to build up the list of live objects which can be displayed in Xcode:\n\n![Icon](http://johnholdsworth.com/mirror.gif)\n\nIn the simulator, the memory sweeper is loaded from a bundle inside the plugin using lldb\nrequiring no changes to the app's project source. To use the plugin, build this project\nand restart Xcode. Once your application is running, use menu item \"Product/Xprobe/Load\"\nto load the initial view of the  memory sweep of your app. If you are a plugin developer\nyou use \"Product/Xprobe/Xcode\" to inspect the objects of the Xcode application itself.\n\nYou can then filter the objects listed into the app or their methods using a pattern.\nIf there are no objects matching the pattern and it is a class name it will be displayed.\nPatterns prefixed with '+' or '-' will search all classes linked into the\napplication for methods matching the pattern. A raw pointer prefixed with\n\"0x\" can be entered to inspect an object passed as an argument to a trace.\nYou can also enter an object \"path\" starting \"seed.\" from the paths logged\nas you browse your application so you can find your way back to objects\neasily.\n\nIf you have the [injectionforxcode](https://github.com/johnno1962/injectionforxcode) plugin\ninstalled Xprobe will allow you to evaluate Objective-C or Swift against a selected instance\nfor which you have the source to log or modify any aspect of the object's state at run time.\n\n#### Stop Press: \n\nXprobe.mm can now snapshot your app to a standalone html file in the event of an error.\nThis performs a sweep and can document the state of your app at the time the error occured\nfor later analysis. An example snapshot file for a ReactNative example project\n\"TickTackToe\" can be [viewed here](http://johnholdsworth.com/snapshot.html).\n\n To take a snapshot, include Xprobe.mm in your app and use the following call:\n\n```objc\n    [Xprobe snapshot:@\"/path/to/snapshot.html.gz\" seeds:@[app delegate, rootViewController]];\n```\n\nIf you run into difficulties you can alter the pattern of classe names not to capture with\nan additional excluding:(NSString *)pattern argument. The default value for this is:\n\n```objc\n    @\"^(?:UI|NS((Object|URL|Proxy)$|Text|Layout|Index|.*(Map|Data|Font))|Web|WAK|SwiftObject|XC|IDE|DVT|Xcode3|IB|VK)\"\n```\n\nThe remaining features are most easily rolled off as a series of bullet points:\n\n![Icon](http://injectionforxcode.johnholdsworth.com/xprobe1.png)\n\nClick on an object's link to view it's ivar contents.\n\nClick the link again to close the detail view.\n\nClick on the superclass link to view it's ivars\n\nClick on an ivar name to refresh it's value from the app\n\nClick on an ivar value to edit and set it's value in the app\n\nThe class' properties, methods and any protocols can be viewed.\n\nThe method lists can be searched (also finding superclass methods)\n\nUse the \"trace\" link to start logging calls to methods on that instance.\n\nTo see all methods traced for an object, click trace against each class.\n\nTrace output can be filtered using a regular expression\n\nThe subviews link will recursively display the tree of subviews under a view.\n\nThe \"render\" link will capture an image when the object is a view.\n\nThe siblings link will display all objects found that share the object's class.\n\nRefresh the object list by typing enter in the Search Field to force a new sweep.\n\nPressing the Graph button will open the summary view of the most important objects\nand any \"kit\" objects directly linked to them taken from the last sweep.\n\nThe object is represented as a square if is it a view (responds to \"subviews\".)\n\nGraph display requires an installation of [\"Graphviz/dot\"](http://www.graphviz.org/) on your computer.\n\nClick on an object to view it's current contents as discussed above.\n\nDiffering filtering of which objects to include can be applied.\n\n\"Animate Messages\" puts a trace on objects having them display \"red\" when messaged.\n\nGraphs can be exported to Graphviz or .png format for printing.\n\nAlas, Swift support is limited at the moment as ivar_getTypeEncoding() returns \nNULL for ivar fields preventing them taking part in the \"sweep\".\n\n### Use on a device.\n\nXprobe works by loading a bundle in the simulator which connects to Xcode when it is loaded.\nAn application makes its list of seed nodes known to Xprobe by implementing the following category:\n\n```objc\n    @implementation Xprobe(Seeding)\n\n    + (NSArray *)xprobeSeeds {\n        UIApplication *app = [UIApplication sharedApplication];\n        NSMutableArray *seeds = [NSMutableArray arrayWithObject:app];\n        [seeds addObjectsFromArray:[app windows]];\n\n        // support for cocos2d\n        Class ccDirectorClass = NSClassFromString(@\"CCDirector\");\n        CCDirector *ccDirector = [ccDirectorClass sharedDirector];\n        if ( ccDirector )\n            [seeds addObject:ccDirector];\n\n        return seeds;\n    }\n\n    @end\n```\n\nOr for OSX:\n\n```objc\n    + (NSArray *)xprobeSeeds {\n        NSApplication *app = [NSApplication sharedApplication];\n        NSMutableArray *seeds = [[app windows] mutableCopy];\n        if ( app.delegate )\n            [seeds insertObject:app.delegate atIndex:0];\n        return seeds;\n    }\n```\n\nOnce an app is initialised call [Xprobe connectTo:\"your.ip.address\" retainObjects:YES] to\nconnect to the TCP server running inside Xcode. The retainObjects: argument specifies whether\nto retain objects found in the sweep. This will make Xprobe more reliable but it will affect\nobject life-cycles in your app. After this, call [Xprobe search:@\"\"] to perform the initial sweep \nstarting at these objects looking for root objects. Each time \"search:\" is called or the object \nclass filter is changed the sweep is performed anew. The application will need to be built with\nXprobe and Xtrace.{h,mm}.\n\nIn this day and age of nice clean \"strong\" and \"weak\" pointers the sweep seems very reliable\nif objects are somehow visible to the seeds. Some legacy classes are not well behaved and \nuse \"assign\" properties which can contain pointers to deallocated objects. To avoid \nsweeping the ivars of these classes Xprobe has an exclusion filter which can be overridden \n(with a warning) in a category:\n\n```objc\n    static NSString *swiftPrefix = @\"_TtC\";\n\n    @implementation Xprobe(ExclusionOverride)\n\n    + (BOOL)xprobeExclude:(NSString *)className {\n        static NSRegularExpression *excluded;\n        if ( !excluded )\n            excluded = [NSRegularExpression xsimpleRegexp:@\"^(_|NS|XC|IDE|DVT|Xcode3|IB|VK|WebHistory)\"];\n        return [excluded xmatches:className] \u0026\u0026 ![className hasPrefix:swiftPrefix];\n    }\n    \n    @end\n```\n\nThese exclusions allow Xprobe to work cleanly inside Xcode itself which comes in handy \nif you're a plugin dev. For any suggestions or feedback you can contact the author\non xprobe at johnholdsworth.com. Major releases will be announced on twitter\n[@Injection4Xcode](https://twitter.com/#!/@Injection4Xcode).\n\nWith Swift 2.3+, Xprobe is no longer able to scan ivars that do not have properties\ni.e. classes that do not inherit from NSObject.\n\n### Source files\n\nXprobe.{h,mm} - core Xprobe functionality required for snapshots\nIvarAccess.h - required routines for access to class ivars by name\nXprobe+Service.mm - optional interactive service connecting to Xcode\n\n### License\n\nCopyright (c) 2014-5 John Holdsworth. Licensed for download, modification and any use during development\nof Objectice-C applications, re-distribution may only be through a public repo github however including\nthis copyright notice. For binary redistribution with your app [get in touch](mailto:xprobe@johnholdsworth.com)!\n\nThis release includes a very slightly modified version of the excellent \n[canviz](https://code.google.com/p/canviz/) library to render \"dot\" files \nin an HTML canvas which is subject to an MIT license. The changes are to pass \nthrough the ID of the node to the node label tag (line 212), to reverse\nthe rendering of nodes and the lines linking them (line 406) and to\nstore edge paths so they can be colored (line 66 and 303) in \"canviz-0.1/canviz.js\".\n\nIt now also includes [CodeMirror](http://codemirror.net/) JavaScript editor\nfor the code to be evaluated using injection under an MIT license.\n\n### As ever:\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. \nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, \nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE \nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnno1962%2Fxprobeplugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnno1962%2Fxprobeplugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnno1962%2Fxprobeplugin/lists"}