Skip to content

Commit 43c9623

Browse files
committed
[swift-inspect] misc cleanup
1 parent e90f5c5 commit 43c9623

File tree

10 files changed

+127
-48
lines changed

10 files changed

+127
-48
lines changed

tools/swift-inspect/Sources/SwiftInspectLinux/MemoryMap.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class MemoryMap {
3131
if name == "[anon:libc_malloc]" { return true }
3232
if name.hasPrefix("[anon:scudo:") { return true }
3333
if name.hasPrefix("[anon:GWP-ASan") { return true }
34-
return false;
34+
return false
3535
}
3636
}
3737

tools/swift-inspect/Sources/SwiftInspectLinux/PTrace.swift

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,64 @@ import Foundation
22
import LinuxSystemHeaders
33

44
public class PTrace {
5-
enum Error: Swift.Error {
6-
case PTraceFailure(_ command: Int32, pid: pid_t, errno: Int32 = get_errno())
7-
case WaitFailure(pid: pid_t, errno: Int32 = get_errno())
8-
case IllegalArgument(description: String)
9-
case UnexpectedWaitStatus(pid: pid_t, status: Int32, sigInfo: siginfo_t? = nil)
5+
enum PTraceError: Error {
6+
case ptraceFailure(_ command: Int32, pid: pid_t, errno: Int32 = get_errno())
7+
case waitFailure(pid: pid_t, errno: Int32 = get_errno())
8+
case unexpectedWaitStatus(pid: pid_t, status: Int32, sigInfo: siginfo_t? = nil)
109
}
1110

1211
let pid: pid_t
1312

1413
public init(process pid: pid_t) throws {
15-
if ptrace_attach(pid) == -1 { throw Error.PTraceFailure(PTRACE_ATTACH, pid: pid) }
14+
guard ptrace_attach(pid) != -1 else {
15+
throw PTraceError.ptraceFailure(PTRACE_ATTACH, pid: pid)
16+
}
1617

1718
while true {
1819
var status: Int32 = 0
1920
let result = waitpid(pid, &status, 0)
20-
if result == -1 {
21+
guard result != -1 else {
2122
if get_errno() == EINTR { continue }
22-
throw Error.WaitFailure(pid: pid)
23+
throw PTraceError.waitFailure(pid: pid)
2324
}
2425

25-
if result == pid && wIfStopped(status) { break }
26+
precondition(pid == result, "waitpid returned unexpected value \(result)")
27+
28+
if wIfStopped(status) { break }
2629
}
2730

2831
self.pid = pid
2932
}
3033

31-
deinit { ptrace_detach(self.pid) }
34+
deinit { _ = ptrace_detach(self.pid) }
3235

3336
public func cont() throws {
34-
if ptrace_continue(self.pid) == -1 { throw Error.PTraceFailure(PTRACE_CONT, pid: self.pid) }
37+
guard ptrace_continue(self.pid) != -1 else {
38+
throw PTraceError.ptraceFailure(PTRACE_CONT, pid: self.pid)
39+
}
3540
}
3641

3742
public func getSigInfo() throws -> siginfo_t {
3843
var sigInfo = siginfo_t()
39-
if ptrace_getsiginfo(self.pid, &sigInfo) == -1 {
40-
throw Error.PTraceFailure(PTRACE_GETSIGINFO, pid: self.pid)
44+
guard ptrace_getsiginfo(self.pid, &sigInfo) != -1 else {
45+
throw PTraceError.ptraceFailure(PTRACE_GETSIGINFO, pid: self.pid)
4146
}
47+
4248
return sigInfo
4349
}
4450

4551
public func pokeData(addr: UInt64, value: UInt64) throws {
46-
if ptrace_pokedata(self.pid, UInt(addr), UInt(value)) == -1 {
47-
throw Error.PTraceFailure(PTRACE_POKEDATA, pid: self.pid)
52+
guard ptrace_pokedata(self.pid, UInt(addr), UInt(value)) != -1 else {
53+
throw PTraceError.ptraceFailure(PTRACE_POKEDATA, pid: self.pid)
4854
}
4955
}
5056

5157
public func getRegSet() throws -> RegisterSet {
5258
var regSet = RegisterSet()
5359
try withUnsafeMutableBytes(of: &regSet) {
5460
var vec = iovec(iov_base: $0.baseAddress!, iov_len: MemoryLayout<RegisterSet>.size)
55-
if ptrace_getregset(self.pid, NT_PRSTATUS, &vec) == -1 {
56-
throw Error.PTraceFailure(PTRACE_GETREGSET, pid: self.pid)
61+
guard ptrace_getregset(self.pid, NT_PRSTATUS, &vec) != -1 else {
62+
throw PTraceError.ptraceFailure(PTRACE_GETREGSET, pid: self.pid)
5763
}
5864
}
5965
return regSet
@@ -63,19 +69,16 @@ public class PTrace {
6369
var regSetCopy = regSet
6470
try withUnsafeMutableBytes(of: &regSetCopy) {
6571
var vec = iovec(iov_base: $0.baseAddress!, iov_len: MemoryLayout<RegisterSet>.size)
66-
if ptrace_setregset(self.pid, NT_PRSTATUS, &vec) == -1 {
67-
throw Error.PTraceFailure(PTRACE_SETREGSET, pid: self.pid)
72+
guard ptrace_setregset(self.pid, NT_PRSTATUS, &vec) != -1 else {
73+
throw PTraceError.ptraceFailure(PTRACE_SETREGSET, pid: self.pid)
6874
}
6975
}
7076
}
7177

7278
public func callRemoteFunction(
7379
at address: UInt64, with args: [UInt64] = [], onTrap callback: (() throws -> Void)? = nil
7480
) throws -> UInt64 {
75-
76-
guard args.count <= 6 else {
77-
throw Error.IllegalArgument(description: "max of 6 arguments allowed")
78-
}
81+
precondition(args.count <= 6, "callRemoteFunction supports max of 6 arguments")
7982

8083
let origRegs = try self.getRegSet()
8184
defer { try? self.setRegSet(regSet: origRegs) }
@@ -93,31 +96,29 @@ public class PTrace {
9396
var status: Int32 = 0
9497
while true {
9598
let result = waitpid(self.pid, &status, 0)
96-
if result == -1 {
99+
guard result != -1 else {
97100
if get_errno() == EINTR { continue }
98-
throw Error.WaitFailure(pid: self.pid)
101+
throw PTraceError.waitFailure(pid: self.pid)
99102
}
100103

101-
if wIfExited(status) || wIfSignaled(status) {
102-
throw Error.UnexpectedWaitStatus(pid: self.pid, status: status)
104+
precondition(self.pid == result, "waitpid returned unexpected value \(result)")
105+
106+
guard wIfStopped(status) && !wIfExited(status) && !wIfSignaled(status) else {
107+
throw PTraceError.unexpectedWaitStatus(pid: self.pid, status: status)
103108
}
104109

105-
if wIfStopped(status) {
106-
guard wStopSig(status) == SIGTRAP, let callback = callback else { break }
110+
guard wStopSig(status) == SIGTRAP, let callback = callback else { break }
107111

108-
// give the caller the opportunity to handle SIGTRAP
109-
try callback()
110-
try self.cont()
111-
continue
112-
}
112+
// give the caller the opportunity to handle SIGTRAP
113+
try callback()
114+
try self.cont()
113115
}
114116

115117
let sigInfo = try self.getSigInfo()
116118
newRegs = try self.getRegSet()
117119

118120
guard wStopSig(status) == SIGSEGV, siginfo_si_addr(sigInfo) == nil else {
119-
print("WSTOPSIG(status):\(wStopSig(status)), si_addr:\(siginfo_si_addr(sigInfo)!)")
120-
throw Error.UnexpectedWaitStatus(pid: self.pid, status: status, sigInfo: sigInfo)
121+
throw PTraceError.unexpectedWaitStatus(pid: self.pid, status: status, sigInfo: sigInfo)
121122
}
122123

123124
return UInt64(newRegs.returnValue())

tools/swift-inspect/Sources/SwiftInspectLinux/Process.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import LinuxSystemHeaders
1616
// The Android version of iovec defineds iov_len as __kernel_size_t, while the
1717
// standard Linux definition is size_t. This extension makes the difference
1818
// easier to deal with.
19-
public extension iovec {
20-
init<T: BinaryInteger>(iov_base: UnsafeMutableRawPointer?, iov_len: T) {
19+
extension iovec {
20+
public init<T: BinaryInteger>(iov_base: UnsafeMutableRawPointer?, iov_len: T) {
2121
self.init()
2222
self.iov_base = iov_base
2323
#if os(Android)
@@ -86,7 +86,6 @@ public class Process {
8686
public func readArray<T>(address: UInt64, upToCount: UInt) throws -> [T] {
8787
guard upToCount > 0 else { return [] }
8888

89-
// TODO: impement using readMem
9089
let maxSize = upToCount * UInt(MemoryLayout<T>.stride)
9190
let array: [T] = Array(unsafeUninitializedCapacity: Int(upToCount)) { buffer, initCount in
9291
var local = iovec(iov_base: buffer.baseAddress!, iov_len: maxSize)
@@ -97,29 +96,35 @@ public class Process {
9796
}
9897

9998
guard array.count > 0 else {
100-
throw ProcessError.processVmReadFailure(pid: self.pid, address: address, size: UInt64(maxSize))
99+
throw ProcessError.processVmReadFailure(
100+
pid: self.pid, address: address, size: UInt64(maxSize))
101101
}
102102

103103
return array
104104
}
105105

106+
// simple wrapper around process_vm_readv
106107
public func readMem(remoteAddr: UInt64, localAddr: UnsafeRawPointer, len: UInt) throws {
107108
var local = iovec(iov_base: UnsafeMutableRawPointer(mutating: localAddr), iov_len: len)
108-
var remote = iovec(iov_base: UnsafeMutableRawPointer(bitPattern: UInt(remoteAddr)), iov_len: len)
109+
var remote = iovec(
110+
iov_base: UnsafeMutableRawPointer(bitPattern: UInt(remoteAddr)), iov_len: len)
109111

110112
let bytesRead = process_vm_readv(self.pid, &local, 1, &remote, 1, 0)
111113
guard bytesRead == len else {
112114
throw ProcessError.processVmReadFailure(pid: self.pid, address: remoteAddr, size: UInt64(len))
113115
}
114116
}
115117

118+
// simple wrapper around process_vm_writev
116119
public func writeMem(remoteAddr: UInt64, localAddr: UnsafeRawPointer, len: UInt) throws {
117120
var local = iovec(iov_base: UnsafeMutableRawPointer(mutating: localAddr), iov_len: len)
118-
var remote = iovec(iov_base: UnsafeMutableRawPointer(bitPattern: UInt(remoteAddr)), iov_len: len)
121+
var remote = iovec(
122+
iov_base: UnsafeMutableRawPointer(bitPattern: UInt(remoteAddr)), iov_len: len)
119123

120124
let bytesWritten = process_vm_writev(self.pid, &local, 1, &remote, 1, 0)
121125
guard bytesWritten == len else {
122-
throw ProcessError.processVmWriteFailure(pid: self.pid, address: remoteAddr, size: UInt64(len))
126+
throw ProcessError.processVmWriteFailure(
127+
pid: self.pid, address: remoteAddr, size: UInt64(len))
123128
}
124129
}
125130
}

tools/swift-inspect/Sources/SwiftInspectLinux/SystemHeaders/errno.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
113
#include <errno.h>
214

315
static inline
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
113
#include <sys/mman.h>

tools/swift-inspect/Sources/SwiftInspectLinux/SystemHeaders/ptrace.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
113
#include <signal.h>
214

315
#include <sys/ptrace.h>
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
113
#include <signal.h>
214

3-
static inline void* siginfo_si_addr(siginfo_t siginfo) {
15+
static inline
16+
void* siginfo_si_addr(siginfo_t siginfo) {
417
return siginfo.si_addr;
518
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
113
#include <unistd.h>

tools/swift-inspect/Sources/SwiftInspectLinux/SystemHeaders/wait.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
113
#include <stdbool.h>
214
#include <sys/wait.h>
315

tools/swift-inspect/Sources/swift-inspect/AndroidRemoteProcess.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ internal final class AndroidRemoteProcess: LinuxRemoteProcess {
127127
// Immediately read and process the heap metadata from the remote process,
128128
// skip past the trap/break instruction and resume the remote process.
129129
try self.process.readMem(remoteAddr: remoteDataAddr, localAddr: buffer, len: UInt(dataLen))
130-
allocations.append(contentsOf: try self.processHeapAllocations(buffer: buffer, len: dataLen))
130+
allocations.append(contentsOf: try self.processHeapMetadata(buffer: buffer, len: dataLen))
131131

132132
guard heap_iterate_metadata_init(buffer, dataLen) else {
133133
throw RemoteProcessError.heapIterationFailed
@@ -141,12 +141,12 @@ internal final class AndroidRemoteProcess: LinuxRemoteProcess {
141141
}
142142

143143
try self.process.readMem(remoteAddr: remoteDataAddr, localAddr: buffer, len: UInt(dataLen))
144-
allocations.append(contentsOf: try self.processHeapAllocations(buffer: buffer, len: dataLen))
144+
allocations.append(contentsOf: try self.processHeapMetadata(buffer: buffer, len: dataLen))
145145

146146
return allocations
147147
}
148148

149-
internal func processHeapAllocations(buffer: UnsafeMutableRawPointer, len: Int) throws -> [(
149+
internal func processHeapMetadata(buffer: UnsafeMutableRawPointer, len: Int) throws -> [(
150150
base: UInt64, len: UInt64
151151
)] {
152152
let callback: @convention(c) (UnsafeMutableRawPointer?, UInt64, UInt64) -> Void = {

0 commit comments

Comments
 (0)