77
88import Foundation
99
10+ /// A set of signals that would normally kill the program. We handle these
11+ /// signals by dumping the pretty stack trace description.
12+ let killSigs = [
13+ SIGILL, SIGABRT, SIGTRAP, SIGFPE,
14+ SIGBUS, SIGSEGV, SIGSYS, SIGQUIT
15+ ]
16+
17+ /// Needed because the type `sigaction` conflicts with the function `sigaction`.
18+ typealias SigAction = sigaction
19+
20+ /// A wrapper that associates a signal handler with the number it handles.
21+ struct SigHandler {
22+ /// The signal action, called when the handler is called.
23+ var action : SigAction
24+
25+ /// The signal number this will fire on.
26+ var signalNumber : Int32
27+ }
28+
1029/// Represents an entry in a stack trace. Contains information necessary to
1130/// reconstruct what was happening at the time this function was executed.
1231private struct TraceEntry : CustomStringConvertible {
@@ -102,6 +121,11 @@ private var __stackContextKey = pthread_key_t()
102121/// Creates a key for a thread-local reference to a PrettyStackTraceHandler.
103122private var stackContextKey : pthread_key_t = {
104123 pthread_key_create ( & __stackContextKey) { ptr in
124+ #if os(Linux)
125+ guard let ptr = ptr else {
126+ return
127+ }
128+ #endif
105129 let unmanaged = Unmanaged< PrettyStackTraceManager> . fromOpaque( ptr)
106130 unmanaged. release ( )
107131 }
@@ -122,29 +146,15 @@ private func threadLocalHandler() -> PrettyStackTraceManager {
122146 return unmanaged. takeUnretainedValue ( )
123147}
124148
125- /// A set of signals that would normally kill the program. We handle these
126- /// signals by dumping the pretty stack trace description.
127- let killSigs = [
128- SIGILL, SIGABRT, SIGTRAP, SIGFPE,
129- SIGBUS, SIGSEGV, SIGSYS, SIGQUIT
130- ]
131-
132- /// Needed because the type `sigaction` conflicts with the function `sigaction`.
133- typealias SigAction = sigaction
134-
135- /// A wrapper that associates a signal handler with the number it handles.
136- struct SigHandler {
137- /// The signal action, called when the handler is called.
138- var action : SigAction
139-
140- /// The signal number this will fire on.
141- var signalNumber : Int32
149+ extension Int32 {
150+ /// HACK: Just for compatibility's sake on Linux.
151+ public init ( bitPattern: Int32 ) { self = bitPattern }
142152}
143153
144154/// Registers the pretty stack trace signal handlers.
145155private func registerHandler( signal: Int32 ) {
146156 var newHandler = SigAction ( )
147- newHandler . __sigaction_u . __sa_handler = { signalNumber in
157+ let cHandler : @ convention ( c ) ( Int32 ) -> Swift . Void = { signalNumber in
148158 unregisterHandlers ( )
149159
150160 // Unblock all potentially blocked kill signals
@@ -155,13 +165,23 @@ private func registerHandler(signal: Int32) {
155165 threadLocalHandler ( ) . dump ( signalNumber)
156166 exit ( signalNumber)
157167 }
158- newHandler. sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK
168+ #if os(macOS)
169+ newHandler. __sigaction_u. __sa_handler = cHandler
170+ #elseif os(Linux)
171+ newHandler. __sigaction_handler = . init( sa_handler: cHandler)
172+ #else
173+ fatalError ( " Cannot register signal action handler on this platform " )
174+ #endif
175+ newHandler. sa_flags = Int32 ( bitPattern: SA_NODEFER) |
176+ Int32 ( bitPattern: SA_RESETHAND) |
177+ Int32 ( bitPattern: SA_ONSTACK)
159178 sigemptyset ( & newHandler. sa_mask)
160179
161180 var handler = SigAction ( )
162181 if sigaction ( signal, & newHandler, & handler) != 0 {
163182 let sh = SigHandler ( action: handler, signalNumber: signal)
164183 registeredSignalInfo [ numRegisteredSignalInfo] = sh
184+ numRegisteredSignalInfo += 1
165185 }
166186}
167187
@@ -189,11 +209,16 @@ private var newAltStackPointer: UnsafeMutableRawPointer?
189209/// Sets up an alternate stack and registers all signal handlers with the
190210/// system.
191211private let __setupStackOnce : Void = {
192- let altStackSize = UInt ( MINSIGSTKSZ) + ( UInt ( 64 ) * 1024 )
212+ #if os(macOS)
213+ typealias SSSize = UInt
214+ #else
215+ typealias SSSize = Int
216+ #endif
217+ let altStackSize = SSSize ( MINSIGSTKSZ) + ( SSSize ( 64 ) * 1024 )
193218
194219 /// Make sure we're not currently executing on an alternate stack already.
195220 guard sigaltstack ( nil , & oldAltStack) == 0 else { return }
196- guard oldAltStack. ss_flags & SS_ONSTACK == 0 else { return }
221+ guard Int ( oldAltStack. ss_flags) & Int ( SS_ONSTACK) == 0 else { return }
197222 guard oldAltStack. ss_sp == nil || oldAltStack. ss_size < altStackSize else {
198223 return
199224 }
@@ -233,4 +258,3 @@ public func trace<T>(_ action: String, file: StaticString = #file,
233258 defer { h. pop ( ) }
234259 return try actions ( )
235260}
236-
0 commit comments