|
16 | 16 |
|
17 | 17 | import Swift
|
18 | 18 |
|
19 |
| -@_implementationOnly import _StringProcessing |
20 |
| - |
21 | 19 | @_implementationOnly import OS.Libc
|
22 | 20 |
|
23 | 21 | #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
|
@@ -476,107 +474,93 @@ public struct Backtrace: CustomStringConvertible, Sendable {
|
476 | 474 | return []
|
477 | 475 | }
|
478 | 476 |
|
479 |
| - let mapRegex = #/ |
480 |
| - ^(?<start>[A-Fa-f0-9]+)-(?<end>[A-Fa-f0-9]+)\s+ |
481 |
| - (?<perms>[-rwxsp]{4})\s+ |
482 |
| - (?<offset>[A-Fa-f0-9]+)\s+ |
483 |
| - (?<major>[A-Fa-f0-9]+):(?<minor>[A-Fa-f0-9]+)\s+ |
484 |
| - (?<inode>\d+)\s+ |
485 |
| - (?<pathname>.*)\s*$ |
486 |
| - /# |
487 |
| - let lines = procMaps.split(separator: "\n") |
488 |
| - |
489 | 477 | // Find all the mapped files and get high/low ranges
|
490 | 478 | var mappedFiles: [Substring:AddressRange] = [:]
|
491 |
| - for line in lines { |
492 |
| - if let match = try? mapRegex.wholeMatch(in: line) { |
493 |
| - let path = stripWhitespace(match.pathname) |
494 |
| - if match.inode == "0" || path == "" { |
495 |
| - continue |
496 |
| - } |
497 |
| - guard let start = Address(match.start, radix: 16), |
498 |
| - let end = Address(match.end, radix: 16) else { |
499 |
| - continue |
500 |
| - } |
| 479 | + for match in ProcMapsScanner(procMaps) { |
| 480 | + let path = stripWhitespace(match.pathname) |
| 481 | + if match.inode == "0" || path == "" { |
| 482 | + continue |
| 483 | + } |
| 484 | + guard let start = Address(match.start, radix: 16), |
| 485 | + let end = Address(match.end, radix: 16) else { |
| 486 | + continue |
| 487 | + } |
501 | 488 |
|
502 |
| - if let range = mappedFiles[path] { |
503 |
| - mappedFiles[path] = AddressRange(low: min(start, range.low), |
504 |
| - high: max(end, range.high)) |
505 |
| - } else { |
506 |
| - mappedFiles[path] = AddressRange(low: start, |
507 |
| - high: end) |
508 |
| - } |
| 489 | + if let range = mappedFiles[path] { |
| 490 | + mappedFiles[path] = AddressRange(low: min(start, range.low), |
| 491 | + high: max(end, range.high)) |
| 492 | + } else { |
| 493 | + mappedFiles[path] = AddressRange(low: start, |
| 494 | + high: end) |
509 | 495 | }
|
510 | 496 | }
|
511 | 497 |
|
512 | 498 | // Look for ELF headers in the process' memory
|
513 | 499 | typealias Source = MemoryImageSource<M>
|
514 | 500 | let source = Source(with: reader)
|
515 |
| - for line in lines { |
516 |
| - if let match = try? mapRegex.wholeMatch(in: line) { |
517 |
| - let path = stripWhitespace(match.pathname) |
518 |
| - if match.inode == "0" || path == "" { |
519 |
| - continue |
520 |
| - } |
| 501 | + for match in ProcMapsScanner(procMaps) { |
| 502 | + let path = stripWhitespace(match.pathname) |
| 503 | + if match.inode == "0" || path == "" { |
| 504 | + continue |
| 505 | + } |
521 | 506 |
|
522 |
| - guard let start = Address(match.start, radix: 16), |
523 |
| - let end = Address(match.end, radix: 16), |
524 |
| - let offset = Address(match.offset, radix: 16) else { |
525 |
| - continue |
526 |
| - } |
| 507 | + guard let start = Address(match.start, radix: 16), |
| 508 | + let end = Address(match.end, radix: 16), |
| 509 | + let offset = Address(match.offset, radix: 16) else { |
| 510 | + continue |
| 511 | + } |
527 | 512 |
|
528 |
| - if offset != 0 || end - start < EI_NIDENT { |
529 |
| - continue |
530 |
| - } |
| 513 | + if offset != 0 || end - start < EI_NIDENT { |
| 514 | + continue |
| 515 | + } |
531 | 516 |
|
532 |
| - // Extract the filename from path |
533 |
| - let name: Substring |
534 |
| - if let slashIndex = path.lastIndex(of: "/") { |
535 |
| - name = path.suffix(from: path.index(after: slashIndex)) |
536 |
| - } else { |
537 |
| - name = path |
538 |
| - } |
| 517 | + // Extract the filename from path |
| 518 | + let name: Substring |
| 519 | + if let slashIndex = path.lastIndex(of: "/") { |
| 520 | + name = path.suffix(from: path.index(after: slashIndex)) |
| 521 | + } else { |
| 522 | + name = path |
| 523 | + } |
539 | 524 |
|
540 |
| - // Inspect the image and extract the UUID and end of text |
541 |
| - let range = mappedFiles[path]! |
542 |
| - let subSource = SubImageSource(parent: source, |
543 |
| - baseAddress: Source.Address(range.low), |
544 |
| - length: Source.Size(range.high |
545 |
| - - range.low)) |
546 |
| - var theUUID: [UInt8]? = nil |
547 |
| - var endOfText: Address = range.low |
548 |
| - |
549 |
| - if let image = try? Elf32Image(source: subSource) { |
550 |
| - theUUID = image.uuid |
551 |
| - |
552 |
| - for hdr in image.programHeaders { |
553 |
| - if hdr.p_type == .PT_LOAD && (hdr.p_flags & PF_X) != 0 { |
554 |
| - endOfText = max(endOfText, range.low + Address(hdr.p_vaddr |
555 |
| - + hdr.p_memsz)) |
556 |
| - } |
| 525 | + // Inspect the image and extract the UUID and end of text |
| 526 | + let range = mappedFiles[path]! |
| 527 | + let subSource = SubImageSource(parent: source, |
| 528 | + baseAddress: Source.Address(range.low), |
| 529 | + length: Source.Size(range.high |
| 530 | + - range.low)) |
| 531 | + var theUUID: [UInt8]? = nil |
| 532 | + var endOfText: Address = range.low |
| 533 | + |
| 534 | + if let image = try? Elf32Image(source: subSource) { |
| 535 | + theUUID = image.uuid |
| 536 | + |
| 537 | + for hdr in image.programHeaders { |
| 538 | + if hdr.p_type == .PT_LOAD && (hdr.p_flags & PF_X) != 0 { |
| 539 | + endOfText = max(endOfText, range.low + Address(hdr.p_vaddr |
| 540 | + + hdr.p_memsz)) |
557 | 541 | }
|
558 |
| - } else if let image = try? Elf64Image(source: subSource) { |
559 |
| - theUUID = image.uuid |
| 542 | + } |
| 543 | + } else if let image = try? Elf64Image(source: subSource) { |
| 544 | + theUUID = image.uuid |
560 | 545 |
|
561 |
| - for hdr in image.programHeaders { |
562 |
| - if hdr.p_type == .PT_LOAD && (hdr.p_flags & PF_X) != 0 { |
563 |
| - endOfText = max(endOfText, range.low + Address(hdr.p_vaddr |
564 |
| - + hdr.p_memsz)) |
565 |
| - } |
| 546 | + for hdr in image.programHeaders { |
| 547 | + if hdr.p_type == .PT_LOAD && (hdr.p_flags & PF_X) != 0 { |
| 548 | + endOfText = max(endOfText, range.low + Address(hdr.p_vaddr |
| 549 | + + hdr.p_memsz)) |
566 | 550 | }
|
567 |
| - } else { |
568 |
| - // Not a valid ELF image |
569 |
| - continue |
570 | 551 | }
|
| 552 | + } else { |
| 553 | + // Not a valid ELF image |
| 554 | + continue |
| 555 | + } |
571 | 556 |
|
572 |
| - let image = Image(name: String(name), |
573 |
| - path: String(path), |
574 |
| - buildID: theUUID, |
575 |
| - baseAddress: range.low, |
576 |
| - endOfText: endOfText) |
| 557 | + let image = Image(name: String(name), |
| 558 | + path: String(path), |
| 559 | + buildID: theUUID, |
| 560 | + baseAddress: range.low, |
| 561 | + endOfText: endOfText) |
577 | 562 |
|
578 |
| - images.append(image) |
579 |
| - } |
| 563 | + images.append(image) |
580 | 564 | }
|
581 | 565 | #endif
|
582 | 566 |
|
|
0 commit comments