Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 |
@@ -3,3 +3,4 @@
|
||||
/Packages
|
||||
/*.xcodeproj
|
||||
.swiftpm
|
||||
.*.sw[nop]
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
--self insert
|
||||
--patternlet inline
|
||||
--stripunusedargs unnamed-only
|
||||
--comments ignore
|
||||
--ifdef no-indent
|
||||
|
||||
# rules
|
||||
|
||||
-50
@@ -1,50 +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: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.1-xenial
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.1-bionic
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=4.2.1
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
sudo: required
|
||||
- os: osx
|
||||
osx_image: xcode11.2
|
||||
sudo: required
|
||||
|
||||
before_install:
|
||||
- git clone https://github.com/IBM-Swift/Package-Builder.git
|
||||
|
||||
script:
|
||||
- ./Package-Builder/build-package.sh -projectDir $TRAVIS_BUILD_DIR
|
||||
@@ -2,8 +2,14 @@
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
@@ -17,7 +23,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
|
||||
@@ -25,9 +31,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
|
||||
|
||||
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/
|
||||
@@ -21,7 +21,7 @@ typealias CBacktraceFullCallback = @convention(c) (_ data: UnsafeMutableRawPoint
|
||||
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? = {
|
||||
_, pc, filename, lineno, function in
|
||||
@@ -53,18 +53,32 @@ private let fullCallback: CBacktraceFullCallback? = {
|
||||
}
|
||||
|
||||
private let errorCallback: CBacktraceErrorCallback? = {
|
||||
_, msg, _ 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)
|
||||
}
|
||||
|
||||
public enum Backtrace {
|
||||
/// Install the backtrace handler on default signals: `SIGILL`, `SIGSEGV`, `SIGBUS`, `SIGFPE`.
|
||||
public static func install() {
|
||||
self.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +100,173 @@ 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 {
|
||||
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
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "signal selection unavailable on Windows")
|
||||
public static func install(signals: [CInt]) {
|
||||
Backtrace.install()
|
||||
}
|
||||
|
||||
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 {
|
||||
public static func install() {}
|
||||
|
||||
public static func install(signals: [CInt]) {}
|
||||
|
||||
@available(*, deprecated, message: "This method will be removed in the next major version.")
|
||||
public static func print() {}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,16 @@
|
||||
|
||||
#if os(Linux)
|
||||
import Glibc
|
||||
#elseif os(Windows)
|
||||
#if swift(<5.4)
|
||||
#error("unsupported Swift version")
|
||||
#else
|
||||
@_implementationOnly
|
||||
import ucrt
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if os(Linux) || os(Windows)
|
||||
@_silgen_name("swift_demangle")
|
||||
public
|
||||
func _stdlib_demangleImpl(
|
||||
|
||||
@@ -94,14 +94,14 @@ fileline_initialize (struct backtrace_state *state,
|
||||
filename = state->filename;
|
||||
break;
|
||||
case 1:
|
||||
filename = getexecname ();
|
||||
break;
|
||||
case 2:
|
||||
filename = "/proc/self/exe";
|
||||
break;
|
||||
case 3:
|
||||
case 2:
|
||||
filename = "/proc/curproc/file";
|
||||
break;
|
||||
case 3:
|
||||
filename = getexecname ();
|
||||
break;
|
||||
case 4:
|
||||
snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
|
||||
(long) getpid ());
|
||||
|
||||
@@ -170,7 +170,7 @@ backtrace_alloc (struct backtrace_state *state,
|
||||
if (page == MAP_FAILED)
|
||||
{
|
||||
if (error_callback)
|
||||
error_callback (data, "mmap", errno);
|
||||
error_callback (data, "mmap for alloc", errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -71,7 +71,7 @@ backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, descriptor, pageoff);
|
||||
if (map == MAP_FAILED)
|
||||
{
|
||||
error_callback (data, "mmap", errno);
|
||||
error_callback (data, "mmap file i/o", errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,28 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Backtrace
|
||||
#if canImport(Darwin)
|
||||
import Darwin
|
||||
#elseif os(Linux)
|
||||
import Glibc
|
||||
#endif
|
||||
|
||||
Backtrace.install()
|
||||
|
||||
func raiseSignal(_ signal: Int32) {
|
||||
raise(signal)
|
||||
}
|
||||
|
||||
let reason = CommandLine.arguments.count == 2 ? CommandLine.arguments[1] : "unknown"
|
||||
Backtrace.install()
|
||||
fatalError(reason)
|
||||
switch reason.uppercased() {
|
||||
case "SIGILL":
|
||||
raiseSignal(SIGILL)
|
||||
case "SIGSEGV":
|
||||
raiseSignal(SIGSEGV)
|
||||
case "SIGBUS":
|
||||
raiseSignal(SIGBUS)
|
||||
case "SIGFPE":
|
||||
raiseSignal(SIGFPE)
|
||||
default:
|
||||
fatalError(reason)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,11 @@ import XCTest
|
||||
extension BacktraceTests {
|
||||
public static var allTests: [(String, (BacktraceTests) -> () throws -> Void)] {
|
||||
return [
|
||||
("testBacktrace", testBacktrace),
|
||||
("testFatalError", testFatalError),
|
||||
("testSIGILL", testSIGILL),
|
||||
("testSIGSEGV", testSIGSEGV),
|
||||
("testSIGBUS", testSIGBUS),
|
||||
("testSIGFPE", testSIGFPE),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,22 +15,76 @@
|
||||
import XCTest
|
||||
|
||||
public final class BacktraceTests: XCTestCase {
|
||||
func testBacktrace() {
|
||||
#if os(Linux)
|
||||
func testFatalError() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#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")
|
||||
}
|
||||
|
||||
func testSIGILL() throws {
|
||||
#if !os(Linux)
|
||||
try XCTSkipIf(true, "test is only supported on Linux")
|
||||
#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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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", expectedError]
|
||||
process.arguments = ["run", "Sample", reason]
|
||||
process.standardError = pipe
|
||||
XCTAssertNoThrow(try process.run())
|
||||
if process.isRunning {
|
||||
process.waitUntilExit()
|
||||
}
|
||||
let stderr = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
||||
print(stderr)
|
||||
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")
|
||||
#endif
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
return String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -17,20 +17,18 @@ 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
|
||||
RUN gem install jazzy --no-ri --no-rdoc
|
||||
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}" = "focal" ] ; then echo "gem: --no-document" > ~/.gemrc ; fi
|
||||
RUN if [ "${ubuntu_version}" = "focal" ] ; then gem install jazzy ; fi
|
||||
|
||||
# tools
|
||||
RUN mkdir -p $HOME/.tools
|
||||
RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile
|
||||
|
||||
# script to allow mapping framepointers on linux (until part of the toolchain)
|
||||
RUN wget -q https://raw.githubusercontent.com/apple/swift/master/utils/symbolicate-linux-fatal -O $HOME/.tools/symbolicate-linux-fatal
|
||||
RUN chmod 755 $HOME/.tools/symbolicate-linux-fatal
|
||||
|
||||
# swiftformat (until part of the toolchain)
|
||||
|
||||
ARG swiftformat_version=0.44.0
|
||||
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
|
||||
|
||||
@@ -6,7 +6,8 @@ services:
|
||||
image: swift-linux-backtrace:18.04-5.2
|
||||
build:
|
||||
args:
|
||||
base_image: "swiftlang/swift:nightly-5.2-bionic"
|
||||
ubuntu_version: "bionic"
|
||||
swift_version: "5.2"
|
||||
|
||||
test:
|
||||
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,16 @@
|
||||
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
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-5.6
|
||||
@@ -0,0 +1,15 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:20.04-5.7
|
||||
build:
|
||||
args:
|
||||
base_image: "swiftlang/swift:nightly-main-focal"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:20.04-5.7
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-5.7
|
||||
@@ -0,0 +1,15 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
runtime-setup:
|
||||
image: swift-linux-backtrace:20.04-main
|
||||
build:
|
||||
args:
|
||||
base_image: "swiftlang/swift:nightly-main-focal"
|
||||
|
||||
test:
|
||||
image: swift-linux-backtrace:20.04-main
|
||||
|
||||
shell:
|
||||
image: swift-linux-backtrace:20.04-main
|
||||
@@ -34,4 +34,4 @@ services:
|
||||
|
||||
shell:
|
||||
<<: *common
|
||||
entrypoint: /bin/bash
|
||||
entrypoint: /bin/bash -l
|
||||
|
||||
Reference in New Issue
Block a user