Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f01e3400ae | |||
| 7277ee0e03 | |||
| d4f33e71ca | |||
| 525d45046b | |||
| adc931806e | |||
| defae63094 | |||
| 80746bdd0a | |||
| 2cfddd6892 | |||
| e9cffd432c | |||
| 9f43812fb5 | |||
| 9cc8c17785 | |||
| a0bfe70c1b | |||
| 1809e7963b | |||
| f25620d5d0 | |||
| 3bd448574b | |||
| c085164685 | |||
| baf9597d12 | |||
| 7ba397e50d | |||
| ad485ae151 | |||
| 662e436989 | |||
| 923624a26e | |||
| e2621e2fa1 | |||
| ea4824d488 | |||
| f1db8bf93d | |||
| 99a6c79fc5 | |||
| d3e04a9d4b | |||
| b3b195e0e6 | |||
| e434780428 | |||
| ceaaf36f0f | |||
| bb3bd2357e | |||
| 5f7686a18b | |||
| d9655c7867 | |||
| 84bcaad52f | |||
| 7152ac0033 | |||
| 54a65d6391 | |||
| 1ca1dbd9ff | |||
| 182caea1a4 | |||
| 5b47490c74 | |||
| b097912943 | |||
| a4f7b4204e | |||
| 9a2ef536ee | |||
| c859218177 | |||
| 1d5fbd8c42 | |||
| 93b3d9a764 | |||
| 4353fd38d5 | |||
| 97a034c8a4 | |||
| 566d2454b2 | |||
| c8d8ddd88b | |||
| 4915cdd24e | |||
| 7a48ec7baa | |||
| c6559c866c | |||
| 232bd5bdbc | |||
| f2fd8c4845 | |||
| 7faa1c401b | |||
| 1afd60a0bb | |||
| 5074f997bf | |||
| f5462810b8 | |||
| e735696872 | |||
| 383950b36a | |||
| feaee74aa6 | |||
| eaf2cef011 |
@@ -2,3 +2,5 @@
|
||||
/.build
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
.swiftpm
|
||||
.*.sw[nop]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Tomer Doron <tomer@apple.com> <tomer@apple.com>
|
||||
Tomer Doron <tomer@apple.com> <tomerd@apple.com>
|
||||
Tomer Doron <tomer@apple.com> <tomer.doron@gmail.com>
|
||||
@@ -0,0 +1,4 @@
|
||||
version: 1
|
||||
builder:
|
||||
configs:
|
||||
- documentation_targets: [Backtrace]
|
||||
@@ -1 +0,0 @@
|
||||
5.0.1
|
||||
@@ -0,0 +1,13 @@
|
||||
# file options
|
||||
|
||||
--swiftversion 5.0
|
||||
--exclude .build
|
||||
|
||||
# format options
|
||||
|
||||
--self insert
|
||||
--patternlet inline
|
||||
--stripunusedargs unnamed-only
|
||||
--ifdef no-indent
|
||||
|
||||
# rules
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# The matrix of builds should cover each combination of Swift version
|
||||
# and platform that is supported. The version of Swift used is specified
|
||||
# by .swift-version, unless SWIFT_SNAPSHOT is specified.
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:4.2.4 SWIFT_SNAPSHOT=4.2.4
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.0-xenial
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.0-bionic
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=4.2.1
|
||||
- os: osx
|
||||
osx_image: xcode10.2
|
||||
sudo: required
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
sudo: required
|
||||
|
||||
before_install:
|
||||
- git clone https://github.com/IBM-Swift/Package-Builder.git
|
||||
|
||||
script:
|
||||
- ./Package-Builder/build-package.sh -projectDir $TRAVIS_BUILD_DIR
|
||||
@@ -0,0 +1,21 @@
|
||||
For the purpose of tracking copyright, this is the list of individuals and
|
||||
organizations who have contributed source code to SwiftLinuxBacktrace.
|
||||
|
||||
For employees of an organization/company where the copyright of work done
|
||||
by employees of that company is held by the company itself, only the company
|
||||
needs to be listed here.
|
||||
|
||||
## COPYRIGHT HOLDERS
|
||||
|
||||
- Apple Inc. (all contributors with '@apple.com')
|
||||
|
||||
### Contributors
|
||||
|
||||
- Ian Partridge <i.partridge@uk.ibm.com>
|
||||
- Tanner <me@tanner.xyz>
|
||||
- Tomer Doron <tomer@apple.com>
|
||||
- Zsolt Váradi <vzsg@users.noreply.github.com>
|
||||
|
||||
**Updating this list**
|
||||
|
||||
Please do not edit this file manually. It is generated using `./scripts/generate_contributors_list.sh`. If a name is misspelled or appearing multiple times: add an entry in `./.mailmap`
|
||||
+16
-28
@@ -1,38 +1,26 @@
|
||||
// swift-tools-version:5.0
|
||||
// swift-tools-version:5.6
|
||||
|
||||
import PackageDescription
|
||||
|
||||
var backtraceDependencies: [Target.Dependency] = []
|
||||
|
||||
#if os(Linux)
|
||||
backtraceDependencies.append(.target(name: "CBacktrace"))
|
||||
#endif
|
||||
|
||||
var targets: [Target] = [
|
||||
.target(
|
||||
name: "Backtrace",
|
||||
dependencies: backtraceDependencies),
|
||||
.testTarget(
|
||||
name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"])
|
||||
]
|
||||
|
||||
#if os(Linux)
|
||||
targets.append(
|
||||
.target(
|
||||
name: "CBacktrace",
|
||||
dependencies: [])
|
||||
)
|
||||
#endif
|
||||
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]),
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: targets
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.executableTarget(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
// swift-tools-version:4.2
|
||||
|
||||
import PackageDescription
|
||||
|
||||
var backtraceDependencies: [Target.Dependency] = []
|
||||
|
||||
#if os(Linux)
|
||||
backtraceDependencies.append(.target(name: "CBacktrace"))
|
||||
#endif
|
||||
|
||||
var targets: [Target] = [
|
||||
.target(
|
||||
name: "Backtrace",
|
||||
dependencies: backtraceDependencies),
|
||||
.testTarget(
|
||||
name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"])
|
||||
]
|
||||
|
||||
#if os(Linux)
|
||||
targets.append(
|
||||
.target(
|
||||
name: "CBacktrace",
|
||||
dependencies: [])
|
||||
)
|
||||
#endif
|
||||
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: targets
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-backtrace",
|
||||
products: [
|
||||
.library(
|
||||
name: "Backtrace",
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.testTarget(name: "BacktraceTests",
|
||||
dependencies: ["Backtrace"]),
|
||||
]
|
||||
)
|
||||
@@ -1,12 +1,23 @@
|
||||
> [!IMPORTANT]
|
||||
> This library is now archived as backtracing is built into Swift 5.9+
|
||||
|
||||
# Backtrace
|
||||
|
||||
This Swift package provides support for automatically printing crash backtraces of Swift programs.
|
||||
|
||||
The library is designed to fill a gap in backtraces support for Swift on non-Darwin platforms.
|
||||
When this gap is closed at the language runtime level, this library will become redundant and be deprecated.
|
||||
|
||||
## Usage
|
||||
|
||||
Add `https://github.com/ianpartridge/swift-backtrace.git` as a dependency in your `Package.swift`.
|
||||
**Note**: You do not need this library on Linux as of Swift 5.9, which has
|
||||
built-in backtracing support.
|
||||
|
||||
Then, in your `main.swift`, do:
|
||||
Add `https://github.com/swift-server/swift-backtrace.git` as a dependency in your `Package.swift`.
|
||||
|
||||
### Crash backtraces
|
||||
|
||||
In your `main.swift`, do:
|
||||
|
||||
```swift
|
||||
import Backtrace
|
||||
@@ -15,7 +26,7 @@ import Backtrace
|
||||
Backtrace.install()
|
||||
```
|
||||
|
||||
Finally, make sure you build your application with debug symbols enabled:
|
||||
Finally, for Swift < 5.2, make sure you build your application with debug symbols enabled. Debug symbols are automatically included for Swift 5.2 and above.
|
||||
|
||||
```
|
||||
$ swift build -c release -Xswiftc -g
|
||||
@@ -23,6 +34,14 @@ $ swift build -c release -Xswiftc -g
|
||||
|
||||
When your app crashes, a stacktrace will be printed to `stderr`.
|
||||
|
||||
## Security
|
||||
|
||||
Please see [SECURITY.md](SECURITY.md) for details on the security process.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
@weissi, for the signal handling code!
|
||||
Ian Partridge ([GitHub](https://github.com/ianpartridge/), [Twitter](https://twitter.com/alfa)) the original author of this package.
|
||||
|
||||
Johannes Weiss ([GitHub](https://github.com/weissi), [Twitter](https://twitter.com/johannesweiss)) for the signal handling code.
|
||||
|
||||
Saleem Abdulrasool ([GitHub](https://github.com/compnerd), [Twitter](https://twitter.com/compnerd)) for the Windows port.
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
# Security
|
||||
|
||||
This document specifies the security process for the Backtrace project.
|
||||
|
||||
## Disclosures
|
||||
|
||||
### Private Disclosure Process
|
||||
|
||||
The Backtrace maintainers ask that known and suspected vulnerabilities be
|
||||
privately and responsibly disclosed by emailing
|
||||
[sswg-security-reports@forums.swift.org](mailto:sswg-security-reports@forums.swift.org)
|
||||
with the all the required detail.
|
||||
**Do not file a public issue.**
|
||||
|
||||
#### When to report a vulnerability
|
||||
|
||||
* You think you have discovered a potential security vulnerability in Backtrace.
|
||||
* You are unsure how a vulnerability affects Backtrace.
|
||||
|
||||
#### What happens next?
|
||||
|
||||
* A member of the team will acknowledge receipt of the report within 3
|
||||
working days (United States). This may include a request for additional
|
||||
information about reproducing the vulnerability.
|
||||
* We will privately inform the Swift Server Work Group ([SSWG][sswg]) of the
|
||||
vulnerability within 10 days of the report as per their [security
|
||||
guidelines][sswg-security].
|
||||
* Once we have identified a fix we may ask you to validate it. We aim to do this
|
||||
within 30 days. In some cases this may not be possible, for example when the
|
||||
vulnerability exists at the protocol level and the industry must coordinate on
|
||||
the disclosure process.
|
||||
* If a CVE number is required, one will be requested from [MITRE][mitre]
|
||||
providing you with full credit for the discovery.
|
||||
* We will decide on a planned release date and let you know when it is.
|
||||
* Prior to release, we will inform major dependents that a security-related
|
||||
patch is impending.
|
||||
* Once the fix has been released we will publish a security advisory on GitHub
|
||||
and in the Server → Security Updates category on the [Swift forums][swift-forums-sec].
|
||||
|
||||
[sswg]: https://github.com/swift-server/sswg
|
||||
[sswg-security]: https://github.com/swift-server/sswg/blob/main/security/README.md
|
||||
[swift-forums-sec]: https://forums.swift.org/c/server/security-updates/
|
||||
[mitre]: https://cveform.mitre.org/
|
||||
@@ -1,16 +1,44 @@
|
||||
#if os(Linux)
|
||||
import Glibc
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2022 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Swift 5.9 has its own built-in backtracing support in the runtime;
|
||||
// we don't want to activate this library if we're using 5.9 or above.
|
||||
#if swift(>=5.9) && !os(Windows)
|
||||
public enum Backtrace {
|
||||
@available(*, deprecated, message: "This is no longer needed in Swift 5.9")
|
||||
public static func install() {}
|
||||
|
||||
@available(*, deprecated, message: "This is no longer needed in Swift 5.9")
|
||||
public static func install(signals: [CInt]) {}
|
||||
|
||||
@available(*, deprecated, message: "This method will be removed in the next major version.")
|
||||
public static func print() {}
|
||||
}
|
||||
|
||||
#elseif os(Linux)
|
||||
import CBacktrace
|
||||
import Glibc
|
||||
|
||||
typealias CBacktraceErrorCallback = @convention(c) (_ data: UnsafeMutableRawPointer?, _ msg: UnsafePointer<CChar>?, _ errnum: CInt) -> Void
|
||||
typealias CBacktraceFullCallback = @convention(c) (_ data: UnsafeMutableRawPointer?, _ pc: UInt, _ filename: UnsafePointer<CChar>?, _ lineno: CInt, _ function: UnsafePointer<CChar>?) -> CInt
|
||||
typealias CBacktraceSimpleCallback = @convention(c) (_ data: UnsafeMutableRawPointer?, _ pc: UInt) -> CInt
|
||||
typealias CBacktraceSyminfoCallback = @convention(c) (_ data: UnsafeMutableRawPointer?, _ pc: UInt, _ filename: UnsafePointer<CChar>?, _ symval: UInt, _ symsize: UInt) -> Void
|
||||
|
||||
private let state = backtrace_create_state(CommandLine.arguments[0], /* BACKTRACE_SUPPORTS_THREADS */ 1, nil, nil)
|
||||
private let state = backtrace_create_state(nil, /* BACKTRACE_SUPPORTS_THREADS */ 1, nil, nil)
|
||||
|
||||
private let fullCallback: CBacktraceFullCallback? = {
|
||||
data, pc, filename, lineno, function in
|
||||
_, pc, filename, lineno, function in
|
||||
|
||||
var str = "0x"
|
||||
str.append(String(pc, radix: 16))
|
||||
@@ -39,21 +67,37 @@ private let fullCallback: CBacktraceFullCallback? = {
|
||||
}
|
||||
|
||||
private let errorCallback: CBacktraceErrorCallback? = {
|
||||
data, msg, errnum in
|
||||
_, msg, errNo in
|
||||
if let msg = msg {
|
||||
_ = withVaList([msg]) { vaList in
|
||||
vfprintf(stderr, "%s\n", vaList)
|
||||
_ = withVaList([msg, errNo]) { vaList in
|
||||
vfprintf(stderr, "SwiftBacktrace ERROR: %s (errno: %d)\n", vaList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func printBacktrace(signal: CInt) {
|
||||
_ = fputs("Received signal \(signal). Backtrace:\n", stderr)
|
||||
backtrace_full(state, /* skip */ 0, fullCallback, errorCallback, nil)
|
||||
fflush(stderr)
|
||||
}
|
||||
|
||||
public enum Backtrace {
|
||||
/// Install the backtrace handler on default signals: `SIGILL`, `SIGSEGV`, `SIGBUS`, `SIGFPE`.
|
||||
public static func install() {
|
||||
setupHandler(signal: SIGILL) { _ in
|
||||
backtrace_full(state, /* skip */ 0, fullCallback, errorCallback, nil)
|
||||
Backtrace.install(signals: [SIGILL, SIGSEGV, SIGBUS, SIGFPE])
|
||||
}
|
||||
|
||||
/// Install the backtrace handler when any of `signals` happen.
|
||||
public static func install(signals: [CInt]) {
|
||||
for signal in signals {
|
||||
self.setupHandler(signal: signal) { signal in
|
||||
printBacktrace(signal: signal)
|
||||
raise(signal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "This method will be removed in the next major version.")
|
||||
public static func print() {
|
||||
backtrace_full(state, /* skip */ 0, fullCallback, errorCallback, nil)
|
||||
}
|
||||
@@ -70,12 +114,179 @@ public enum Backtrace {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elseif os(Windows)
|
||||
#if swift(<5.4)
|
||||
#error("unsupported Swift version")
|
||||
#else
|
||||
@_implementationOnly import CRT
|
||||
@_implementationOnly import WinSDK
|
||||
#endif
|
||||
|
||||
public enum Backtrace {
|
||||
public static func install() {
|
||||
private static var MachineType: DWORD {
|
||||
#if arch(arm)
|
||||
DWORD(IMAGE_FILE_MACHINE_ARMNT)
|
||||
#elseif arch(arm64)
|
||||
DWORD(IMAGE_FILE_MACHINE_ARM64)
|
||||
#elseif arch(i386)
|
||||
DWORD(IMAGE_FILE_MACHINE_I386)
|
||||
#elseif arch(x86_64)
|
||||
DWORD(IMAGE_FILE_MACHINE_AMD64)
|
||||
#else
|
||||
#error("unsupported architecture")
|
||||
#endif
|
||||
}
|
||||
|
||||
public static func print() {
|
||||
/// Signal selection unavailable on Windows. Use ``install()-484jy``.
|
||||
@available(*, deprecated, message: "signal selection unavailable on Windows")
|
||||
public static func install(signals: [CInt]) {
|
||||
Backtrace.install()
|
||||
}
|
||||
|
||||
/// Install the backtrace handler on default signals.
|
||||
public static func install() {
|
||||
// Install a last-chance vectored exception handler to capture the error
|
||||
// before the termination and report the stack trace. It is unlikely
|
||||
// that this will be recovered at this point by a SEH handler.
|
||||
_ = AddVectoredExceptionHandler(0) { _ in
|
||||
// NOTE: GetCurrentProcess does not increment the reference count on
|
||||
// the process. This handle should _not_ be closed upon completion.
|
||||
let hProcess: HANDLE = GetCurrentProcess()
|
||||
|
||||
var cxr: CONTEXT = CONTEXT()
|
||||
cxr.ContextFlags =
|
||||
DWORD(CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
|
||||
RtlCaptureContext(&cxr)
|
||||
|
||||
_ = SymInitializeW(hProcess, nil, true)
|
||||
_ = SymSetOptions(DWORD(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME))
|
||||
|
||||
var Frame: STACKFRAME64 = STACKFRAME64()
|
||||
#if arch(arm)
|
||||
Frame.AddrPC.Offset = cxr.Pc
|
||||
Frame.AddrFrame.Offset = cxr.R11
|
||||
Frame.AddrStack.Offset = cxr.Sp
|
||||
#elseif arch(arm64)
|
||||
Frame.AddrPC.Offset = cxr.Pc
|
||||
Frame.AddrFrame.Offset = cxr.Fp
|
||||
Frame.AddrStack.Offset = cxr.Sp
|
||||
#elseif arch(i386)
|
||||
Frame.AddrPC.Offset = cxr.Eip
|
||||
Frame.AddrFrame.Offset = cxr.Ebp
|
||||
Frame.AddrStack.Offset = cxr.Esp
|
||||
#elseif arch(x86_64)
|
||||
Frame.AddrPC.Offset = cxr.Rip
|
||||
Frame.AddrFrame.Offset = cxr.Rbp
|
||||
Frame.AddrStack.Offset = cxr.Rsp
|
||||
#else
|
||||
#error("unsupported architecture")
|
||||
#endif
|
||||
Frame.AddrPC.Mode = AddrModeFlat
|
||||
Frame.AddrFrame.Mode = AddrModeFlat
|
||||
Frame.AddrStack.Mode = AddrModeFlat
|
||||
|
||||
// Constant indicating the maximum symbol length that we expect
|
||||
// during symbolication of the stack trace.
|
||||
let kMaxSymbolLength: Int = 255
|
||||
|
||||
// Heap allocate the buffer as we need to account for the trailing
|
||||
// storage that we need to provide.
|
||||
let pSymbolBuffer: UnsafeMutableRawPointer =
|
||||
UnsafeMutableRawPointer.allocate(byteCount: MemoryLayout<IMAGEHLP_SYMBOL64>.size + kMaxSymbolLength,
|
||||
alignment: 1)
|
||||
defer { pSymbolBuffer.deallocate() }
|
||||
|
||||
let pSymbol: UnsafeMutablePointer<IMAGEHLP_SYMBOL64> =
|
||||
pSymbolBuffer.bindMemory(to: IMAGEHLP_SYMBOL64.self,
|
||||
capacity: 1)
|
||||
|
||||
let hThread: HANDLE = GetCurrentThread()
|
||||
while StackWalk64(Backtrace.MachineType, hProcess, hThread,
|
||||
&Frame, &cxr, nil, SymFunctionTableAccess64,
|
||||
SymGetModuleBase64, nil) {
|
||||
var qwModuleBase: DWORD64 =
|
||||
SymGetModuleBase64(hProcess, Frame.AddrPC.Offset)
|
||||
|
||||
let module: String = withUnsafeMutablePointer(to: &qwModuleBase) {
|
||||
$0.withMemoryRebound(to: HINSTANCE.self, capacity: 1) { hInstance in
|
||||
String(decoding: [WCHAR](unsafeUninitializedCapacity: Int(MAX_PATH + 1)) {
|
||||
$1 = Int(GetModuleFileNameW(hInstance.pointee,
|
||||
$0.baseAddress,
|
||||
DWORD($0.count)))
|
||||
}, as: UTF16.self)
|
||||
}
|
||||
}
|
||||
|
||||
pSymbol.pointee.SizeOfStruct =
|
||||
DWORD(MemoryLayout<IMAGEHLP_SYMBOL64>.size)
|
||||
pSymbol.pointee.MaxNameLength = DWORD(kMaxSymbolLength)
|
||||
_ = SymGetSymFromAddr64(hProcess, Frame.AddrPC.Offset, nil,
|
||||
pSymbol)
|
||||
|
||||
var symbol: String =
|
||||
withUnsafePointer(to: &pSymbol.pointee.Name) {
|
||||
String(cString: $0)
|
||||
}
|
||||
|
||||
// Undecorate Swift 3+ names only. Earlier Swift decorations
|
||||
// are unsupported. Any MSVC name decoration has been
|
||||
// unperformed during the DbgHelp operation through the use of
|
||||
// the `SYMOPT_UNDNAME` option.
|
||||
if symbol.hasPrefix("$s") || symbol.hasPrefix("$S") {
|
||||
symbol = _stdlib_demangleName(symbol)
|
||||
}
|
||||
|
||||
var Displacement: DWORD = 0
|
||||
var Line: IMAGEHLP_LINE64 = IMAGEHLP_LINE64()
|
||||
Line.SizeOfStruct = DWORD(MemoryLayout<IMAGEHLP_LINE64>.size)
|
||||
_ = SymGetLineFromAddr64(hProcess, Frame.AddrPC.Offset,
|
||||
&Displacement, &Line)
|
||||
|
||||
var details: String = ""
|
||||
|
||||
if !symbol.isEmpty {
|
||||
// Truncate the module path to the filename. The
|
||||
// `PathFindFileNameW` call will return the beginning of the
|
||||
// string if a path separator character is not found.
|
||||
if let pszModule = module.withCString(encodedAs: UTF16.self,
|
||||
PathFindFileNameW) {
|
||||
details.append(", \(String(decodingCString: pszModule, as: UTF16.self))!\(symbol)")
|
||||
}
|
||||
}
|
||||
|
||||
if let szFileName = Line.FileName {
|
||||
details.append(" at \(String(cString: szFileName)):\(Line.LineNumber)")
|
||||
}
|
||||
|
||||
_ = details.withCString { pszDetails in
|
||||
withVaList([Frame.AddrPC.Offset, pszDetails]) {
|
||||
#if arch(arm64) || arch(x86_64)
|
||||
vfprintf(stderr, "%#016x%s\n", $0)
|
||||
#else
|
||||
vfprintf(stderr, "%#08x%s\n", $0)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ = SymCleanup(hProcess)
|
||||
|
||||
// We have not handled the exception, continue the search.
|
||||
return EXCEPTION_CONTINUE_SEARCH
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
public enum Backtrace {
|
||||
/// Install the backtrace handler on default signals. Available on Windows and Linux only.
|
||||
public static func install() {}
|
||||
|
||||
/// Install the backtrace handler on specific signals. Available on Linux only.
|
||||
public static func install(signals: [CInt]) {}
|
||||
|
||||
@available(*, deprecated, message: "This method will be removed in the next major version.")
|
||||
public static func print() {}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Swift 5.9 has its own built-in backtracing support in the runtime;
|
||||
// we don't want to activate this library if we're using 5.9 or above.
|
||||
#if !(swift(>=5.9) && !os(Windows))
|
||||
|
||||
#if os(Linux)
|
||||
import Glibc
|
||||
#elseif os(Windows)
|
||||
#if swift(<5.4)
|
||||
#error("unsupported Swift version")
|
||||
#else
|
||||
import Darwin
|
||||
@_implementationOnly
|
||||
import ucrt
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if os(Linux) || os(Windows)
|
||||
@_silgen_name("swift_demangle")
|
||||
public
|
||||
func _stdlib_demangleImpl(
|
||||
@@ -12,18 +36,19 @@ func _stdlib_demangleImpl(
|
||||
outputBuffer: UnsafeMutablePointer<CChar>?,
|
||||
outputBufferSize: UnsafeMutablePointer<UInt>?,
|
||||
flags: UInt32
|
||||
) -> UnsafeMutablePointer<CChar>?
|
||||
) -> UnsafeMutablePointer<CChar>?
|
||||
|
||||
internal func _stdlib_demangleName(_ mangledName: String) -> String {
|
||||
return mangledName.utf8CString.withUnsafeBufferPointer {
|
||||
(mangledNameUTF8CStr) in
|
||||
mangledNameUTF8CStr in
|
||||
|
||||
let demangledNamePtr = _stdlib_demangleImpl(
|
||||
mangledName: mangledNameUTF8CStr.baseAddress,
|
||||
mangledNameLength: UInt(mangledNameUTF8CStr.count - 1),
|
||||
outputBuffer: nil,
|
||||
outputBufferSize: nil,
|
||||
flags: 0)
|
||||
flags: 0
|
||||
)
|
||||
|
||||
if let demangledNamePtr = demangledNamePtr {
|
||||
let demangledName = String(cString: demangledNamePtr)
|
||||
@@ -33,3 +58,6 @@ internal func _stdlib_demangleName(_ mangledName: String) -> String {
|
||||
return mangledName
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# ``Backtrace``
|
||||
|
||||
Provides support for automatically printing crash backtraces of Swift programs.
|
||||
|
||||
## Overview
|
||||
|
||||
The Backtrace library is designed to fill a gap in backtraces support for Swift on non-Darwin platforms.
|
||||
When this gap is closed at the language runtime level, this library will become redundant and be deprecated.
|
||||
|
||||
## Getting started
|
||||
|
||||
When building web-services and daemons, direct usage of this library is discouraged.
|
||||
Instead, use [swift-service-lifecycle](https://github.com/swift-server/swift-service-lifecycle) which helps manage the application lifecycle including setting up backtraces hooks when needed.
|
||||
|
||||
Add `https://github.com/swift-server/swift-backtrace.git` as a dependency in your `Package.swift`.
|
||||
|
||||
### Crash backtraces
|
||||
|
||||
In your `main.swift`, do:
|
||||
|
||||
```swift
|
||||
import Backtrace
|
||||
|
||||
// Do this first
|
||||
Backtrace.install()
|
||||
```
|
||||
|
||||
Finally, for Swift < 5.2, make sure you build your application with debug symbols enabled. Debug symbols are automatically included for Swift 5.2 and above.
|
||||
|
||||
```
|
||||
$ swift build -c release -Xswiftc -g
|
||||
```
|
||||
|
||||
When your app crashes, a stacktrace will be printed to `stderr`.
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* atomic.c -- Support for atomic functions if not present.
|
||||
Copyright (C) 2013-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2013-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -111,3 +112,4 @@ backtrace_atomic_store_int (int *p, int v)
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* backtrace-supported.h.in -- Whether stack backtrace is supported.
|
||||
Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -64,3 +65,4 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
will work for variables. It will always work for functions. */
|
||||
|
||||
#define BACKTRACE_SUPPORTS_DATA 1
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* backtrace.c -- Entry point for stack backtrace library.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -98,7 +99,7 @@ unwind (struct _Unwind_Context *context, void *vdata)
|
||||
|
||||
/* Get a stack backtrace. */
|
||||
|
||||
int
|
||||
int __attribute__((noinline))
|
||||
backtrace_full (struct backtrace_state *state, int skip,
|
||||
backtrace_full_callback callback,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
@@ -127,3 +128,4 @@ backtrace_full (struct backtrace_state *state, int skip,
|
||||
_Unwind_Backtrace (unwind, &bdata);
|
||||
return bdata.ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef __linux__
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
@@ -13,6 +14,10 @@
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `getpagesize', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRNLEN 1
|
||||
@@ -35,8 +40,16 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
/* #undef HAVE_LIBZ */
|
||||
/* Define to 1 if you have KERN_PROC and KERN_PROC_PATHNAME in <sys/sysctl.h>.
|
||||
*/
|
||||
/* #undef HAVE_KERN_PROC */
|
||||
|
||||
/* Define to 1 if you have KERN_PROCARGS and KERN_PROC_PATHNAME in
|
||||
<sys/sysctl.h>. */
|
||||
/* #undef HAVE_KERN_PROC_ARGS */
|
||||
|
||||
/* Define if -llzma is available. */
|
||||
/* #undef HAVE_LIBLZMA */
|
||||
|
||||
/* Define to 1 if you have the <link.h> header file. */
|
||||
#define HAVE_LINK_H 1
|
||||
@@ -47,6 +60,9 @@
|
||||
/* Define to 1 if you have the `lstat' function. */
|
||||
#define HAVE_LSTAT 1
|
||||
|
||||
/* Define to 1 if you have the <mach-o/dyld.h> header file. */
|
||||
/* #undef HAVE_MACH_O_DYLD_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
@@ -84,7 +100,7 @@
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if -lz is available. */
|
||||
/* #undef HAVE_ZLIB */
|
||||
#define HAVE_ZLIB 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
@@ -133,6 +149,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
@@ -148,3 +169,4 @@
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
#endif
|
||||
|
||||
+1955
-677
File diff suppressed because it is too large
Load Diff
+1794
-213
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* fileline.c -- Get file and line number information in a backtrace.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -39,6 +40,14 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined (HAVE_KERN_PROC_ARGS) || defined (HAVE_KERN_PROC)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MACH_O_DYLD_H
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#include "include/backtrace.h"
|
||||
#include "internal.h"
|
||||
|
||||
@@ -46,6 +55,107 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
#define getexecname() NULL
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_KERN_PROC_ARGS) && !defined (HAVE_KERN_PROC)
|
||||
|
||||
#define sysctl_exec_name1(state, error_callback, data) NULL
|
||||
#define sysctl_exec_name2(state, error_callback, data) NULL
|
||||
|
||||
#else /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
|
||||
|
||||
static char *
|
||||
sysctl_exec_name (struct backtrace_state *state,
|
||||
int mib0, int mib1, int mib2, int mib3,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
int mib[4];
|
||||
size_t len;
|
||||
char *name;
|
||||
size_t rlen;
|
||||
|
||||
mib[0] = mib0;
|
||||
mib[1] = mib1;
|
||||
mib[2] = mib2;
|
||||
mib[3] = mib3;
|
||||
|
||||
if (sysctl (mib, 4, NULL, &len, NULL, 0) < 0)
|
||||
return NULL;
|
||||
name = (char *) backtrace_alloc (state, len, error_callback, data);
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
rlen = len;
|
||||
if (sysctl (mib, 4, name, &rlen, NULL, 0) < 0)
|
||||
{
|
||||
backtrace_free (state, name, len, error_callback, data);
|
||||
return NULL;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef HAVE_KERN_PROC_ARGS
|
||||
|
||||
static char *
|
||||
sysctl_exec_name1 (struct backtrace_state *state,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
/* This variant is used on NetBSD. */
|
||||
return sysctl_exec_name (state, CTL_KERN, KERN_PROC_ARGS, -1,
|
||||
KERN_PROC_PATHNAME, error_callback, data);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define sysctl_exec_name1(state, error_callback, data) NULL
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KERN_PROC
|
||||
|
||||
static char *
|
||||
sysctl_exec_name2 (struct backtrace_state *state,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
/* This variant is used on FreeBSD. */
|
||||
return sysctl_exec_name (state, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1,
|
||||
error_callback, data);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define sysctl_exec_name2(state, error_callback, data) NULL
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
|
||||
|
||||
#ifdef HAVE_MACH_O_DYLD_H
|
||||
|
||||
static char *
|
||||
macho_get_executable_path (struct backtrace_state *state,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
uint32_t len;
|
||||
char *name;
|
||||
|
||||
len = 0;
|
||||
if (_NSGetExecutablePath (NULL, &len) == 0)
|
||||
return NULL;
|
||||
name = (char *) backtrace_alloc (state, len, error_callback, data);
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
if (_NSGetExecutablePath (name, &len) != 0)
|
||||
{
|
||||
backtrace_free (state, name, len, error_callback, data);
|
||||
return NULL;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
#else /* !defined (HAVE_MACH_O_DYLD_H) */
|
||||
|
||||
#define macho_get_executable_path(state, error_callback, data) NULL
|
||||
|
||||
#endif /* !defined (HAVE_MACH_O_DYLD_H) */
|
||||
|
||||
/* Initialize the fileline information from the executable. Returns 1
|
||||
on success, 0 on failure. */
|
||||
|
||||
@@ -83,7 +193,7 @@ fileline_initialize (struct backtrace_state *state,
|
||||
|
||||
descriptor = -1;
|
||||
called_error_callback = 0;
|
||||
for (pass = 0; pass < 5; ++pass)
|
||||
for (pass = 0; pass < 8; ++pass)
|
||||
{
|
||||
int does_not_exist;
|
||||
|
||||
@@ -106,6 +216,15 @@ fileline_initialize (struct backtrace_state *state,
|
||||
(long) getpid ());
|
||||
filename = buf;
|
||||
break;
|
||||
case 5:
|
||||
filename = sysctl_exec_name1 (state, error_callback, data);
|
||||
break;
|
||||
case 6:
|
||||
filename = sysctl_exec_name2 (state, error_callback, data);
|
||||
break;
|
||||
case 7:
|
||||
filename = macho_get_executable_path (state, error_callback, data);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
@@ -199,3 +318,31 @@ backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
|
||||
state->syminfo_fn (state, pc, callback, error_callback, data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* A backtrace_syminfo_callback that can call into a
|
||||
backtrace_full_callback, used when we have a symbol table but no
|
||||
debug info. */
|
||||
|
||||
void
|
||||
backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
|
||||
const char *symname,
|
||||
uintptr_t symval ATTRIBUTE_UNUSED,
|
||||
uintptr_t symsize ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
|
||||
|
||||
bdata->ret = bdata->full_callback (bdata->full_data, pc, NULL, 0, symname);
|
||||
}
|
||||
|
||||
/* An error callback that corresponds to
|
||||
backtrace_syminfo_to_full_callback. */
|
||||
|
||||
void
|
||||
backtrace_syminfo_to_full_error_callback (void *data, const char *msg,
|
||||
int errnum)
|
||||
{
|
||||
struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
|
||||
|
||||
bdata->full_error_callback (bdata->full_data, msg, errnum);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef __linux__
|
||||
/* btest.c -- Filename header for libbacktrace library
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
@@ -44,6 +45,10 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
|
||||
# define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\')
|
||||
# define HAS_DRIVE_SPEC(f) ((f)[0] != '\0' && (f)[1] == ':')
|
||||
# define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || HAS_DRIVE_SPEC(f))
|
||||
#else
|
||||
# define IS_DIR_SEPARATOR(c) ((c) == '/')
|
||||
# define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* backtrace.h -- Public header file for stack backtrace library.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -54,13 +55,14 @@ struct backtrace_state;
|
||||
invalid after this function returns.
|
||||
|
||||
As a special case, the ERRNUM argument will be passed as -1 if no
|
||||
debug info can be found for the executable, but the function
|
||||
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
|
||||
MSG in this case will be something along the lines of "no debug
|
||||
info". Similarly, ERRNUM will be passed as -1 if there is no
|
||||
symbol table, but the function requires a symbol table (e.g.,
|
||||
backtrace_syminfo). This may be used as a signal that some other
|
||||
approach should be tried. */
|
||||
debug info can be found for the executable, or if the debug info
|
||||
exists but has an unsupported version, but the function requires
|
||||
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
|
||||
this case will be something along the lines of "no debug info".
|
||||
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
|
||||
but the function requires a symbol table (e.g., backtrace_syminfo).
|
||||
This may be used as a signal that some other approach should be
|
||||
tried. */
|
||||
|
||||
typedef void (*backtrace_error_callback) (void *data, const char *msg,
|
||||
int errnum);
|
||||
@@ -75,7 +77,13 @@ typedef void (*backtrace_error_callback) (void *data, const char *msg,
|
||||
use appropriate atomic operations. If THREADED is zero the state
|
||||
may only be accessed by one thread at a time. This returns a state
|
||||
pointer on success, NULL on error. If an error occurs, this will
|
||||
call the ERROR_CALLBACK routine. */
|
||||
call the ERROR_CALLBACK routine.
|
||||
|
||||
Calling this function allocates resources that cannot be freed.
|
||||
There is no backtrace_free_state function. The state is used to
|
||||
cache information that is expensive to recompute. Programs are
|
||||
expected to call this function at most once and to save the return
|
||||
value for all later calls to backtrace functions. */
|
||||
|
||||
extern struct backtrace_state *backtrace_create_state (
|
||||
const char *filename, int threaded,
|
||||
@@ -180,3 +188,4 @@ extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t addr,
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* internal.h -- Internal header file for stack backtrace library.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -56,6 +57,14 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ATTRIBUTE_FALLTHROUGH
|
||||
# if (GCC_VERSION >= 7000)
|
||||
# define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
|
||||
# else
|
||||
# define ATTRIBUTE_FALLTHROUGH
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYNC_FUNCTIONS
|
||||
|
||||
/* Define out the sync functions. These should never be called if
|
||||
@@ -179,7 +188,7 @@ struct backtrace_view
|
||||
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. Store the
|
||||
result in *VIEW. Returns 1 on success, 0 on error. */
|
||||
extern int backtrace_get_view (struct backtrace_state *state, int descriptor,
|
||||
off_t offset, size_t size,
|
||||
off_t offset, uint64_t size,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data, struct backtrace_view *view);
|
||||
|
||||
@@ -257,6 +266,18 @@ extern int backtrace_vector_release (struct backtrace_state *state,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data);
|
||||
|
||||
/* Free the space managed by VEC. This will reset VEC. */
|
||||
|
||||
static inline void
|
||||
backtrace_vector_free (struct backtrace_state *state,
|
||||
struct backtrace_vector *vec,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
vec->alc += vec->size;
|
||||
vec->size = 0;
|
||||
backtrace_vector_release (state, vec, error_callback, data);
|
||||
}
|
||||
|
||||
/* Read initial debug data from a descriptor, and set the
|
||||
fileline_data, syminfo_fn, and syminfo_data fields of STATE.
|
||||
Return the fileln_fn field in *FILELN_FN--this is done this way so
|
||||
@@ -274,23 +295,70 @@ extern int backtrace_initialize (struct backtrace_state *state,
|
||||
void *data,
|
||||
fileline *fileline_fn);
|
||||
|
||||
/* An enum for the DWARF sections we care about. */
|
||||
|
||||
enum dwarf_section
|
||||
{
|
||||
DEBUG_INFO,
|
||||
DEBUG_LINE,
|
||||
DEBUG_ABBREV,
|
||||
DEBUG_RANGES,
|
||||
DEBUG_STR,
|
||||
DEBUG_ADDR,
|
||||
DEBUG_STR_OFFSETS,
|
||||
DEBUG_LINE_STR,
|
||||
DEBUG_RNGLISTS,
|
||||
|
||||
DEBUG_MAX
|
||||
};
|
||||
|
||||
/* Data for the DWARF sections we care about. */
|
||||
|
||||
struct dwarf_sections
|
||||
{
|
||||
const unsigned char *data[DEBUG_MAX];
|
||||
size_t size[DEBUG_MAX];
|
||||
};
|
||||
|
||||
/* DWARF data read from a file, used for .gnu_debugaltlink. */
|
||||
|
||||
struct dwarf_data;
|
||||
|
||||
/* Add file/line information for a DWARF module. */
|
||||
|
||||
extern int backtrace_dwarf_add (struct backtrace_state *state,
|
||||
uintptr_t base_address,
|
||||
const unsigned char* dwarf_info,
|
||||
size_t dwarf_info_size,
|
||||
const unsigned char *dwarf_line,
|
||||
size_t dwarf_line_size,
|
||||
const unsigned char *dwarf_abbrev,
|
||||
size_t dwarf_abbrev_size,
|
||||
const unsigned char *dwarf_ranges,
|
||||
size_t dwarf_range_size,
|
||||
const unsigned char *dwarf_str,
|
||||
size_t dwarf_str_size,
|
||||
const struct dwarf_sections *dwarf_sections,
|
||||
int is_bigendian,
|
||||
struct dwarf_data *fileline_altlink,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data, fileline *fileline_fn);
|
||||
void *data, fileline *fileline_fn,
|
||||
struct dwarf_data **fileline_entry);
|
||||
|
||||
/* A data structure to pass to backtrace_syminfo_to_full. */
|
||||
|
||||
struct backtrace_call_full
|
||||
{
|
||||
backtrace_full_callback full_callback;
|
||||
backtrace_error_callback full_error_callback;
|
||||
void *full_data;
|
||||
int ret;
|
||||
};
|
||||
|
||||
/* A backtrace_syminfo_callback that can call into a
|
||||
backtrace_full_callback, used when we have a symbol table but no
|
||||
debug info. */
|
||||
|
||||
extern void backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
|
||||
const char *symname,
|
||||
uintptr_t symval,
|
||||
uintptr_t symsize);
|
||||
|
||||
/* An error callback that corresponds to
|
||||
backtrace_syminfo_to_full_callback. */
|
||||
|
||||
extern void backtrace_syminfo_to_full_error_callback (void *, const char *,
|
||||
int);
|
||||
|
||||
/* A test-only hook for elf_uncompress_zdebug. */
|
||||
|
||||
@@ -301,4 +369,14 @@ extern int backtrace_uncompress_zdebug (struct backtrace_state *,
|
||||
unsigned char **uncompressed,
|
||||
size_t *uncompressed_size);
|
||||
|
||||
/* A test-only hook for elf_uncompress_lzma. */
|
||||
|
||||
extern int backtrace_uncompress_lzma (struct backtrace_state *,
|
||||
const unsigned char *compressed,
|
||||
size_t compressed_size,
|
||||
backtrace_error_callback, void *data,
|
||||
unsigned char **uncompressed,
|
||||
size_t *uncompressed_size);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* mmap.c -- Memory allocation with mmap.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -42,6 +43,10 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
#include "include/backtrace.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef HAVE_DECL_GETPAGESIZE
|
||||
extern int getpagesize (void);
|
||||
#endif
|
||||
|
||||
/* Memory allocation on systems that provide anonymous mmap. This
|
||||
permits the backtrace functions to be invoked from a signal
|
||||
handler, assuming that mmap is async-signal safe. */
|
||||
@@ -321,5 +326,8 @@ backtrace_vector_release (struct backtrace_state *state,
|
||||
backtrace_free (state, (char *) vec->base + aligned, alc,
|
||||
error_callback, data);
|
||||
vec->alc = 0;
|
||||
if (vec->size == 0)
|
||||
vec->base = NULL;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* mmapio.c -- File views using mmap.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -40,6 +41,10 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
#include "include/backtrace.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef HAVE_DECL_GETPAGESIZE
|
||||
extern int getpagesize (void);
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED ((void *)-1)
|
||||
#endif
|
||||
@@ -51,7 +56,7 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
int
|
||||
backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
int descriptor, off_t offset, size_t size,
|
||||
int descriptor, off_t offset, uint64_t size,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data, struct backtrace_view *view)
|
||||
{
|
||||
@@ -60,6 +65,12 @@ backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
off_t pageoff;
|
||||
void *map;
|
||||
|
||||
if ((uint64_t) (size_t) size != size)
|
||||
{
|
||||
error_callback (data, "file size too large", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pagesize = getpagesize ();
|
||||
inpage = offset % pagesize;
|
||||
pageoff = offset - inpage;
|
||||
@@ -98,3 +109,4 @@ backtrace_release_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
if (munmap (const_cast.v, view->len) < 0)
|
||||
error_callback (data, "munmap", errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* posix.c -- POSIX file I/O routines for the backtrace library.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -67,7 +68,11 @@ backtrace_open (const char *filename, backtrace_error_callback error_callback,
|
||||
descriptor = open (filename, (int) (O_RDONLY | O_BINARY | O_CLOEXEC));
|
||||
if (descriptor < 0)
|
||||
{
|
||||
if (does_not_exist != NULL && errno == ENOENT)
|
||||
/* If DOES_NOT_EXIST is not NULL, then don't call ERROR_CALLBACK
|
||||
if the file does not exist. We treat lacking permission to
|
||||
open the file as the file not existing; this case arises when
|
||||
running the libgo syscall package tests as root. */
|
||||
if (does_not_exist != NULL && (errno == ENOENT || errno == EACCES))
|
||||
*does_not_exist = 1;
|
||||
else
|
||||
error_callback (data, filename, errno);
|
||||
@@ -98,3 +103,4 @@ backtrace_close (int descriptor, backtrace_error_callback error_callback,
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* print.c -- Print the current backtrace.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -80,7 +81,7 @@ error_callback (void *data, const char *msg, int errnum)
|
||||
|
||||
/* Print a backtrace. */
|
||||
|
||||
void
|
||||
void __attribute__((noinline))
|
||||
backtrace_print (struct backtrace_state *state, int skip, FILE *f)
|
||||
{
|
||||
struct print_data data;
|
||||
@@ -90,3 +91,4 @@ backtrace_print (struct backtrace_state *state, int skip, FILE *f)
|
||||
backtrace_full (state, skip + 1, print_callback, error_callback,
|
||||
(void *) &data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* simple.c -- The backtrace_simple function.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -55,7 +56,7 @@ struct backtrace_simple_data
|
||||
int ret;
|
||||
};
|
||||
|
||||
/* Unwind library callback routine. This is passd to
|
||||
/* Unwind library callback routine. This is passed to
|
||||
_Unwind_Backtrace. */
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
@@ -90,7 +91,7 @@ simple_unwind (struct _Unwind_Context *context, void *vdata)
|
||||
|
||||
/* Get a simple stack backtrace. */
|
||||
|
||||
int
|
||||
int __attribute__((noinline))
|
||||
backtrace_simple (struct backtrace_state *state, int skip,
|
||||
backtrace_simple_callback callback,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
@@ -106,3 +107,4 @@ backtrace_simple (struct backtrace_state *state, int skip,
|
||||
_Unwind_Backtrace (simple_unwind, &bdata);
|
||||
return bdata.ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* sort.c -- Sort without allocating memory
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -106,3 +107,4 @@ backtrace_qsort (void *basearg, size_t count, size_t size,
|
||||
goto tail_recurse;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifdef __linux__
|
||||
/* state.c -- Create the backtrace state.
|
||||
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -70,3 +71,4 @@ backtrace_create_state (const char *filename, int threaded,
|
||||
|
||||
return state;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Backtrace
|
||||
#if canImport(Darwin)
|
||||
import Darwin
|
||||
#elseif canImport(Glibc)
|
||||
import Glibc
|
||||
#elseif canImport(Musl)
|
||||
import Musl
|
||||
#endif
|
||||
|
||||
#if swift(<5.9) || os(Windows)
|
||||
Backtrace.install()
|
||||
#endif
|
||||
|
||||
func raiseSignal(_ signal: Int32) {
|
||||
raise(signal)
|
||||
}
|
||||
|
||||
let reason = CommandLine.arguments.count == 2 ? CommandLine.arguments[1] : "unknown"
|
||||
switch reason.uppercased() {
|
||||
case "SIGILL":
|
||||
raiseSignal(SIGILL)
|
||||
case "SIGSEGV":
|
||||
raiseSignal(SIGSEGV)
|
||||
case "SIGBUS":
|
||||
raiseSignal(SIGBUS)
|
||||
case "SIGFPE":
|
||||
raiseSignal(SIGFPE)
|
||||
default:
|
||||
fatalError(reason)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// BacktraceTests+XCTest.swift
|
||||
//
|
||||
import XCTest
|
||||
|
||||
///
|
||||
/// NOTE: This file was generated by generate_linux_tests.rb
|
||||
///
|
||||
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
|
||||
///
|
||||
|
||||
extension BacktraceTests {
|
||||
public static var allTests: [(String, (BacktraceTests) -> () throws -> Void)] {
|
||||
return [
|
||||
("testFatalError", testFatalError),
|
||||
("testSIGILL", testSIGILL),
|
||||
("testSIGSEGV", testSIGSEGV),
|
||||
("testSIGBUS", testSIGBUS),
|
||||
("testSIGFPE", testSIGFPE),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,110 @@
|
||||
import XCTest
|
||||
@testable import Backtrace
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
final class BacktraceTests: XCTestCase {
|
||||
func testExample() {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct
|
||||
// results.
|
||||
XCTAssert(true)
|
||||
import XCTest
|
||||
|
||||
public final class BacktraceTests: XCTestCase {
|
||||
func testFatalError() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#endif
|
||||
|
||||
#if swift(>=5.9)
|
||||
try XCTSkipIf(true, "test is not supported on Swift 5.9")
|
||||
#endif
|
||||
|
||||
let expectedError = UUID().uuidString
|
||||
let stderr = try runSample(reason: expectedError)
|
||||
print(stderr)
|
||||
|
||||
XCTAssert(stderr.contains("Received signal 4. Backtrace:"))
|
||||
XCTAssert(stderr.contains("Current stack trace:"), "expected stanard error to include backtrace")
|
||||
XCTAssert(stderr.contains("Fatal error: \(expectedError)"), "expected stanard error to include error information")
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testExample", testExample),
|
||||
]
|
||||
func testSIGILL() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#endif
|
||||
|
||||
#if swift(>=5.9)
|
||||
try XCTSkipIf(true, "test is not supported on Swift 5.9")
|
||||
#endif
|
||||
|
||||
let stderr = try runSample(reason: "SIGILL")
|
||||
print(stderr)
|
||||
|
||||
XCTAssert(stderr.contains("Received signal \(SIGILL). Backtrace:"))
|
||||
XCTAssert(stderr.contains("Sample.raiseSignal"))
|
||||
}
|
||||
|
||||
func testSIGSEGV() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#endif
|
||||
|
||||
#if swift(>=5.9)
|
||||
try XCTSkipIf(true, "test is not supported on Swift 5.9")
|
||||
#endif
|
||||
|
||||
let stderr = try runSample(reason: "SIGSEGV")
|
||||
print(stderr)
|
||||
|
||||
XCTAssert(stderr.contains("Received signal \(SIGSEGV). Backtrace:"))
|
||||
XCTAssert(stderr.contains("Sample.raiseSignal"))
|
||||
}
|
||||
|
||||
func testSIGBUS() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#endif
|
||||
|
||||
#if swift(>=5.9)
|
||||
try XCTSkipIf(true, "test is not supported on Swift 5.9")
|
||||
#endif
|
||||
|
||||
let stderr = try runSample(reason: "SIGBUS")
|
||||
print(stderr)
|
||||
|
||||
XCTAssert(stderr.contains("Received signal \(SIGBUS). Backtrace:"))
|
||||
XCTAssert(stderr.contains("Sample.raiseSignal"))
|
||||
}
|
||||
|
||||
func testSIGFPE() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#endif
|
||||
|
||||
#if swift(>=5.9)
|
||||
try XCTSkipIf(true, "test is not supported on Swift 5.9")
|
||||
#endif
|
||||
|
||||
let stderr = try runSample(reason: "SIGFPE")
|
||||
print(stderr)
|
||||
|
||||
XCTAssert(stderr.contains("Received signal \(SIGFPE). Backtrace:"))
|
||||
XCTAssert(stderr.contains("Sample.raiseSignal"))
|
||||
}
|
||||
|
||||
func runSample(reason: String) throws -> String {
|
||||
let pipe = Pipe()
|
||||
let process = Process()
|
||||
process.executableURL = URL(fileURLWithPath: "/usr/bin/swift")
|
||||
process.arguments = ["run", "Sample", reason]
|
||||
process.standardError = pipe
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
return String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import XCTest
|
||||
|
||||
#if !canImport(ObjectiveC)
|
||||
public func allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(BacktraceTests.allTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
+27
-3
@@ -1,7 +1,31 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// LinuxMain.swift
|
||||
//
|
||||
import XCTest
|
||||
|
||||
///
|
||||
/// NOTE: This file was generated by generate_linux_tests.rb
|
||||
///
|
||||
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
|
||||
///
|
||||
|
||||
#if os(Linux) || os(FreeBSD)
|
||||
import BacktraceTests
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += BacktraceTests.allTests()
|
||||
XCTMain(tests)
|
||||
XCTMain([
|
||||
testCase(BacktraceTests.allTests),
|
||||
])
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
ARG swift_version=5.0
|
||||
ARG ubuntu_version=bionic
|
||||
ARG base_image=swift:$swift_version-$ubuntu_version
|
||||
FROM $base_image
|
||||
# needed to do again after FROM due to docker limitation
|
||||
ARG swift_version
|
||||
ARG ubuntu_version
|
||||
|
||||
# set as UTF-8
|
||||
RUN apt-get update && apt-get install -y locales locales-all
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US.UTF-8
|
||||
|
||||
# dependencies
|
||||
RUN apt-get update && apt-get install -y wget
|
||||
RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests
|
||||
|
||||
# ruby and jazzy for docs generation
|
||||
RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev build-essential
|
||||
# jazzy no longer works on older version of ubuntu as ruby is too old.
|
||||
RUN if [ "${ubuntu_version}" = "jammy" ] ; then echo "gem: --no-document" > ~/.gemrc ; fi
|
||||
RUN if [ "${ubuntu_version}" = "jammy" ] ; then gem install jazzy ; fi
|
||||
|
||||
# tools
|
||||
RUN mkdir -p $HOME/.tools
|
||||
RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile
|
||||
|
||||
# swiftformat (until part of the toolchain)
|
||||
|
||||
ARG swiftformat_version=0.44.6
|
||||
RUN git clone --branch $swiftformat_version --depth 1 https://github.com/nicklockwood/SwiftFormat $HOME/.tools/swift-format
|
||||
RUN cd $HOME/.tools/swift-format && swift build -c release
|
||||
RUN ln -s $HOME/.tools/swift-format/.build/release/swiftformat $HOME/.tools/swiftformat
|
||||
@@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:16.04-5.1
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "xenial"
|
||||
swift_version: "5.1"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:16.04-5.1
|
||||
environment:
|
||||
- SANITIZER_ARG=--sanitize=thread
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:16.04-5.1
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:18.04-5.0
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "bionic"
|
||||
swift_version: "5.0"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:18.04-5.0
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:18.04-5.0
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:18.04-5.2
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "bionic"
|
||||
swift_version: "5.2"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:18.04-5.2
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:18.04-5.2
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:18.04-5.3
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "bionic"
|
||||
swift_version: "5.3"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:18.04-5.3
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:18.04-5.3
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:20.04-5.4
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "focal"
|
||||
swift_version: "5.4"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:20.04-5.4
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-5.4
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:20.04-5.5
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "focal"
|
||||
swift_version: "5.5"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:20.04-5.5
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-5.5
|
||||
@@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:20.04-5.6
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "focal"
|
||||
swift_version: "5.6"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:20.04-5.6
|
||||
environment:
|
||||
- FORCE_TEST_DISCOVERY=--enable-test-discovery
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-5.6
|
||||
@@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:20.04-5.7
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "focal"
|
||||
swift_version: "5.7"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:20.04-5.7
|
||||
environment:
|
||||
- FORCE_TEST_DISCOVERY=--enable-test-discovery
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-5.7
|
||||
@@ -0,0 +1,17 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:22.04-5.10
|
||||
build:
|
||||
args:
|
||||
base_image: "swiftlang/swift:nightly-5.10-jammy"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:22.04-5.10
|
||||
environment:
|
||||
- FORCE_TEST_DISCOVERY=--enable-test-discovery
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:22.04-5.10
|
||||
@@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:22.04-5.8
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "jammy"
|
||||
swift_version: "5.8"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:22.04-5.8
|
||||
environment:
|
||||
- FORCE_TEST_DISCOVERY=--enable-test-discovery
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:22.04-5.8
|
||||
@@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:22.04-5.9
|
||||
build:
|
||||
args:
|
||||
ubuntu_version: "jammy"
|
||||
swift_version: "5.9"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:22.04-5.9
|
||||
environment:
|
||||
- FORCE_TEST_DISCOVERY=--enable-test-discovery
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:22.04-5.9
|
||||
@@ -0,0 +1,17 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:22.04-main
|
||||
build:
|
||||
args:
|
||||
base_image: "swiftlang/swift:nightly-main-jammy"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:22.04-main
|
||||
environment:
|
||||
- FORCE_TEST_DISCOVERY=--enable-test-discovery
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:22.04-main
|
||||
@@ -0,0 +1,37 @@
|
||||
# this file is not designed to be run directly
|
||||
# instead, use the docker-compose.<os>.<swift> files
|
||||
# eg docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.1804.50.yaml run test
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:default
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
|
||||
common: &common
|
||||
image: swift-linux-backtrace:default
|
||||
depends_on: [runtime-setup]
|
||||
volumes:
|
||||
- ~/.ssh:/root/.ssh
|
||||
- ..:/code:z
|
||||
working_dir: /code
|
||||
cap_drop:
|
||||
- CAP_NET_RAW
|
||||
- CAP_NET_BIND_SERVICE
|
||||
|
||||
soundness:
|
||||
<<: *common
|
||||
command: /bin/bash -cl "./scripts/soundness.sh"
|
||||
|
||||
test:
|
||||
<<: *common
|
||||
command: /bin/bash -cl "swift test -c release -Xswiftc -g -Xswiftc -warnings-as-errors $${FORCE_TEST_DISCOVERY-} $${SANITIZER_ARG-}"
|
||||
|
||||
# util
|
||||
|
||||
shell:
|
||||
<<: *common
|
||||
entrypoint: /bin/bash -l
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
##===----------------------------------------------------------------------===##
|
||||
##
|
||||
## This source file is part of the SwiftLinuxBacktrace open source project
|
||||
##
|
||||
## Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
## See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
##
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
set -eu
|
||||
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
contributors=$( cd "$here"/.. && git shortlog -es | cut -f2 | sed 's/^/- /' )
|
||||
|
||||
cat > "$here/../CONTRIBUTORS.txt" <<- EOF
|
||||
For the purpose of tracking copyright, this is the list of individuals and
|
||||
organizations who have contributed source code to SwiftLinuxBacktrace.
|
||||
|
||||
For employees of an organization/company where the copyright of work done
|
||||
by employees of that company is held by the company itself, only the company
|
||||
needs to be listed here.
|
||||
|
||||
## COPYRIGHT HOLDERS
|
||||
|
||||
- Apple Inc. (all contributors with '@apple.com')
|
||||
|
||||
### Contributors
|
||||
|
||||
$contributors
|
||||
|
||||
**Updating this list**
|
||||
|
||||
Please do not edit this file manually. It is generated using \`./scripts/generate_contributors_list.sh\`. If a name is misspelled or appearing multiple times: add an entry in \`./.mailmap\`
|
||||
EOF
|
||||
Executable
+231
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
#
|
||||
# process_test_files.rb
|
||||
#
|
||||
# Copyright 2016 Tony Stone
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Created by Tony Stone on 5/4/16.
|
||||
#
|
||||
require 'getoptlong'
|
||||
require 'fileutils'
|
||||
require 'pathname'
|
||||
|
||||
include FileUtils
|
||||
|
||||
#
|
||||
# This ruby script will auto generate LinuxMain.swift and the +XCTest.swift extension files for Swift Package Manager on Linux platforms.
|
||||
#
|
||||
# See https://github.com/apple/swift-corelibs-xctest/blob/master/Documentation/Linux.md
|
||||
#
|
||||
def header(fileName)
|
||||
string = <<-eos
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// <FileName>
|
||||
//
|
||||
import XCTest
|
||||
|
||||
///
|
||||
/// NOTE: This file was generated by generate_linux_tests.rb
|
||||
///
|
||||
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
|
||||
///
|
||||
eos
|
||||
|
||||
string
|
||||
.sub('<FileName>', File.basename(fileName))
|
||||
.sub('<Date>', Time.now.to_s)
|
||||
end
|
||||
|
||||
def createExtensionFile(fileName, classes)
|
||||
extensionFile = fileName.sub! '.swift', '+XCTest.swift'
|
||||
print 'Creating file: ' + extensionFile + "\n"
|
||||
|
||||
File.open(extensionFile, 'w') do |file|
|
||||
file.write header(extensionFile)
|
||||
file.write "\n"
|
||||
|
||||
for classArray in classes
|
||||
file.write 'extension ' + classArray[0] + " {\n"
|
||||
file.write ' public static var allTests: [(String, (' + classArray[0] + ") -> () throws -> Void)] {\n"
|
||||
file.write " return [\n"
|
||||
|
||||
for funcName in classArray[1]
|
||||
file.write ' ("' + funcName + '", ' + funcName + "),\n"
|
||||
end
|
||||
|
||||
file.write " ]\n"
|
||||
file.write " }\n"
|
||||
file.write "}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def createLinuxMain(testsDirectory, allTestSubDirectories, files)
|
||||
fileName = testsDirectory + '/LinuxMain.swift'
|
||||
print 'Creating file: ' + fileName + "\n"
|
||||
|
||||
File.open(fileName, 'w') do |file|
|
||||
file.write header(fileName)
|
||||
file.write "\n"
|
||||
|
||||
file.write "#if os(Linux) || os(FreeBSD)\n"
|
||||
for testSubDirectory in allTestSubDirectories.sort { |x, y| x <=> y }
|
||||
file.write 'import ' + testSubDirectory + "\n"
|
||||
end
|
||||
file.write "\n"
|
||||
file.write "XCTMain([\n"
|
||||
|
||||
testCases = []
|
||||
for classes in files
|
||||
for classArray in classes
|
||||
testCases << classArray[0]
|
||||
end
|
||||
end
|
||||
|
||||
for testCase in testCases.sort { |x, y| x <=> y }
|
||||
file.write ' testCase(' + testCase + ".allTests),\n"
|
||||
end
|
||||
file.write "])\n"
|
||||
file.write "#endif\n"
|
||||
end
|
||||
end
|
||||
|
||||
def parseSourceFile(fileName)
|
||||
puts 'Parsing file: ' + fileName + "\n"
|
||||
|
||||
classes = []
|
||||
currentClass = nil
|
||||
inIfLinux = false
|
||||
inElse = false
|
||||
ignore = false
|
||||
|
||||
#
|
||||
# Read the file line by line
|
||||
# and parse to find the class
|
||||
# names and func names
|
||||
#
|
||||
File.readlines(fileName).each do |line|
|
||||
if inIfLinux
|
||||
if /\#else/.match(line)
|
||||
inElse = true
|
||||
ignore = true
|
||||
else
|
||||
if /\#end/.match(line)
|
||||
inElse = false
|
||||
inIfLinux = false
|
||||
ignore = false
|
||||
end
|
||||
end
|
||||
else
|
||||
if /\#if[ \t]+os\(Linux\)/.match(line)
|
||||
inIfLinux = true
|
||||
ignore = false
|
||||
end
|
||||
end
|
||||
|
||||
next if ignore
|
||||
# Match class or func
|
||||
match = line[/class[ \t]+[a-zA-Z0-9_]*(?=[ \t]*:[ \t]*XCTestCase)|func[ \t]+test[a-zA-Z0-9_]*(?=[ \t]*\(\))/, 0]
|
||||
if match
|
||||
|
||||
if match[/class/, 0] == 'class'
|
||||
className = match.sub(/^class[ \t]+/, '')
|
||||
#
|
||||
# Create a new class / func structure
|
||||
# and add it to the classes array.
|
||||
#
|
||||
currentClass = [className, []]
|
||||
classes << currentClass
|
||||
else # Must be a func
|
||||
funcName = match.sub(/^func[ \t]+/, '')
|
||||
#
|
||||
# Add each func name the the class / func
|
||||
# structure created above.
|
||||
#
|
||||
currentClass[1] << funcName
|
||||
end
|
||||
end
|
||||
end
|
||||
classes
|
||||
end
|
||||
|
||||
#
|
||||
# Main routine
|
||||
#
|
||||
#
|
||||
|
||||
testsDirectory = 'Tests'
|
||||
|
||||
options = GetoptLong.new(['--tests-dir', GetoptLong::OPTIONAL_ARGUMENT])
|
||||
options.quiet = true
|
||||
|
||||
begin
|
||||
options.each do |option, value|
|
||||
case option
|
||||
when '--tests-dir'
|
||||
testsDirectory = value
|
||||
end
|
||||
end
|
||||
rescue GetoptLong::InvalidOption
|
||||
end
|
||||
|
||||
allTestSubDirectories = []
|
||||
allFiles = []
|
||||
|
||||
Dir[testsDirectory + '/*'].each do |subDirectory|
|
||||
next unless File.directory?(subDirectory)
|
||||
directoryHasClasses = false
|
||||
Dir[subDirectory + '/*Test{s,}.swift'].each do |fileName|
|
||||
next unless File.file? fileName
|
||||
fileClasses = parseSourceFile(fileName)
|
||||
|
||||
#
|
||||
# If there are classes in the
|
||||
# test source file, create an extension
|
||||
# file for it.
|
||||
#
|
||||
next unless fileClasses.count > 0
|
||||
createExtensionFile(fileName, fileClasses)
|
||||
directoryHasClasses = true
|
||||
allFiles << fileClasses
|
||||
end
|
||||
|
||||
if directoryHasClasses
|
||||
allTestSubDirectories << Pathname.new(subDirectory).split.last.to_s
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Last step is the create a LinuxMain.swift file that
|
||||
# references all the classes and funcs in the source files.
|
||||
#
|
||||
if allFiles.count > 0
|
||||
createLinuxMain(testsDirectory, allTestSubDirectories, allFiles)
|
||||
end
|
||||
# eof
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
##===----------------------------------------------------------------------===##
|
||||
##
|
||||
## This source file is part of the SwiftLinuxBacktrace open source project
|
||||
##
|
||||
## Copyright (c) 2022 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
## See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
##
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
##===----------------------------------------------------------------------===##
|
||||
##
|
||||
## This source file is part of the Swift Distributed Actors open source project
|
||||
##
|
||||
## Copyright (c) 2018-2019 Apple Inc. and the Swift Distributed Actors project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
## See CONTRIBUTORS.md for the list of Swift Distributed Actors project authors
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
##
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
swift package --disable-sandbox preview-documentation --target $1
|
||||
Executable
+140
@@ -0,0 +1,140 @@
|
||||
#!/bin/bash
|
||||
##===----------------------------------------------------------------------===##
|
||||
##
|
||||
## This source file is part of the SwiftLinuxBacktrace open source project
|
||||
##
|
||||
## Copyright (c) 2017-2022 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
## See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
##
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
set -eu
|
||||
|
||||
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
function replace_acceptable_years() {
|
||||
# this needs to replace all acceptable forms with 'YEARS'
|
||||
sed -e 's/20[12][78901]-20[12][89012]/YEARS/' -e 's/2019/YEARS/' -e 's/202[012]/YEARS/'
|
||||
}
|
||||
|
||||
printf "=> Checking linux tests... "
|
||||
FIRST_OUT="$(git status --porcelain)"
|
||||
ruby "$here/../scripts/generate_linux_tests.rb" > /dev/null
|
||||
SECOND_OUT="$(git status --porcelain)"
|
||||
if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then
|
||||
printf "\033[0;31mmissing changes!\033[0m\n"
|
||||
git --no-pager diff
|
||||
exit 1
|
||||
else
|
||||
printf "\033[0;32mokay.\033[0m\n"
|
||||
fi
|
||||
|
||||
printf "=> Checking format... "
|
||||
FIRST_OUT="$(git status --porcelain)"
|
||||
swiftformat . > /dev/null 2>&1
|
||||
SECOND_OUT="$(git status --porcelain)"
|
||||
if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then
|
||||
printf "\033[0;31mformatting issues!\033[0m\n"
|
||||
git --no-pager diff
|
||||
exit 1
|
||||
else
|
||||
printf "\033[0;32mokay.\033[0m\n"
|
||||
fi
|
||||
|
||||
printf "=> Checking license headers\n"
|
||||
tmp=$(mktemp /tmp/.swift-aws-lambda-sanity_XXXXXX)
|
||||
|
||||
for language in swift-or-c bash dtrace; do
|
||||
printf " * $language... "
|
||||
declare -a matching_files
|
||||
declare -a exceptions
|
||||
expections=( )
|
||||
matching_files=( -name '*' )
|
||||
case "$language" in
|
||||
swift-or-c)
|
||||
exceptions=( -name Package.swift -o -name 'Package@*.swift' -o -path './Sources/CBacktrace/*' )
|
||||
matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' )
|
||||
cat > "$tmp" <<"EOF"
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) YEARS Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
EOF
|
||||
;;
|
||||
bash)
|
||||
matching_files=( -name '*.sh' )
|
||||
cat > "$tmp" <<"EOF"
|
||||
#!/bin/bash
|
||||
##===----------------------------------------------------------------------===##
|
||||
##
|
||||
## This source file is part of the SwiftLinuxBacktrace open source project
|
||||
##
|
||||
## Copyright (c) YEARS Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
## See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
##
|
||||
##===----------------------------------------------------------------------===##
|
||||
EOF
|
||||
;;
|
||||
dtrace)
|
||||
matching_files=( -name '*.d' )
|
||||
cat > "$tmp" <<"EOF"
|
||||
#!/usr/sbin/dtrace -q -s
|
||||
/*===----------------------------------------------------------------------===*
|
||||
*
|
||||
* This source file is part of the SwiftLinuxBacktrace open source project
|
||||
*
|
||||
* Copyright (c) YEARS Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
* Licensed under Apache License v2.0
|
||||
*
|
||||
* See LICENSE.txt for license information
|
||||
* See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
EOF
|
||||
;;
|
||||
*)
|
||||
echo >&2 "ERROR: unknown language '$language'"
|
||||
;;
|
||||
esac
|
||||
|
||||
expected_lines=$(cat "$tmp" | wc -l)
|
||||
expected_sha=$(cat "$tmp" | shasum)
|
||||
|
||||
(
|
||||
cd "$here/.."
|
||||
find . \
|
||||
\( \! -path './.build/*' -a \
|
||||
\( "${matching_files[@]}" \) -a \
|
||||
\( \! \( "${exceptions[@]}" \) \) \) | while read line; do
|
||||
if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then
|
||||
printf "\033[0;31mmissing headers in file '$line'!\033[0m\n"
|
||||
diff -u <(cat "$line" | replace_acceptable_years | head -n $expected_lines) "$tmp"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
printf "\033[0;32mokay.\033[0m\n"
|
||||
)
|
||||
done
|
||||
|
||||
rm "$tmp"
|
||||
@@ -1,3 +1,18 @@
|
||||
#!/bin/bash
|
||||
##===----------------------------------------------------------------------===##
|
||||
##
|
||||
## This source file is part of the SwiftLinuxBacktrace open source project
|
||||
##
|
||||
## Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
## See CONTRIBUTORS.txt for the list of SwiftLinuxBacktrace project authors
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
##
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# This script creates a vendored copy of libbacktrace that is
|
||||
@@ -48,12 +63,15 @@ done
|
||||
|
||||
EXCLUDES=(
|
||||
'*test*'
|
||||
'alloc.c'
|
||||
'nounwind.c'
|
||||
'pecoff.c'
|
||||
'read.c'
|
||||
'unknown.c'
|
||||
'xcoff.c'
|
||||
'macho.c'
|
||||
'alloc.c'
|
||||
'allocfail.c'
|
||||
'instrumented_alloc.c'
|
||||
)
|
||||
|
||||
for exclude in "${EXCLUDES[@]}"
|
||||
@@ -69,4 +87,7 @@ mv "$DSTROOT/backtrace.h" "$DSTROOT/include"
|
||||
echo "REPLACING references to \"backtrace.h\" with \"include/backtrace.h\""
|
||||
find $DSTROOT -name "*.[ch]" -print0 | xargs -0 sed -i -e 's#"backtrace.h"#"include/backtrace.h"#g'
|
||||
|
||||
echo "ADDING preprocessor conditionals"
|
||||
find $DSTROOT -name "*.[ch]" -print0 | xargs -0 sed -i -e '1i#ifdef __linux__' -e '$a#endif'
|
||||
|
||||
echo "DONE"
|
||||
|
||||
Reference in New Issue
Block a user