Skip to content

Commit

Permalink
Safety around using the Int type #11
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed Feb 8, 2024
1 parent 0d08110 commit e5b6389
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 11 deletions.
12 changes: 8 additions & 4 deletions Sources/Meter/DlfcnSymbolicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,20 @@ struct DynamicLibraryInfo {
}

extension DlfcnSymbolicator: Symbolicator {
public func symbolicate(address: Int, in target: SymbolicationTarget) -> [SymbolInfo] {
public func symbolicate(address: UInt64, in target: SymbolicationTarget) -> [SymbolInfo] {
guard let loadedImage = imageMap[target.uuid] else {
return []
}

let loadAddress = Int(bitPattern: loadedImage.header)
let relativeAddress = address - target.loadAddress
let processAddress = loadAddress + relativeAddress
let relativeAddress = address - UInt64(target.loadAddress)
let processAddress = UInt64(loadAddress) + relativeAddress

guard let info = DynamicLibraryInfo(address: processAddress) else {
if processAddress > Int.max {
return []
}

guard let info = DynamicLibraryInfo(address: Int(processAddress)) else {
return []
}

Expand Down
8 changes: 6 additions & 2 deletions Sources/Meter/Symbolicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public struct SymbolicationTarget: Hashable {
}

public protocol Symbolicator {
func symbolicate(address: Int, in target: SymbolicationTarget) -> [SymbolInfo]
func symbolicate(address: UInt64, in target: SymbolicationTarget) -> [SymbolInfo]
}

public extension Frame {
Expand All @@ -74,9 +74,13 @@ public extension Symbolicator {
let subframes = frame.subFrames ?? []
let symSubframes = subframes.map({ symbolicate(frame: $0, withOffsetAsLoadAddress: withOffsetAsLoadAddress) })

if frame.address > Int.max {
return Frame(frame: frame, symbolInfo: [], subFrames: symSubframes)
}

let addr = Int(frame.address)
let target = frame.symbolicationTarget(withOffsetAsLoadAddress: withOffsetAsLoadAddress)
let info = target.map({ symbolicate(address: addr, in: $0) }) ?? []
let info = target.map({ symbolicate(address: UInt64(addr), in: $0) }) ?? []

return Frame(frame: frame, symbolInfo: info, subFrames: symSubframes)
}
Expand Down
41 changes: 36 additions & 5 deletions Tests/MeterTests/SymbolicationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import XCTest
import BinaryImage

struct MockSymbolicator {
typealias SymbolicationHandler = (Int, SymbolicationTarget) -> [SymbolInfo]
typealias SymbolicationHandler = (UInt64, SymbolicationTarget) -> [SymbolInfo]

var symbolicationHandler: SymbolicationHandler

Expand All @@ -13,12 +13,14 @@ struct MockSymbolicator {
}

extension MockSymbolicator: Symbolicator {
func symbolicate(address: Int, in target: SymbolicationTarget) -> [SymbolInfo] {
func symbolicate(address: UInt64, in target: SymbolicationTarget) -> [SymbolInfo] {
return symbolicationHandler(address, target)
}
}

final class SymbolicationTests: XCTestCase {
lazy var processImages = BinaryImage.imageMap

// guard against 64bit addresses
#if !os(watchOS)
func testDlfcnSymbolicator() throws {
Expand All @@ -40,7 +42,36 @@ final class SymbolicationTests: XCTestCase {
XCTAssertNil(infoArray[0].lineNumber)
XCTAssertNil(infoArray[0].file)
}
#endif
#endif

func testDlfcnSymbolicatorWithAddressOutsideIntRange() throws {
let randomImage = try XCTUnwrap(processImages.first)

let symbolicator = DlfcnSymbolicator()

// the load address and path are both bogus and will not match the UUID
let target = try XCTUnwrap(
SymbolicationTarget(
uuid: randomImage.key,
loadAddress: 0x19d0c4000,
path: "/usr/lib/system/libsystem_kernel.dylib"
)
)

// this will fail, but it should not crash
let infoArray = symbolicator.symbolicate(address: UInt64(Int.max) + 1, in: target)

XCTAssertEqual(infoArray.count, 0)
}

func testDlfcnSymbolicatorWithFrameAddressOutsideIntRange() throws {
let symbolicator = DlfcnSymbolicator()

// this will fail, but it should not crash
let frame = Frame(address: UInt64(Int.max) + 1, subFrames: nil)

_ = symbolicator.symbolicate(frame: frame, withOffsetAsLoadAddress: true)
}

func testTargetCalculation() throws {
let uuid = UUID()
Expand Down Expand Up @@ -78,7 +109,7 @@ final class SymbolicationTests: XCTestCase {
let symbolInfoB = SymbolInfo(symbol: "symbolB", offset: 10)
let symbolInfoA = SymbolInfo(symbol: "symbolA", offset: 10)

let mockResults = [Int(frameB.address): [symbolInfoB], Int(frameA.address): [symbolInfoA]]
let mockResults = [frameB.address: [symbolInfoB], frameA.address: [symbolInfoA]]

let mockSymbolicator = MockSymbolicator { addr, _ in
return mockResults[addr]!
Expand Down Expand Up @@ -165,7 +196,7 @@ final class SymbolicationTests: XCTestCase {

let symbolInfo = SymbolInfo(symbol: "symSymbol", offset: 10)

let mockResults = [74565: [symbolInfo]]
let mockResults = [UInt64(74565): [symbolInfo]]

let mockSymbolicator = MockSymbolicator { addr, _ in
return mockResults[addr]!
Expand Down

0 comments on commit e5b6389

Please sign in to comment.