Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeorgeLyon/765605dadf371ee0f29b86913677a4c2 to your computer and use it in GitHub Desktop.
Save GeorgeLyon/765605dadf371ee0f29b86913677a4c2 to your computer and use it in GitHub Desktop.
import Foundation
import MachO.dyld
import MachO.getsect
extension DefaultStringInterpolation {
mutating func appendInterpolation(pointer: Int) {
appendInterpolation(String(format: "0x%016\(PRIxPTR)", pointer))
}
}
enum CurrentExecutable {
static let baseAddress = getsegbyname("__TEXT").pointee.vmaddr
static let imageSlides = Dictionary(
uniqueKeysWithValues:
(0..<_dyld_image_count())
.map { (String(cString: _dyld_get_image_name($0)), _dyld_get_image_vmaddr_slide($0)) })
/// This is suboptimal
static let name: String = {
var requiredSize: UInt32 = 0
/**
-1 indicates the path didn't fit, which is expected given that we provided a buffer of size 0. As a side effect, this sets `requiredSize` to the size of buffer we require.
*/
precondition(_NSGetExecutablePath(nil, &requiredSize) == -1)
return String(
unsafeUninitializedCapacity: Int(requiredSize),
initializingUTF8With: { buffer in
buffer.withMemoryRebound(to: Int8.self) { buffer in
precondition(_NSGetExecutablePath(buffer.baseAddress, &requiredSize) == 0)
/// We do not include the NULL terminator
return Int(requiredSize) - 1
}
})
}()
static let imageSlide = imageSlides[name]!
}
func printBacktrace() {
Thread.callStackReturnAddresses.map(\.intValue).forEach { returnAddress in
let symbolAddress = returnAddress - CurrentExecutable.imageSlide
print("""
\(pointer: returnAddress): \(pointer: symbolAddress)
""")
}
}
/* */ printBacktrace()
// Debug info can be accessed using a dSYM like so: dwarfdump <path-to-dSYM> --lookup=<symbolAddress>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment