Hi, I am currently dealing with a crash when converting UnsafePointer<CChar>!
to String in Swift. The pointer comes from the type es_string_token_t
which my app receives from the Endpoint Security framework.
This is what my code looks like:
extension es_string_token_t {
var description: String {
if self.data != nil && self.length > 0 {
return String(cString: self.data)
}
return ""
}
}
And it produces the following crash:
Thread 4 Crashed:: Dispatch queue: com.apple.root.default-qos
0 libsystem_platform.dylib 0x18bd44864 _platform_strlen + 4
1 libswiftCore.dylib 0x198f3a3c0 String.init(cString:) + 32
2 com.company.app.App 0x10456aac0 0x104564000 + 27328
3 com.company.app.App 0x10456f768 0x104564000 + 46952
4 com.company.app.App 0x1045793d8 0x104564000 + 87000
5 com.company.app.App 0x10457e8f8 0x104564000 + 108792
6 com.company.app.App 0x10458758c 0x104564000 + 144780
7 libdispatch.dylib 0x18bb6a5f0 _dispatch_call_block_and_release + 32
8 libdispatch.dylib 0x18bb6c1b4 _dispatch_client_callout + 20
9 libdispatch.dylib 0x18bb7da04 _dispatch_root_queue_drain + 680
10 libdispatch.dylib 0x18bb7e104 _dispatch_worker_thread2 + 164
11 libsystem_pthread.dylib 0x18bd2c324 _pthread_wqthread + 228
12 libsystem_pthread.dylib 0x18bd2b080 start_wqthread + 8
My app is deployed on arround 13k macs and only some of them experience this crash which I havent been able to reproduce. Any help would be appreciated.
I found a solution similar to what Quinn suggested on Google's Project Santa's github. I just ported it to swift. Here it is:
let deadline = DispatchTime(uptimeNanoseconds: cMsg.pointee.deadline) - .seconds(2)
let handlerSemaphore = DispatchSemaphore(value: 0)
handlerSemaphore.signal()
let deadlineSemaphore = DispatchSemaphore(value: 0)
queue.asyncAfter(deadline: deadline) {
// Check if event handler has already responded
if handlerSemaphore.wait(timeout: .now()) == .timedOut {
// Event handler already responded so exit
return
}
// Deadline met, event handler still processing, default to allow
self.allowMessage(cMsg)
deadlineSemaphore.signal()
}
queue.async {
// Process auth event and respond
handleAuthEvent(cMsg)
// Check if deadline was met
if handlerSemaphore.wait(timeout: .now()) == .timedOut {
// Wait for deadline block to allow the message, then free
deadlineSemaphore.wait()
}
self.freeMessage(cMsg)
}