{"id":17211078,"url":"https://github.com/zadr/pipewrench","last_synced_at":"2025-10-15T03:09:31.722Z","repository":{"id":60605398,"uuid":"461149237","full_name":"zadr/PipeWrench","owner":"zadr","description":"A take on automatically checking for memory leaks","archived":false,"fork":false,"pushed_at":"2023-03-13T17:21:52.000Z","size":78,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-27T12:52:41.063Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","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/zadr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-19T09:51:35.000Z","updated_at":"2024-12-20T00:50:21.000Z","dependencies_parsed_at":"2023-01-19T15:31:47.762Z","dependency_job_id":null,"html_url":"https://github.com/zadr/PipeWrench","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zadr%2FPipeWrench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zadr%2FPipeWrench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zadr%2FPipeWrench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zadr%2FPipeWrench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zadr","download_url":"https://codeload.github.com/zadr/PipeWrench/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248794083,"owners_count":21162610,"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":[],"created_at":"2024-10-15T02:56:12.298Z","updated_at":"2025-10-15T03:09:26.679Z","avatar_url":"https://github.com/zadr.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"#### What Is This?\nPipeWrench is an iOS library that can be linked into a [testing target](https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/01-introduction.html#//apple_ref/doc/uid/TP40014132) that automatically runs `leaks` when a test fails, and when a test suite finishes running.\n\n#### How Does It Work?\nPipeWrench copies `NSTask.h` from the macOS SDK, and then shells out to the [leaks](x-man-page://leaks) and [heap](x-man-page://heap) command line tool to do all the heavy lifting.\n\nSince iOS doesn't have `NSTask`, this PipeWrench is limited to running on the iOS Simulator.\n\n#### Why Wouldn't I Use The Memory Graph In Xcode?\nCan't press buttons manually when running automated tests on CI systems. Even if you could, it would be very tedious to have to press the same button all the time.\n\n#### Integration?\nThis is a prototype. If you want to use PipeWrench, you'll have to add it as a submodule and deal with the xcodeproj manually.\n\n#### Environment Variables\nThere are a handful of environment variables that control PipeWrench's behavior. These are best set as part of the target's build and run configuration. Here is a brief overview of available environment variables:\n\n- `EnablePipeWrench` - Default: `false`. Should PipeWrench automatically track leaks when linked into a test target that is loaded into memory? It is not required to start PipeWrench at load-time; calling `let pipeWrench = PipeWrench(logger: PWLogIngest()) ; try? pipeWrench.start()` will also result in leaks being tracked, for example, on a per-test or per-test case basis.\n- `MemgraphRootDirectory` - Default: `/tmp/PipeWrench/\u003cuuid\u003e/`. Where on disk should memgraph files be saved? By default, PipeWrench will save files to a directory under `/tmp/PipeWrench/` with a new uuid for each instance of PipeWrench.\n- `CreateMemgraphRootDirectory` - Default: `false`. If a directory to save memgraph files to does not exist, should it be created?\n- `ConsoleLoggingEnabled` - Default: `true`. Should PipeWrench log any output (debug or informational) to the device console?\n- `DiskLoggingPath` - Default: `nil`. If non-nil, PipeWrench will write any log output to a file on disk.\n\nFor more context, see swiftdoc in [Constants.swift](https://github.com/zadr/PipeWrench/blob/main/PipeWrench/PipeWrench/Constants.swift).\n\n#### Running the Prototype?\n1. Open `App.xcodeproj`.\n2. Hit ⌘U to run tests. When running with Xcode 13.2.1, you'll see something like this at the end of the test run:\n\n```\nTest Suite 'Selected tests' started at 2022-02-19 00:30:11.360\nTest Suite 'AppTests.xctest' started at 2022-02-19 00:30:11.360\nTest Suite 'AppTests' started at 2022-02-19 00:30:11.360\nTest Case '-[AppTests.AppTests testExample]' started.\nTest Case '-[AppTests.AppTests testExample]' passed (0.001 seconds).\nTest Case '-[AppTests.AppTests testPerformanceExample]' started.\n/Users/z/Desktop/App/AppTests/AppTests.swift:15: Test Case '-[AppTests.AppTests testPerformanceExample]' measured [Time, seconds] average: 0.000, relative standard deviation: 154.614%, values: [0.000258, 0.000029, 0.000023, 0.000021, 0.000022, 0.000021, 0.000020, 0.000020, 0.000021, 0.000022], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: \"\", baselineAverage: , polarity: prefers smaller, maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100\nTest Case '-[AppTests.AppTests testPerformanceExample]' passed (0.264 seconds).\nTest Suite 'AppTests' passed at 2022-02-19 00:30:11.626.\n\t Executed 2 tests, with 0 failures (0 unexpected) in 0.265 (0.266) seconds\nTest Suite 'AppTests.xctest' passed at 2022-02-19 00:30:11.626.\n\t Executed 2 tests, with 0 failures (0 unexpected) in 0.265 (0.266) seconds\nTest Suite 'Selected tests' passed at 2022-02-19 00:30:11.627.\n\t Executed 2 tests, with 0 failures (0 unexpected) in 0.265 (0.267) seconds\nleaking :(\nProcess:         App [78941]\nPath:            /Users/z/Library/Developer/CoreSimulator/Devices/87C655D7-8376-41BF-81D5-9CE1B66680EC/data/Containers/Bundle/Application/60DB5134-FD92-4EE6-87DB-ECD7746A47BD/App.app/App\nLoad Address:    0x102fd4000\nIdentifier:      App\nVersion:         ???\nCode Type:       ARM64\nParent Process:  debugserver [78942]\n\nDate/Time:       2022-02-19 00:30:12.040 -0800\nLaunch Time:     2022-02-19 00:30:10.689 -0800\nOS Version:      iPhone OS 15.2 (19C51)\nReport Version:  7\nAnalysis Tool:   /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/bin/leaks\nAnalysis Tool Version:  iOS Simulator 15.2 (19C51)\n\nPhysical footprint:         12.5M\nPhysical footprint (peak):  12.5M\n----\n\nleaks Report Version: 4.0\nProcess 78941: 31480 nodes malloced for 4419 KB\nProcess 78941: 1 leak for 32 total leaked bytes.\n\n    1 (32 bytes) ROOT LEAK: 0x6000017ebc40 [32]\n```\n\nwhich tells us there is one leak found, along with the memory address.\n\n## License\n\nPipeWrench is available under the MIT license.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzadr%2Fpipewrench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzadr%2Fpipewrench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzadr%2Fpipewrench/lists"}