Compare commits
25 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 |
@@ -0,0 +1,4 @@
|
||||
version: 1
|
||||
builder:
|
||||
configs:
|
||||
- documentation_targets: [Backtrace]
|
||||
+6
-4
@@ -1,4 +1,4 @@
|
||||
// swift-tools-version:5.0
|
||||
// swift-tools-version:5.6
|
||||
|
||||
import PackageDescription
|
||||
|
||||
@@ -10,14 +10,16 @@ let package = Package(
|
||||
targets: ["Backtrace"]
|
||||
),
|
||||
],
|
||||
dependencies: [],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Backtrace",
|
||||
dependencies: ["CBacktrace"]),
|
||||
.target(name: "CBacktrace",
|
||||
dependencies: []),
|
||||
.target(name: "Sample",
|
||||
dependencies: ["Backtrace"]),
|
||||
.executableTarget(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"]),
|
||||
]
|
||||
)
|
||||
@@ -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,9 +1,18 @@
|
||||
> [!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
|
||||
|
||||
**Note**: You do not need this library on Linux as of Swift 5.9, which has
|
||||
built-in backtracing support.
|
||||
|
||||
Add `https://github.com/swift-server/swift-backtrace.git` as a dependency in your `Package.swift`.
|
||||
|
||||
### Crash backtraces
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// This source file is part of the SwiftLinuxBacktrace open source project
|
||||
//
|
||||
// Copyright (c) 2019-2020 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Copyright (c) 2019-2022 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
@@ -12,7 +12,21 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if os(Linux)
|
||||
// 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
|
||||
|
||||
@@ -64,12 +78,13 @@ private let errorCallback: CBacktraceErrorCallback? = {
|
||||
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 `SIGILL`.
|
||||
/// Install the backtrace handler on default signals: `SIGILL`, `SIGSEGV`, `SIGBUS`, `SIGFPE`.
|
||||
public static func install() {
|
||||
Backtrace.install(signals: [SIGILL])
|
||||
Backtrace.install(signals: [SIGILL, SIGSEGV, SIGBUS, SIGFPE])
|
||||
}
|
||||
|
||||
/// Install the backtrace handler when any of `signals` happen.
|
||||
@@ -77,6 +92,7 @@ public enum Backtrace {
|
||||
for signal in signals {
|
||||
self.setupHandler(signal: signal) { signal in
|
||||
printBacktrace(signal: signal)
|
||||
raise(signal)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,11 +138,13 @@ public enum Backtrace {
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 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
|
||||
@@ -262,8 +280,10 @@ public enum Backtrace {
|
||||
|
||||
#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.")
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// 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)
|
||||
@@ -55,3 +59,5 @@ internal func _stdlib_demangleName(_ mangledName: String) -> String {
|
||||
}
|
||||
}
|
||||
#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,6 +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
|
||||
|
||||
@@ -1,6 +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
|
||||
|
||||
@@ -1,6 +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
|
||||
@@ -99,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)
|
||||
|
||||
@@ -14,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
|
||||
@@ -36,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
|
||||
@@ -48,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
|
||||
|
||||
@@ -85,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.
|
||||
*/
|
||||
@@ -134,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 */
|
||||
|
||||
|
||||
+1953
-677
File diff suppressed because it is too large
Load Diff
+1792
-213
File diff suppressed because it is too large
Load Diff
@@ -1,6 +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
|
||||
@@ -40,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"
|
||||
|
||||
@@ -47,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. */
|
||||
|
||||
@@ -84,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;
|
||||
|
||||
@@ -94,19 +203,28 @@ fileline_initialize (struct backtrace_state *state,
|
||||
filename = state->filename;
|
||||
break;
|
||||
case 1:
|
||||
filename = "/proc/self/exe";
|
||||
filename = getexecname ();
|
||||
break;
|
||||
case 2:
|
||||
filename = "/proc/curproc/file";
|
||||
filename = "/proc/self/exe";
|
||||
break;
|
||||
case 3:
|
||||
filename = getexecname ();
|
||||
filename = "/proc/curproc/file";
|
||||
break;
|
||||
case 4:
|
||||
snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
|
||||
(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 ();
|
||||
}
|
||||
@@ -200,4 +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
|
||||
|
||||
@@ -45,7 +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,6 +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
|
||||
@@ -55,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);
|
||||
@@ -76,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,
|
||||
|
||||
@@ -1,6 +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
|
||||
@@ -57,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
|
||||
@@ -180,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);
|
||||
|
||||
@@ -258,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
|
||||
@@ -275,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. */
|
||||
|
||||
@@ -302,5 +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,6 +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
|
||||
@@ -43,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. */
|
||||
@@ -170,7 +174,7 @@ backtrace_alloc (struct backtrace_state *state,
|
||||
if (page == MAP_FAILED)
|
||||
{
|
||||
if (error_callback)
|
||||
error_callback (data, "mmap for alloc", errno);
|
||||
error_callback (data, "mmap", errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -322,6 +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,6 +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
|
||||
@@ -41,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
|
||||
@@ -52,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)
|
||||
{
|
||||
@@ -61,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;
|
||||
@@ -71,7 +81,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 file i/o", errno);
|
||||
error_callback (data, "mmap", errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +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
|
||||
@@ -68,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);
|
||||
|
||||
@@ -1,6 +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
|
||||
@@ -81,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;
|
||||
|
||||
@@ -1,6 +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
|
||||
@@ -56,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
|
||||
@@ -91,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)
|
||||
|
||||
@@ -1,6 +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
|
||||
|
||||
@@ -1,6 +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
|
||||
|
||||
@@ -13,7 +13,32 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
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"
|
||||
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,96 @@
|
||||
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
|
||||
|
||||
#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")
|
||||
}
|
||||
|
||||
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", 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) ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -18,9 +18,9 @@ RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools
|
||||
|
||||
# ruby and jazzy for docs generation
|
||||
RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev build-essential
|
||||
# switch of gem docs building
|
||||
RUN echo "gem: --no-document" > ~/.gemrc
|
||||
RUN if [ "${ubuntu_version}" != "xenial" ] ; then gem install jazzy ; fi
|
||||
# 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
|
||||
|
||||
@@ -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
|
||||
@@ -22,16 +22,16 @@ services:
|
||||
- CAP_NET_RAW
|
||||
- CAP_NET_BIND_SERVICE
|
||||
|
||||
sanity:
|
||||
soundness:
|
||||
<<: *common
|
||||
command: /bin/bash -cl "./scripts/sanity.sh"
|
||||
command: /bin/bash -cl "./scripts/soundness.sh"
|
||||
|
||||
test:
|
||||
<<: *common
|
||||
command: /bin/bash -cl "swift test -c release -Xswiftc -g -Xswiftc -warnings-as-errors $${SANITIZER_ARG-}"
|
||||
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
|
||||
entrypoint: /bin/bash -l
|
||||
|
||||
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
|
||||
@@ -3,7 +3,7 @@
|
||||
##
|
||||
## This source file is part of the SwiftLinuxBacktrace open source project
|
||||
##
|
||||
## Copyright (c) 2017-2018 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Copyright (c) 2017-2022 Apple Inc. and the SwiftLinuxBacktrace project authors
|
||||
## Licensed under Apache License v2.0
|
||||
##
|
||||
## See LICENSE.txt for license information
|
||||
@@ -19,7 +19,7 @@ here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
function replace_acceptable_years() {
|
||||
# this needs to replace all acceptable forms with 'YEARS'
|
||||
sed -e 's/2017-2018/YEARS/' -e 's/2019-2020/YEARS/' -e 's/2019/YEARS/' -e 's/2020/YEARS/'
|
||||
sed -e 's/20[12][78901]-20[12][89012]/YEARS/' -e 's/2019/YEARS/' -e 's/202[012]/YEARS/'
|
||||
}
|
||||
|
||||
printf "=> Checking linux tests... "
|
||||
@@ -57,7 +57,7 @@ for language in swift-or-c bash dtrace; do
|
||||
matching_files=( -name '*' )
|
||||
case "$language" in
|
||||
swift-or-c)
|
||||
exceptions=( -name Package.swift -o -path './Sources/CBacktrace/*' )
|
||||
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"
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -63,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[@]}"
|
||||
|
||||
Reference in New Issue
Block a user