Skip to content

[swift-inspect] Fix the swift-inspect build on Darwin. #41620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)

import SwiftRemoteMirror
@_implementationOnly import SymbolicationShims
import SymbolicationShims

internal final class DarwinRemoteProcess: RemoteProcess {
public typealias ProcessIdentifier = pid_t
Expand All @@ -23,8 +23,10 @@ internal final class DarwinRemoteProcess: RemoteProcess {

public var process: ProcessHandle { task }
public private(set) var context: SwiftReflectionContextRef!
private var symbolicator: CSSymbolicatorRef

private var swiftCore: CSTypeRef
private let swiftConcurrency: CSTypeRef

static var QueryDataLayout: QueryDataLayoutFunction {
return { (context, type, _, output) in
Expand All @@ -38,7 +40,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {

case DLQ_GetPtrAuthMask:
let mask = GetPtrauthMask()
output.storeBytes(of: mask, toByteOffset: 0, as: UInt.size)
output.storeBytes(of: mask, toByteOffset: 0, as: UInt.self)
return 1

case DLQ_GetObjCReservedLowBits:
Expand All @@ -65,10 +67,25 @@ internal final class DarwinRemoteProcess: RemoteProcess {
}
}

func read(address: swift_addr_t, size: Int) -> UnsafeRawPointer? {
return task_peek(task, address, mach_vm_size_t(size))
}

func getAddr(symbolName: String) -> swift_addr_t {
// FIXME: use `__USER_LABEL_PREFIX__` instead of the hardcoded `_`.
let fullName = "_\(symbolName)"
let symbol = CSSymbolOwnerGetSymbolWithMangledName(swiftCore, fullName)
if CSIsNull(symbol) {
symbol = CSSymbolOwnerGetSymbolWithMangledName(swiftConcurrency, fullName)
}
let range = CSSymbolGetRange(symbol)
return swift_addr_t(range.location)
}

static var ReadBytes: ReadBytesFunction {
return { (context, address, size, _) in
let process: DarwinRemoteProcess = DarwinRemoteProcess.fromOpaque(context!)
return task_peek(process.task, address, size)
return process.read(address: address, size: Int(size))
}
}

Expand All @@ -90,11 +107,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
let buffer = UnsafeBufferPointer(start: $0, count: Int(length))
return String(decoding: buffer, as: UTF8.self)
}

let symbol =
CSSymbolOwnerGetSymbolWithMangledName(process.swiftCore, "_\(name)")
// FIXME: use `__USER_LABEL_PREFIX__` instead of the hardcoded `_`.
return swift_addr_t(CSSymbolGetRange(symbol).location)
return process.getAddr(symbolName: name)
}
}

Expand All @@ -107,6 +120,14 @@ internal final class DarwinRemoteProcess: RemoteProcess {
}
self.task = task

self.symbolicator = CSSymbolicatorCreateWithTask(self.task)
self.swiftCore =
CSSymbolicatorGetSymbolOwnerWithNameAtTime(self.symbolicator,
"libswiftCore.dylib", kCSNow)
self.swiftConcurrency = CSSymbolicatorGetSymbolOwnerWithNameAtTime(
symbolicator, "libswift_Concurrency.dylib", kCSNow)
_ = task_start_peeking(self.task)

guard let context =
swift_reflection_createReflectionContextWithDataLayout(self.toOpaqueRef(),
Self.QueryDataLayout,
Expand All @@ -116,12 +137,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {
Self.GetSymbolAddress) else {
return nil
}

self.symbolicator = CSSymbolicatorCreateWithTask(self.task)
self.swiftCore =
CSSymbolicatorGetSymbolOwnerWithNameAtTime(self.symbolicator,
"libswiftCore.dylib", kCSNow)
_ = task_start_peeking(self.task)
self.context = context

_ = CSSymbolicatorForeachSymbolOwnerAtTime(self.symbolicator, kCSNow, { owner in
let address = CSSymbolOwnerGetBaseAddress(owner)
Expand All @@ -136,7 +152,7 @@ internal final class DarwinRemoteProcess: RemoteProcess {

func symbolicate(_ address: swift_addr_t) -> (module: String?, symbol: String?) {
let symbol =
CSSymbolicatorGetSymbolWithAddressAtTime(sself.symbolicator, address, kCSNow)
CSSymbolicatorGetSymbolWithAddressAtTime(self.symbolicator, address, kCSNow)

let module = CSSymbolGetSymbolOwner(symbol)
return (CSSymbolOwnerGetName(module), CSSymbolGetName(symbol))
Expand All @@ -153,8 +169,9 @@ extension DarwinRemoteProcess {
{ (task, context, type, ranges, count) in
let callback: (swift_addr_t, UInt64) -> Void =
context!.assumingMemoryBound(to: ((swift_addr_t, UInt64) -> Void).self).pointee
ranges.forEach {
callback(swift_addr_t($0.address), UInt64($0.size))
for i in 0..<Int(count) {
let range = ranges[i]
callback(swift_addr_t(range.address), UInt64(range.size))
}
})
}
Expand Down Expand Up @@ -196,24 +213,24 @@ extension DarwinRemoteProcess {
let result =
thread_info(threadList![i], thread_flavor_t(THREAD_IDENTIFIER_INFO),
$0, &infoCount)
guard result == ERROR_SUCCESS else {
guard result == KERN_SUCCESS else {
print("unable to get info for thread \(i): \(String(cString: mach_error_string(result))) (0x\(String(result, radix: 16)))")
return
}
}
}

let tlsStart = info.thread_handle
if tlsStart == 0 { return }
let tlsStart = info.thread_handle
if tlsStart == 0 { continue }

let SWIFT_CONCURRENCY_TASK_KEY = 103
let currentTaskPointer = tlsStart + UInt64(SWIFT_CONCURRENCY_TASK_KEY * MemoryLayout<UnsafeRawPointer>.size)
if let pointer = ReadBytes(currentTaskPointer, size: MemoryLayout<UnsafeRawPointer>.size) {
let currentTask = pointer.load(as: UInt.self)
results.append((threadID: info.thread_id, currentTask: swift_addr_t(currentTask)))
}
}
let SWIFT_CONCURRENCY_TASK_KEY = 103
let currentTaskPointer = tlsStart + UInt64(SWIFT_CONCURRENCY_TASK_KEY * MemoryLayout<UnsafeRawPointer>.size)
if let pointer = read(address: currentTaskPointer, size: MemoryLayout<UnsafeRawPointer>.size) {
let currentTask = pointer.load(as: UInt.self)
results.append((threadID: info.thread_id, currentTask: swift_addr_t(currentTask)))
}
}
return result
return results
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)

import ArgumentParser
import SwiftRemoteMirror

struct DumpConcurrency: ParsableCommand {
Expand Down Expand Up @@ -60,7 +61,7 @@ fileprivate class ConcurrencyDumper {

lazy var heapInfo: HeapInfo = gatherHeapInfo()

lazy var threadCurrentTasks = process.threadCurrentTasks().filter{ $0.currentTask != 0 }
lazy var threadCurrentTasks = process.currentTasks.filter{ $0.currentTask != 0 }

lazy var tasks: [swift_reflection_ptr_t: TaskInfo] = gatherTasks()

Expand All @@ -76,8 +77,8 @@ fileprivate class ConcurrencyDumper {
self.process = process

func getMetadata(symbolName: String) -> swift_reflection_ptr_t? {
let addr = process.GetSymbolAddress(symbolName)
if let ptr = process.ReadBytes(addr, MemoryLayout<UInt>.size) {
let addr = process.getAddr(symbolName: symbolName)
if let ptr = process.read(address: addr, size: MemoryLayout<UInt>.size) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes will be problematic for Windows support, but we can deal with it then.

return swift_reflection_ptr_t(ptr.load(as: UInt.self))
}
return nil
Expand Down Expand Up @@ -148,7 +149,7 @@ fileprivate class ConcurrencyDumper {
return cached
}

let name = context.name(metadata: metadata)
let name = context.name(type: metadata)
metadataNameCache[metadata] = name
return name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ internal protocol RemoteProcess: AnyObject {
static var GetSymbolAddress: GetSymbolAddressFunction { get }

func symbolicate(_ address: swift_addr_t) -> (module: String?, symbol: String?)
func iterateHeap(_ body: (swift_addr_t, UInt64) -> Void)
}

extension RemoteProcess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,10 @@ func task_enumerate_malloc_blocks(
Sym.task_enumerate_malloc_blocks(task, context, type_mask, recorder)
}

func machErrStr(_ kr: kern_return_t) -> String {
let errStr = String(cString: mach_error_string(kr))
let errHex = String(kr, radix: 16)
return "\(errStr) (0x\(errHex))"
}

#endif