Rentgen is a troubleshooting tool, that allows you to observe release and retain events on class and closure types. The hooking is allowed by "swizzeling" the Swift Runtime calls.
This package is deprecated. I strongly recommed using my arctool and closuredesc scripts for LLDB. You can achieve essentially the same functionality, without the need to add any Swift code to your program.
All you need to do in order to use the Rentgen is adding it as dependency to your project and desired target in Swift Package Manager:
.package(url: "https://github.com/mikolasstuchlik/Rentgen.git", from: "0.1.0"),Following example demonstrates how to hook on a closure:
let myClosure: () -> Void = { [foo1 = FooClass(), foo2 = AnotherClass()] in
print("hello \(foo1) \(foo2)")
}
try Rentgen.ClosureArcTool.hookOnNonThrowing(for: myClosure) { (strongRefs, unownedRefs, weakRefs) in
print("Did retain. Strong: \(strongRefs), unowned: \(unownedRefs), weak: \(weakRefs).")
}
beforeRelease: { (strongRefs, unownedRefs, weakRefs) in
print("Will release. Strong: \(strongRefs), unowned: \(unownedRefs), weak: \(weakRefs)")
}This tools is based upon discussion about the behaviour of closures on the Swift Forum and discussion about troubleshooting strong retain overflows.
The Rentgen package takes ideas discussed in the above mentioned threads and packages them for real-world use and modification.
The whole package is based on various assumptions on how the objects in memory look at runtime. There may be case that I haven't noticed during implementation. One case I have patched is optimization, where no capture list is allocated, if closure captures only one instance of a reference counted type.