Giter Club home page Giter Club logo

swiftcoroutine's Introduction

Swift Coroutine

macOS Ubuntu codecov codebeat badge

Many languages, such as Kotlin, Go, JavaScript, Python, Rust, C#, C++ and others, already have coroutines support that makes the async/await pattern implementation possible. This feature is not yet supported in Swift, but this can be improved by a framework without the need to change the language.

Main features

  • It is the first implementation of coroutines for Swift with iOS, macOS and Linux support.
  • It includes futures and channels that supplement coroutines for more flexibility.
  • It is completely lock-free and uses only atomic primitives for synchronizations.

Motivation

Asynchronous programming is usually associated with callbacks. It is quite convenient until there are too many of them and they start nesting. Then it's called a pyramid of doom or even callback hell.

Another problem of asynchronous programming is error handling, because Swift's natural error handling mechanism cannot be used.

What about Rx and other such frameworks?

There are many other frameworks that make it easy to use asynchronous code, such as Combine, RxSwift, PromiseKit and so on. They use other approaches that have some drawbacks:

  • Similar to callbacks, you also need to create chained calls, that’s why you can’t normally use loops, exception handling, etc.
  • Usually you need to learn a complex new API with hundreds of methods.
  • Instead of working with the actual data, you need to operate with some wrappers all the time.
  • Chaining of errors can be really complicated to handle.

Async/await

The async/await pattern is an alternative that allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function.

It is already well-established in other programming languages and is an evolution in asynchronous programming. The implementation of this pattern is possible thanks to coroutines.

Let’s have a look at the example with coroutine inside of which await() suspends it and resumes when the result is available without blocking the thread.

//executes coroutine on the main thread
DispatchQueue.main.startCoroutine {
    
    //extension that returns CoFuture<(data: Data, response: URLResponse)>
    let dataFuture = URLSession.shared.dataTaskFuture(for: imageURL)
    
    //await CoFuture result that suspends coroutine and doesn't block the thread
    let data: Data = try dataFuture.await().data

    //create UIImage from the data
    guard let image = UIImage(data: data) else { return }
    
    //execute heavy task on global queue and await the result without blocking the thread
    let thumbnail: UIImage = try DispatchQueue.global().await { image.makeThumbnail() }

    //set image in UIImageView on the main thread
    self.imageView.image = thumbnail
    
}

Documentation

API documentation

Requirements

  • Support only 64-bit architectures
  • iOS 10+ / macOS 10.12+ / Ubuntu
  • Xcode 10.4+
  • Swift 5.2+

Installation

Working with SwiftCoroutine

Coroutines

A coroutine is a computation that can be suspended and resumed at a later time without blocking a thread. Coroutines build upon regular functions and can be executed on any scheduler with a possibility to switch among them during execution.

Key benefits

  • Suspend instead of block. The main advantage of coroutines is the ability to suspend their execution at some point without blocking a thread and resuming later on.
  • Fast context switching. Switching between coroutines is much faster than switching between threads as it does not require the involvement of operating system.
  • Asynchronous code in synchronous manner. The use of coroutines allows an asynchronous, non-blocking function to be structured in a manner similar to an ordinary synchronous function. And even though coroutines can run in multiple threads, your code will still look consistent and therefore easy to understand.

Usage

The coroutines API design is as minimalistic as possible. It consists of the CoroutineScheduler protocol that describes how to schedule coroutines (DispatchQueue already conforms it), and the Coroutine structure with utility methods. This API is enough to do amazing things.

The following example shows the usage of await() inside a coroutine to wrap asynchronous calls.

//execute coroutine on the main thread
DispatchQueue.main.startCoroutine {
    
    //await URLSessionDataTask response without blocking the thread
    let (data, response, error) = try Coroutine.await { callback in
        URLSession.shared.dataTask(with: url, completionHandler: callback).resume()
    }
    
    . . . use response on the main thread . . . 
}

Here's how we can conform NSManagedObjectContext to CoroutineScheduler for launching coroutines on it.

extension NSManagedObjectContext: CoroutineScheduler {

    func scheduleTask(_ task: @escaping () -> Void) {
        perform(task)
    }
    
}

//execute coroutine on the main thread
DispatchQueue.main.startCoroutine {
    let context: NSManagedObjectContext //context with privateQueueConcurrencyType
    let request: NSFetchRequest<NSDictionary> //some complex request

    //execute request on the context without blocking the main thread
    let result: [NSDictionary] = try context.await { try context.fetch(request) }
}

Futures and Promises

A future is a read-only holder for a result that will be provided later and the promise is the provider of this result. They represent the eventual completion or failure of an asynchronous operation.

The futures and promises approach itself has become an industry standart. It is a convenient mechanism to synchronize asynchronous code. But together with coroutines, it takes the usage of asynchronous code to the next level and has become a part of the async/await pattern. If coroutines are a skeleton, then futures and promises are its muscles.

Main features

  • Performance. It is much faster than most of other futures and promises implementations.
  • Awaitable. You can await the result inside the coroutine.
  • Cancellable. You can cancel the whole chain as well as handle it and complete the related actions.

Usage

Futures and promises are represented by the corresponding CoFuture class and its CoPromise subclass.

//wraps some async func with CoFuture
func makeIntFuture() -> CoFuture<Int> {
    let promise = CoPromise<Int>()
    someAsyncFunc { int in
        promise.success(int)
    }
    return promise
}

It allows to start multiple tasks in parallel and synchronize them later with await().

//create CoFuture<Int> that takes 2 sec. from the example above 
let future1: CoFuture<Int> = makeIntFuture()

//execute coroutine on the global queue and returns CoFuture<Int> with future result
let future2: CoFuture<Int> = DispatchQueue.global().coroutineFuture {
    try Coroutine.delay(.seconds(3)) //some work that takes 3 sec.
    return 6
}

//execute coroutine on the main thread
DispatchQueue.main.startCoroutine {
    let sum: Int = try future1.await() + future2.await() //will await for 3 sec.
    self.label.text = "Sum is \(sum)"
}

It's very easy to transform or compose CoFutures into a new one.

let array: [CoFuture<Int>]

//create new CoFuture<Int> with sum of future results
let sum = CoFuture { try array.reduce(0) { try $0 + $1.await() } }

Channels

Futures and promises provide a convenient way to transfer a single value between coroutines. Channels provide a way to transfer a stream of values. Conceptually, a channel is similar to a queue that allows to suspend a coroutine on receive if it is empty, or on send if it is full.

This non-blocking primitive is widely used in such languages as Go and Kotlin, and it is another instrument that improves working with coroutines.

Usage

To create channels, use the CoChannel class.

//create a channel with a buffer which can store only one element
let channel = CoChannel<Int>(capacity: 1)

DispatchQueue.global().startCoroutine {
    for i in 0..<100 {
        //imitate some work
        try Coroutine.delay(.seconds(1))
        //sends a value to the channel and suspends coroutine if its buffer is full
        try channel.awaitSend(i)
    }
    
    //close channel when all values are sent
    channel.close()
}

DispatchQueue.global().startCoroutine {
    //receives values until closed and suspends a coroutine if it's empty
    for i in channel.makeIterator() {
        print("Receive", i)
    }
    
    print("Done")
}

Scope

All launched coroutines, CoFutures and CoChannels, usually do not need to be referenced. They are deinited after their execution. But often there is a need to complete them earlier, when they are no longer needed. For this, CoFuture and CoChannel have methods for canceling.

CoScope makes it easier to manage the life cycle of these objects. It allows you to keep weak references to them and cancel if necessary or on deinit.

Usage

You can add coroutines, CoFutures, CoChannels and other CoCancellable to CoScope to cancel them when they are no longer needed or on deinit.

class ViewController: UIViewController {

    let scope = CoScope() //will cancel all objects on `cancel()` or deinit
    
    func performSomeWork() {
        //create new `CoChannel` and add to `CoScope`
        let channel = makeSomeChannel().added(to: scope)
        
        //execute coroutine and add to `CoScope`
        DispatchQueue.main.startCoroutine(in: scope) { [weak self] in
            for item in channel.makeIterator() {
                try self?.performSomeWork(with: item)
            }
        }
    }
    
    func performSomeWork(with item: Item) throws {
        //create new `CoFuture` and add to `CoScope`
        let future = makeSomeFuture(item).added(to: scope)
        
        let result = try future.await()
        . . . do some work using result . . .
    }

}

swiftcoroutine's People

Contributors

belozierov avatar calebkleveter avatar yuao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftcoroutine's Issues

主线程栈溢出

不知道什么操作导致主线程栈溢出,导致出现UI渲染crash了,最后修改下面代码为512解决,想了解有没有什么错误写法导致库的栈不释放,很容易栈溢出
internal static let recommended = Coroutine.StackSize(size: 512 * 1024)

Add finally block feature

Hi,

I developed a feature that I found missing.

The problem is that I want to continue the execution of a coroutine block even if there is an error, for example a loader must disappear after the request whether there is an error or not.

With current framework:

DispatchQueue.main.startCoroutine(in: self.scope) {

isLoading = true 

    do {
        try self.service.getAll().await()
        try self.service.getAll().await() // Error occurred go to catch block
        try self.service.getAll().await()

        isLoading = false
    } catch {
        // Error occurred
         isLoading = false
    }
}

With this version as soon as there is an error we do not continue the block we go into the catch block. But the problem is that isLoading = false is written twice

I know I can also do this which will not stop the block but it is not what I reach, if there is an error I want the block to be stopped

DispatchQueue.main.startCoroutine(in: self.scope) {

isLoading = true 

        try? self.service.getAll().await()
        try? self.service.getAll().await() // Error occurred but I dont want continue to the next request, I want hide the loader
        try? self.service.getAll().await()

        isLoading = false
}

So my solution is as follows, I wrap the coroutine block to make it clearer, Async / Await. And I added 2 blocks to catch the error, and a finally block which will be executed even if we get an error.

isLoading = true

async {
    try self.service.getAll().await()
    try self.service.getAll().await() // Error go to catch
    try self.service.getAll().await()
}.catch { error in
    Log.s("Error occurred:  \(error.localizedDescription)")
}.finally {
   // This block will be executed at the end of the block even if there is an error
   isLoading = false
 }

I already wrote this wrapper, if you are interested in integrating it into the framework I can make a pull request. This way will not replace the old way, it will just be a new possibility way

Typed Errors in CoFuture

Is there a reason that CoFuture is not generic to its Error result type as well as its Value? As it is, similarly to Swift's untyped throwing functions, I'm always needing a default clause when I switch over CoFuture failure cases. I assume there's a good reason for designing it this way....

Thread safety of CoChannels

Can CoChannel be cancelled from different thread than where it has been created? Ie, I create channels on DispatchQueue.global(), and cancel them later at DispatchQueue.main, as they become unneeded. But channels seem to continue working until app termination.

Can a `CoChannel` have multiple receivers?

I have two objects that call makeIterator() on the same instance of a CoChannel, and only the first caller is receiving values:

class SomeClass {
    func observe(channel: CoChannel<SomeData?>) {
        scheduler.startCoroutine(in: scope) { [weak self] in
            for item in channel.makeIterator() {
                self?.item = item
            }
        }
    }
}

let obj1 = SomeClass()
let obj2 = SomeClass()

obj1.observe(channel: someChannel) // this one receives
obj2.observe(channel: someChannel) // this one doesn't

It seems like all the methods on a CoChannel only allow consuming the value (remove and return), and I'm guessing that may be the reason the second observer never receives anything.

Is it possible to just peek, and therefore allow have multiple observers, like Observable of Rx or SharedFlow of Kotlin coroutine?

UnitTest `CoFutureAwaitTests testNestetAwaits` fail.

Hello dev:

UnitTest CoFutureAwaitTests testNestetAwaits fail when swift test for this project on macOS 10.14.6. Thanks.

>  swift test

// …

Test Case '-[SwiftCoroutineTests.CoFutureAwaitTests testConcurrency]' started.
Test Case '-[SwiftCoroutineTests.CoFutureAwaitTests testConcurrency]' passed (1.900 seconds).
Test Case '-[SwiftCoroutineTests.CoFutureAwaitTests testNestetAwaits]' started.
Exited with signal code 11

`Coroutine.await` crashes for iOS

Calling the below code crashes with
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file SwiftCoroutine/SharedCoroutine.swift, line 112.

The crashing version:

let scheduler = DispatchQueue.main
let repo = SomeRepository()

class SomeRepository {
    func getSomethingAsync() throws -> [String] {
        return try Coroutine.await { (continuation) in
            try! Coroutine.delay(.seconds(2))
            continuation(["foo", "bar", "baz",])
        }

    }
}

func foo() {
    scheduler.startCoroutine {
        do {
            let something = try repo.getSomethingAsync()
            print(something)
        } catch {
            #warning("TODO: handle error")
        }
    }
}

However, this is fine:

class SomeRepository {
    func getSomethingAsync() throws -> [String] {
        // getSomethingAsync is guaranteed to be called inside a coroutine
        try! Coroutine.delay(.seconds(2))
        return ["foo", "bar", "baz",]
    }
}

Not sure if this is expected behavior.
If it is, I think it might be a good idea to mention dos and don'ts in the documentation.

CoFutureAwaitTests.swift:51 - testConcurrency() - unit test fails

When running the unit tests of the current master branch I get the following test crash

commit 014ebe763cb08bb9e04dcf112787e585f7dc00f5 (HEAD -> master, origin/master, origin/HEAD)

In file and line: CoFutureAwaitTests.swift:51

Bildschirmfoto 2020-03-30 um 09 21 21

xctest(7034,0x700009087000) malloc: *** error for object 0x111abe000: pointer being freed was not allocated
xctest(7034,0x700009087000) malloc: *** set a breakpoint in malloc_error_break to debug
  • Xcode Version 11.4 (11E146)
  • macOS Catalina 10.15.4 (19E266)
  • MacBook Pro (16", 2019)

If it's of interest to you I will debug further using your instructions.

Request - Cocoapod support

Hi!
Wonderful and interesting project!
I was wondering if you're planning to support Cocoapod in future release.

Thank you!

Extending Generator to include Input and Output

Javascript Generators allow for both input and output arguments in their yield:

  `[input] = yield [output]`

I have found this incredibly useful in using coroutines that typically either:

  • generate data: Generator<Void, Output>
  • transform data: Generator<Input, Output>
  • consume data: Generator<Input, Void>

Is it possible to extend Generator in this way?

Let me say, I love the ambition of this project! Having been a swift dev for a few years, I recently jumped into javascript and kotlin, and have found async function generators , coroutines and structured concurrency to be the single most important revolution in language design in a generation. Having to go back to using RxFeedback with switch yard state-machines fills me with dread.


Some motivating examples:

Notice in the examples below how coroutines allow for much more elegant way to store state and correctly consume a sequence (i.e. a grammar) of events.

An async state machine can also be beautifully coded as a Generator<Event, State> with events sent to the machine using let newState = stateflow.next(event)

I have a server-side generator that creates websocket events:

async function* videoDownloader({
  localVideoFilePath,
  videoURL,
  videoID
}) {
  yield State.Initial
  const localFileStream = fs.createWriteStream(localVideoFilePath)
  const localFileCompleted = new Promise(resolve => localFileStream.once('close', () => resolve()))
  const videoPipe = videoStream
    .pipe(localFileStream)
  const opened = new Promise(resolve => videoPipe.once('open', () => resolve()))
  const closed = new Promise(resolve => videoPipe.once('close', () => resolve({
    event: 'close'
  })))
  const error = new Promise(resolve => videoPipe.once('error', error => resolve({
    event: 'close',
    error: error
  })))
  await opened
  const result = await Promise.race([closed, error])
  switch (result.event) {
  case 'closed': 
     yield State.Complete
     break
  case 'error':
    yield State.Error(result.message) 
  }
}

with a client-side consumer that monitors so:

  function* processDownload() {
    var next = yield
    expect(next, 'Initial')
    next = yield
    expect(next, 'ReceivedResponse')
    processMonitor.videoMetadata = next['0']
    processMonitor.videoMetadata.json = processMonitor.videoMetadataJson
    processMonitor.videoDuration = parseInt(processMonitor.videoMetadata.length.slice(0, -2))
    next = yield
    expect(next, 'Downloading')
    do {
      const percent = next['0']
      downloadProgress.progress('set percent', percent)
      downloadProgress.progress('set label', `Downloading ${percent.toFixed(0)}%`)
      downloadProgress.progress('set bar label', `${percent.toFixed(0)}%`)
      next = yield
    } while (next._name === 'Downloading')

    expect(next, 'Complete')
    downloadProgress.progress('set success', 'Video download complete')
    processMonitor.download.isActive = false
    processMonitor.download.isCompleted = true
    processMonitor.conversion.isActive = true
  }

Or for android / kotlin I use a builder function to implement a coroutine-based state machine so:

@ExperimentalCoroutinesApi
@FlowPreview
private val stateFlow = StateFlow<Mode, Event> {

    uninitialized@ while (true) {
        yield(Mode.Uninitialized) thenRequire Command.Initialize
        yield(Mode.Initializing) thenRequire Response.Initialized
        when (yield(Mode.Initialized)) {
            is Command.Prepare   -> {
                yield(Mode.Preparing) thenRequire Response.Prepared
            }
            Command.Uninitialize -> {
                yield(Mode.Uninitializing) thenRequire Response.Uninitialized
                continue@uninitialized
            }
            else                 -> exception()
        }
        ready@ while (true) {
            when (yield(Mode.Ready)) {
                Command.Play         -> {
                    when (yield(Mode.Playing)) {
                        Command.Stop     -> {
                            yield(Mode.Stopping) thenRequire Response.Stopped
                            continue@ready
                        }
                        Response.Stopped -> continue@ready
                        else             -> exception()
                    }
                }
                is Command.Prepare   -> {
                    yield(Mode.Preparing) thenRequire Response.Prepared
                    continue@ready
                }
                Command.Uninitialize -> {
                    yield(Mode.Uninitializing) thenRequire Response.Uninitialized
                    continue@uninitialized
                }
                else                 -> exception()
            }
        }
    }
    Response.Completed
}

Please note the examples above are chopped down and thus prototype code only.

Is it possible to support iOS 10 or lower?

I tried running the tests on iOS 10 simulator. Some problems came up.

  1. CoFutureAwaitTests.testConcurrency was stuck
    It seems the test scale is too large. It passed after reducing the scale.

  2. random EXC_BAD_ACCESS after CoroutineContextTests.testInitWithPageGuard
    Comment out the mprotect(stack, .pageSize, PROT_READ) in CoroutineContext.init, or add mprotect(stack, .pageSize, PROT_READ | PROT_WRITE) in CoroutineContext.deinit, the test passes. Maybe the granularity of protection changes is as large as an entire region, as the document said.
    https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mprotect.2.html

So I'm curious why the requirement is iOS 11.0+.

setjmp/longjmp are Undefined Behavior in Swift

I was ecstatic when I saw this repo. Unfortunately, I was informed that the basis of the coroutines defined in this project are unsafe:

setjmp and longjmp aren't safe to use in Swift (or ARC ObjC)—retain counts will leak, and weak refs may corrupt memory.
- Joe Groff

Further references:

https://twitter.com/search?q=from%3Ajckarter%20setjmp&src=typed_query

Unless this information is incorrect, there should probably at least be a warning in the README on this.

How to await all futures in a collection?

In Kotlin and C#, there are ways to await several coroutines in a collection at the same time, namely Collection<Deferred<T>>.awaitAll() and Task.WhenAll(IEnumerable<Task>) respectively. I now have a list of several CoFuture<Void> in an array (the amount of futures is dynamic) that I want to await at the same time instead of individually. Can I do this with current API?

Swift race access & stack buffer overflow

Used memory sanitizer in xcode, and got crash:

Crashed Thread: 13 Dispatch queue: com.apple.root.default-qos

abort() called
CoreSimulator 732.17 - Device: iPhone 8 (88037FF6-637E-4827-B62A-4BD2AD70CCE6) - Runtime: iOS 12.2 (16E226) - DeviceType: iPhone 8

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Application Specific Information:
==49420==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x700004312000; bottom 0x10013c25e000; size: 0x5ffec80b4000 (105547882512384)
False positive error reports may follow

SUMMARY: AddressSanitizer: stack-buffer-overflow (/Users/admin/Library/Developer/CoreSimulator/Devices/88037FF6-637E-4827-B62A-4BD2AD70CCE6/data/Containers/Bundle/Application/F8151562-99F5-44CC-8239-92715B85CBED/MyApp.app/Frameworks/libclang_rt.asan_iossim_dynamic.dylib:x86_64+0x17e70) in wrap_memcpy+0x3a0
Shadow bytes around the buggy address:
0x020155643f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643f60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643f80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x020155643f90:[01]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x020155643fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==49420==ABORTING

Thread 13 Crashed:: Dispatch queue: com.apple.root.default-qos
0 libsystem_kernel.dylib 0x000000011029b33a __pthread_kill + 10
1 libsystem_pthread.dylib 0x00000001102f8e60 pthread_kill + 430
2 libsystem_c.dylib 0x000000011005e0bc __abort + 144
3 libsystem_c.dylib 0x000000011005e02c abort + 142
4 libclang_rt.asan_iossim_dynamic.dylib 0x0000000104024d06 __sanitizer::Abort() + 70
5 libclang_rt.asan_iossim_dynamic.dylib 0x00000001040246f4 __sanitizer::Die() + 196
6 libclang_rt.asan_iossim_dynamic.dylib 0x000000010400c374 __asan::ScopedInErrorReport::~ScopedInErrorReport() + 420
7 libclang_rt.asan_iossim_dynamic.dylib 0x000000010400bc0e __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) + 1198
8 libclang_rt.asan_iossim_dynamic.dylib 0x0000000103fdbe90 wrap_memcpy + 960
9 org.cocoapods.SwiftCoroutine 0x000000010b657f45 SharedCoroutine.saveStack() + 2053 (SharedCoroutine.swift:78)
10 org.cocoapods.SwiftCoroutine 0x000000010b65fb97 SharedCoroutineQueue.start(dispatcher:scheduler:task:) + 1143 (SharedCoroutineQueue.swift:38)
11 org.cocoapods.SwiftCoroutine 0x000000010b65cba3 closure #1 in SharedCoroutineDispatcher.execute(on:task:) + 579 (SharedCoroutineDispatcher.swift:27)
12 org.cocoapods.SwiftCoroutine 0x000000010b623821 thunk for @escaping @callee_guaranteed () -> () + 145
13 libclang_rt.asan_iossim_dynamic.dylib 0x00000001040049cb __wrap_dispatch_async_block_invoke + 203
14 libdispatch.dylib 0x000000010ff02d7f _dispatch_call_block_and_release + 12
15 libdispatch.dylib 0x000000010ff03db5 _dispatch_client_callout + 8
16 libdispatch.dylib 0x000000010ff067b9 _dispatch_queue_override_invoke + 1022
17 libdispatch.dylib 0x000000010ff14632 _dispatch_root_queue_drain + 351
18 libdispatch.dylib 0x000000010ff14fca _dispatch_worker_thread2 + 130
19 libsystem_pthread.dylib 0x00000001102f59f7 _pthread_wqthread + 220
20 libsystem_pthread.dylib 0x00000001102f4b77 start_wqthread + 15

WARNING: ThreadSanitizer: Swift access race (pid=51212)
Modifying access of Swift variable at 0x7b1000453c18 by thread T19:
#0 $s14SwiftCoroutine8CoFutureC11addCallbackyyys6ResultOyxs5Error_pGcF (SwiftCoroutine:x86_64+0x2bf68)
#1 $s14SwiftCoroutine8CoFutureC12whenCanceledyyyycF (SwiftCoroutine:x86_64+0x33b15)
#2 $s14SwiftCoroutine0B9SchedulerPAAE15coroutineFutureyAA02CoE0Cyqd__Gqd__yKclFyycfU_ (SwiftCoroutine:x86_64+0x4108d)
#3 $s14SwiftCoroutine0B9SchedulerPAAE15coroutineFutureyAA02CoE0Cyqd__Gqd__yKclFyycfU_TA (SwiftCoroutine:x86_64+0x41445)
#4 $s14SwiftCoroutine0B7ContextC12performBlock33_474932A1564BFE56FB9333EE19D4C48CLLSvyF (SwiftCoroutine:x86_64+0x3d172)
#5 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_ (SwiftCoroutine:x86_64+0x3d010)
#6 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_To (SwiftCoroutine:x86_64+0x3d330)
#7 start (SwiftCoroutine:x86_64+0x3ffa)
#8 $s14SwiftCoroutine0B7ContextC5startSbyF (SwiftCoroutine:x86_64+0x3ce5e)
#9 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0
(SwiftCoroutine:x86_64+0x4b17d)
#10 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0_TA (SwiftCoroutine:x86_64+0x4ea9d)
#11 $s14SwiftCoroutine06SharedB0C7perform33_5CCAB8CB89EE233ADAF37DFE55B1ABD1LLyAA0cB5QueueC15CompletionStateOSbyXEF (SwiftCoroutine:x86_64+0x4b21f)
#12 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU
(SwiftCoroutine:x86_64+0x4b046)
#13 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_TA (SwiftCoroutine:x86_64+0x4b0ad)
#14 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TR (SwiftCoroutine:x86_64+0x4b4bb)
#15 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TRTA (SwiftCoroutine:x86_64+0x4b52d)
#16 $s14SwiftCoroutine0B8ProtocolPAAE16performAsCurrentyqd__qd__yXElF (SwiftCoroutine:x86_64+0x3eae7)
#17 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyF (SwiftCoroutine:x86_64+0x4af55)
#18 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x510e0)
#19 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_ (SwiftCoroutine:x86_64+0x4f33b)
#20 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_TA (SwiftCoroutine:x86_64+0x4f414)
#21 $sIeg_IeyB_TR (SwiftCoroutine:x86_64+0x2eec3)
#22 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#23 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)

Previous read of size 8 at 0x7b1000453c18 by thread T18:
#0 $s14SwiftCoroutine13CallbackStackV6appendySbyxcF (SwiftCoroutine:x86_64+0x1e035)
#1 $s14SwiftCoroutine8CoFutureC11addCallbackyyys6ResultOyxs5Error_pGcF (SwiftCoroutine:x86_64+0x2bfc4)
#2 $s14SwiftCoroutine8CoFutureC5awaitxyKFs6ResultOyxs5Error_pGyKXEfu_yyAHccACyxGcfu0_yyAHccfu1_ (SwiftCoroutine:x86_64+0x2d7a6)
#3 $s14SwiftCoroutine8CoFutureC5awaitxyKFs6ResultOyxs5Error_pGyKXEfu_yyAHccACyxGcfu0_yyAHccfu1_TA (SwiftCoroutine:x86_64+0x2f800)
#4 $ss6ResultOyxs5Error_pGlyxIsegn_Igg_xlyADIsegn_Iegg_lTR (SwiftCoroutine:x86_64+0x2d814)
#5 $ss6ResultOyxs5Error_pGlyxIsegn_Igg_xlyADIsegn_Iegg_lTRTA.1 (SwiftCoroutine:x86_64+0x2f7a6)
#6 $s14SwiftCoroutine06SharedB0C5awaityxyyxcXEKlF (SwiftCoroutine:x86_64+0x4d200)
#7 $s14SwiftCoroutine06SharedB0CAA0B8ProtocolA2aDP5awaityqd__yyqd__cXEKlFTW (SwiftCoroutine:x86_64+0x4e53a)
#8 $s14SwiftCoroutine8CoFutureC5awaitxyKFs6ResultOyxs5Error_pGyKXEfu_ (SwiftCoroutine:x86_64+0x2d4e5)
#9 $s14SwiftCoroutine8CoFutureC5awaitxyKFs6ResultOyxs5Error_pGyKXEfu_TA (SwiftCoroutine:x86_64+0x2d62f)
#10 $s14SwiftCoroutine8CoFutureC5awaitxyKF (SwiftCoroutine:x86_64+0x2d0f9)
#11 $s5MyApp19EntitiesServiceImplC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_y13ViperServices0lC10BootResultOctFyycfU_ (MyApp:x86_64+0x1004a07be)
#12 $s5MyApp19EntitiesServiceImplC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_y13ViperServices0lC10BootResultOctFyycfU_TA (MyApp:x86_64+0x1004a1449)
#13 $s14SwiftCoroutine0B9SchedulerPAAE05startB02in4taskyAA7CoScopeCSg_yyKctFyycfU_ (SwiftCoroutine:x86_64+0x3ffe6)
#14 $s14SwiftCoroutine0B9SchedulerPAAE05startB02in4taskyAA7CoScopeCSg_yyKctFyycfU_TA (SwiftCoroutine:x86_64+0x400f5)
#15 $s14SwiftCoroutine0B7ContextC12performBlock33_474932A1564BFE56FB9333EE19D4C48CLLSvyF (SwiftCoroutine:x86_64+0x3d172)
#16 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_ (SwiftCoroutine:x86_64+0x3d010)
#17 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_To (SwiftCoroutine:x86_64+0x3d330)
#18 start (SwiftCoroutine:x86_64+0x3ffa)
#19 $s14SwiftCoroutine0B7ContextC5startSbyF (SwiftCoroutine:x86_64+0x3ce5e)
#20 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0
(SwiftCoroutine:x86_64+0x4b17d)
#21 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0_TA (SwiftCoroutine:x86_64+0x4ea9d)
#22 $s14SwiftCoroutine06SharedB0C7perform33_5CCAB8CB89EE233ADAF37DFE55B1ABD1LLyAA0cB5QueueC15CompletionStateOSbyXEF (SwiftCoroutine:x86_64+0x4b21f)
#23 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU
(SwiftCoroutine:x86_64+0x4b046)
#24 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_TA (SwiftCoroutine:x86_64+0x4b0ad)
#25 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TR (SwiftCoroutine:x86_64+0x4b4bb)
#26 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TRTA (SwiftCoroutine:x86_64+0x4b52d)
#27 $s14SwiftCoroutine0B8ProtocolPAAE16performAsCurrentyqd__qd__yXElF (SwiftCoroutine:x86_64+0x3eae7)
#28 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyF (SwiftCoroutine:x86_64+0x4af55)
#29 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x510e0)
#30 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_ (SwiftCoroutine:x86_64+0x4f33b)
ThreadSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
A 0
#31 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_TA (SwiftCoroutine:x86_64+0x4f414)
#32 $sIeg_IeyB_TR (SwiftCoroutine:x86_64+0x2eec3)
#33 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#34 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)

Location is heap block of size 64 at 0x7b1000453c00 allocated by thread T18:
#0 malloc (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x4ef1a)
#1 swift_slowAlloc (libswiftCore.dylib:x86_64+0x2ce3c8)
#2 $s14SwiftCoroutine9CoPromiseCACyxGycfC (SwiftCoroutine:x86_64+0x3784f)
#3 $s14SwiftCoroutine0B9SchedulerPAAE15coroutineFutureyAA02CoE0Cyqd__Gqd__yKclF (SwiftCoroutine:x86_64+0x40bb6)
#4 $s5MyApp19EntitiesServiceImplC16loadStoryEffects33_CF1F1424D0659537F27DBA3EFCD861E7LL14SwiftCoroutine8CoFutureCyytGyF (MyApp:x86_64+0x1004d8677)
#5 $s5MyApp19EntitiesServiceImplC4boot13launchOpt[DefaultViperServicesContainer]: Still booting ["StateService", "ApphudService", "AnalyticsService", "ExtensionService", "GdprService", "PremiumService", "SmartNewsService", "PushNotificationsService"]ions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_y13ViperServices0lC10BootResultOctFyycfU_ (MyApp:x86_64+0x1004a0791)
#6 $s5MyApp19EntitiesServiceImplC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_y13ViperServices0lC10BootResultOctFyycfU_TA (MyApp:x86_64+0x1004a1449)
#7 $s14SwiftCoroutine0B9SchedulerPAAE05startB02in4taskyAA7CoScopeCSg_yyKctFyycfU_ (SwiftCoroutine:x86_64+0x3ffe6)
#8 $s14SwiftCoroutine0B9SchedulerPAAE05startB02in4taskyAA7CoScopeCSg_yyKctFyycfU_TA (SwiftCoroutine:x86_64+0x400f5)
#9 $s14SwiftCoroutine0B7ContextC12performBlock33_474932A1564BFE56FB9333EE19D4C48CLLSvyF (SwiftCoroutine:x86_64+0x3d172)
#10 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_ (SwiftCoroutine:x86_64+0x3d010)
#11 $s14SwiftCoroutin
e0B7ContextC5startSbyFySVSgcfU_To (SwiftCoroutine:x86_64+0x3d330)
#12 start (SwiftCoroutine:x86_64+0x3ffa)
#13 $s14SwiftCoroutine0B7ContextC5startSbyF (SwiftCoroutine:x86_64+0x3ce5e)
#14 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0
(SwiftCoroutine:x86_64+0x4b17d)
#15 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0_TA (SwiftCoroutine:x86_64+0x4ea9d)
#16 $s14SwiftCoroutine06SharedB0C7perform33_5CCAB8CB89EE233ADAF37DFE55B1ABD1LLyAA0cB5QueueC15CompletionStateOSbyXEF (SwiftCoroutine:x86_64+0x4b21f)
#17 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU
(SwiftCoroutine:x86_64+0x4b046)
#18 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_TA (SwiftCoroutine:x86_64+0x4b0ad)
#19 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TR (SwiftCoroutine:x86_64+0x4b4bb)
#20 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TRTA (SwiftCoroutine:x86_64+0x4b52d)
#21 $s14SwiftCoroutine0B8ProtocolPAAE16performAsCurrentyqd__qd__yXElF (SwiftCoroutine:x86_64+0x3eae7)
#22 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyF (SwiftCoroutine:x86_64+0x4af55)
#23 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x510e0)
#24 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_ (SwiftCoroutine:x86_64+0x4f33b)
#25 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_TA (SwiftCoroutine:x86_64+0x4f414)
#26 $sIeg_IeyB_TR (SwiftCoroutine:x86_64+0x2eec3)
#27 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#28 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)

Thread T19 (tid=5147481, running) is a GCD worker thread

Thread T18 (tid=5147475, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (/Users/admin/Library/Developer/CoreSimulator/Devices/88037FF6-637E-4827-B62A-4BD2AD70CCE6/data/Containers/Bundle/Application/89A141C1-2DC8-4A6C-B3DB-65CC1E2A08F7/MyApp.app/Frameworks/SwiftCoroutine.framework/SwiftCoroutine:x86_64+0x2bf68) in $s14SwiftCoroutine8CoFutureC11addCallbackyyys6ResultOyxs5Error_pGcF+0x1f8

ThreadSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.

WARNING: ThreadSanitizer: Swift access race (pid=51212)
Modifying access of Swift variable at 0x7b140011cb70 by thread T18:
#0 $s14SwiftCoroutine06SharedB10DispatcherC4pushyyAA0cB5QueueCF (SwiftCoroutine:x86_64+0x4f912)
#1 $s14SwiftCoroutine06SharedB5QueueC11performNext022_8C5C69B88B6EDEB22EAD6G9DF7AA0AADLL3foryAA0cB10DispatcherC_tF (SwiftCoroutine:x86_64+0x522d2)
#2 $s14SwiftCoroutine06SharedB5QueueC8complete022_8C5C69B88B6EDEB22EAD6F9DF7AA0AADLL4withyAC15CompletionStateO_tF (SwiftCoroutine:x86_64+0x5160c)
#3 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x51109)
#4 $s14SwiftCoroutine0B7ContextC12performBlock33_474932A1564BFE56FB9333EE19D4C48CLLSvyF (SwiftCoroutine:x86_64+0x3d172)
#5 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_ (SwiftCoroutine:x86_64+0x3d010)
#6 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_To (SwiftCoroutine:x86_64+0x3d330)
#7 start (SwiftCoroutine:x86_64+0x3ffa)
#8 $s14SwiftCoroutine0B7ContextC5startSbyF (SwiftCoroutine:x86_64+0x3ce5e)
#9 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0
(SwiftCoroutine:x86_64+0x4b17d)
#10 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0_TA (SwiftCoroutine:x86_64+0x4ea9d)
#11 $s14SwiftCoroutine06SharedB0C7perform33_5CCAB8CB89EE233ADAF37DFE55B1ABD1LLyAA0cB5QueueC15CompletionStateOSbyXEF (SwiftCoroutine:x86_64+0x4b21f)
#12 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU
(SwiftCoroutine:x86_64+0x4b046)
#13 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_TA (SwiftCoroutine:x86_64+0x4b0ad)
#14 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TR (SwiftCoroutine:x86_64+0x4b4bb)
#15 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TRTA (SwiftCoroutine:x86_64+0x4b52d)
#16 $s14SwiftCoroutine0B8ProtocolPAAE16performAsCurrentyqd__qd__yXElF (SwiftCoroutine:x86_64+0x3eae7)
#17 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyF (SwiftCoroutine:x86_64+0x4af55)
#18 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x510e0)
#19 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_ (SwiftCoroutine:x86_64+0x4f33b)
#20 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_TA (SwiftCoroutine:x86_64+0x4f414)
#21 $sIeg_IeyB_TR (SwiftCoroutine:x86_64+0x2eec3)
#22 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#23 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)

Previous modifying access of Swift variable at 0x7b140011cb70 by thread T19:
#0 $s14SwiftCoroutine9FifoQueueV3popxSgyF (SwiftCoroutine:x86_64+0x474bf)
#1 $s14SwiftCoroutine06SharedB10DispatcherC12getFreeQueue33_1A5FB05E2411224CDC4772F9B26581BDLLAA0cbG0CyF (SwiftCoroutine:x86_64+0x4f50d)
#2 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_ (SwiftCoroutine:x86_64+0x4f31c)
#3 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_TA (SwiftCoroutine:x86_64+0x4f414)
#4 $sIeg_IeyB_TR (SwiftCoroutine:x86_64+0x2eec3)
#5 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#6 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)

Location is heap block of size 72 at 0x7b140011cb50 allocated by main thread:
#0 malloc (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x4ef1a)
#1 swift_slowAlloc (libswiftCore.dylib:x86_64+0x2ce3c8)
#2 globalinit_33_1A5FB05E2411224CDC4772F9B26581BD_func0 (SwiftCoroutine:x86_64+0x4eb5b)
#3 dispatch_once (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x71794)
#4 dispatch_once_f (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x71880)
#5 swift_once (libswiftCore.dylib:x86_64+0x2f0578)
#6 $s14SwiftCoroutine0B9SchedulerPAAE06_startB0yyyycF (SwiftCoroutine:x86_64+0x3fb20)
#7 $s14SwiftCoroutine0B9SchedulerPAAE05startB02in4taskyAA7CoScopeCSg_yyKctF (SwiftCoroutine:x86_64+0x3ff2c)
#8 $s5MyApp19EntitiesServiceImplC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_y13ViperServices0lC10BootResultOctF (MyApp:x86_64+0x1004a04ca)
#9 $s5MyApp19EntitiesServiceImplC13ViperServices0eC0AadEP4boot13launchOptions10completionySDySo019UIApplicationLaunchI3KeyaypGSg_yAD0eC10BootResultOctFTW (MyApp:x86_64+0x1004e3e88)
#10 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU3_ (ViperServices:x86_64+0xff28)
#11 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU3_TA (ViperServices:x86_64+0x1c58c)
#12 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU4_ (ViperServices:x86_64+0x112f7)
#13 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU4_TA (ViperServices:x86_64+0x1c625)
#14 $sIeg_IeyB_TR (ViperServices:x86_64+0x11393)
#15 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#16 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)
#17 start (libdyld.dylib:x86_64+0x1540)

Thread T18 (tid=5147475, running) is a GCD worker thread

Thread T19 (tid=5147481, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (/Users/admin/Library/Developer/CoreSimulator/Devices/88037FF6-637E-4827-B62A-4BD2AD70CCE6/data/Containers/Bundle/Application/89A141C1-2DC8-4A6C-B3DB-65CC1E2A08F7/MyApp.app/Frameworks/SwiftCoroutine.framework/SwiftCoroutine:x86_64+0x4f912) in $s14SwiftCoroutine06SharedB10DispatcherC4pushyyAA0cB5QueueCF+0x222

ThreadSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.

WARNING: ThreadSanitizer: Swift access race (pid=51212)
Modifying access of Swift variable at 0x7b140011cb80 by thread T18:
#0 $s14SwiftCoroutine9FifoQueueV4pushyyxF (SwiftCoroutine:x86_64+0x45dff)
#1 $s14SwiftCoroutine06SharedB10DispatcherC4pushyyAA0cB5QueueCF (SwiftCoroutine:x86_64+0x4f934)
#2 $s14SwiftCoroutine06SharedB5QueueC11performNext022_8C5C69B88B6EDEB22EAD6G9DF7AA0AADLL3foryAA0cB10DispatcherC_tF (SwiftCoroutine:x86_64+0x522d2)
#3 $s14SwiftCoroutine06SharedB5QueueC8complete022_8C5C69B88B6EDEB22EAD6F9DF7AA0AADLL4withyAC15CompletionStateO_tF (SwiftCoroutine:x86_64+0x5160c)
#4 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x51109)
#5 $s14SwiftCoroutine0B7ContextC12performBlock33_474932A1564BFE56FB9333EE19D4C48CLLSvyF (SwiftCoroutine:x86_64+0x3d172)
#6 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_ (SwiftCoroutine:x86_64+0x3d010)
#7 $s14SwiftCoroutine0B7ContextC5startSbyFySVSgcfU_To (SwiftCoroutine:x86_64+0x3d330)
#8 start (SwiftCoroutine:x86_64+0x3ffa)
#9 $s14SwiftCoroutine0B7ContextC5startSbyF (SwiftCoroutine:x86_64+0x3ce5e)
#10 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0
(SwiftCoroutine:x86_64+0x4b17d)
#11 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_SbycAA0B7ContextCcfu_Sbycfu0_TA (SwiftCoroutine:x86_64+0x4ea9d)
#12 $s14SwiftCoroutine06SharedB0C7perform33_5CCAB8CB89EE233ADAF37DFE55B1ABD1LLyAA0cB5QueueC15CompletionStateOSbyXEF (SwiftCoroutine:x86_64+0x4b21f)
#13 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU
(SwiftCoroutine:x86_64+0x4b046)
#14 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyFAHyXEfU_TA (SwiftCoroutine:x86_64+0x4b0ad)
#15 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TR (SwiftCoroutine:x86_64+0x4b4bb)
#16 $s14SwiftCoroutine06SharedB5QueueC15CompletionStateOIgd_AEIegr_TRTA (SwiftCoroutine:x86_64+0x4b52d)
#17 $s14SwiftCoroutine0B8ProtocolPAAE16performAsCurrentyqd__qd__yXElF (SwiftCoroutine:x86_64+0x3eae7)
#18 $s14SwiftCoroutine06SharedB0C5startAA0cB5QueueC15CompletionStateOyF (SwiftCoroutine:x86_64+0x4af55)
#19 $s14SwiftCoroutine06SharedB5QueueC5start10dispatcher9scheduler4taskyAA0cB10DispatcherC_AA0B9Scheduler_pyyctF (SwiftCoroutine:x86_64+0x510e0)
#20 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_ (SwiftCoroutine:x86_64+0x4f33b)
#21 $s14SwiftCoroutine06SharedB10DispatcherC7execute2on4taskyAA0B9Scheduler_p_yyctFyycfU_TA (SwiftCoroutine:x86_64+0x4f414)
#22 $sIeg_IeyB_TR (SwiftCoroutine:x86_64+0x2eec3)
#23 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#24 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)

Previous write of size 1 at 0x7b140011cb80 by thread T19:
[failed to restore the stack]

Location is heap block of size 72 at 0x7b140011cb50 allocated by main thread:
#0 malloc (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x4ef1a)
#1 swift_slowAlloc (libswiftCore.dylib:x86_64+0x2ce3c8)
#2 globalinit_33_1A5FB05E2411224CDC4772F9B26581BD_func0 (SwiftCoroutine:x86_64+0x4eb5b)
#3 dispatch_once (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x71794)
#4 dispatch_once_f (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x71880)
#5 swift_once (libswiftCore.dylib:x86_64+0x2f0578)
#6 $s14SwiftCoroutine0B9SchedulerPAAE06_startB0yyyycF (SwiftCoroutine:x86_64+0x3fb20)
#7 $s14SwiftCoroutine0B9SchedulerPAAE05startB02in4taskyAA7CoScopeCSg_yyKctF (SwiftCoroutine:x86_64+0x3ff2c)
#8 $s5MyApp19EntitiesServiceImplC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_y13ViperServices0lC10BootResultOctF (MyApp:x86_64+0x1004a04ca)
#9 $s5MyApp19EntitiesServiceImplC13ViperServices0eC0AadEP4boot13launchOptions10completionySDySo019UIApplicationLaunchI3KeyaypGSg_yAD0eC10BootResultOctFTW (MyApp:x86_64+0x1004e3e88)
#10 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU3_ (ViperServices:x86_64+0xff28)
#11 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU3_TA (ViperServices:x86_64+0x1c58c)
#12 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU4_ (ViperServices:x86_64+0x112f7)
#13 $s13ViperServices07DefaultaB9ContainerC4boot13launchOptions10completionySDySo019UIApplicationLaunchG3KeyaypGSg_yAA0abD10BootResultOctFyyyccfU_0E4NextL_yyFyycfU4_TA (ViperServices:x86_64+0x1c625)
#14 $sIeg_IeyB_TR (ViperServices:x86_64+0x11393)
#15 __tsan::invoke_and_release_block(void*) (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
#16 _dispatch_client_callout (libdispatch.dylib:x86_64+0x3db4)
#17 start (libdyld.dylib:x86_64+0x1540)

Thread T18 (tid=5147475, running) is a GCD worker thread

Thread T19 (tid=5147481, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (/Users/admin/Library/Developer/CoreSimulator/Devices/88037FF6-637E-4827-B62A-4BD2AD70CCE6/data/Containers/Bundle/Application/89A141C1-2DC8-4A6C-B3DB-65CC1E2A08F7/MyApp.app/Frameworks/SwiftCoroutine.framework/SwiftCoroutine:x86_64+0x45dff) in $s14SwiftCoroutine9FifoQueueV4pushyyxF+0x38f

Race Conditions

What Happened

Hello,

I created a test program that calculates many points for x^2 on 4 threads. However after running in Xcode 13 with 'Thread Sanitizer' on, it keeps alerting me about a race condition on the first line of 'getFreeQueue()'. This is on an iPhone 12 Pro Simulator running iOS 15.

As this is likely just me not understanding how to use the library, any help would be greatly appreciated!

Demo Code

struct Point {
    var x: Double
    var y: Double
}

class TestingAsyncModel: ObservableObject {
    @Published var text: String = ""

    func getPoints(min: Double, max: Double, numThreads: Int, function: @escaping (Double) -> Double) -> CoFuture<[Point]> {
        
        func getPoints(min: Double, max: Double) -> CoFuture<[Point]> {
            return DispatchQueue.global().coroutineFuture {
                return stride(from: min, through: max, by: 0.01).map { x in
                    return Point(x: x, y: function(x))
                }
            }
        }
        
        let spread = (max - min)/Double(numThreads)
        
        let coroutines = stride(from: min, to: max, by: spread).map { start in
            return getPoints(min: start, max: start + spread)
        }
        
        return DispatchQueue.global().coroutineFuture {
            return try coroutines.flatMap {try $0.await()}
        }
    }
    
    init() {
        DispatchQueue.main.startCoroutine { [weak self] in
            self?.text = "start"
            
            let pointsFuture = self?.getPoints(min: -100, max: 100, numThreads: 4) { x in
                return x * x
            }
            
            guard let points = try pointsFuture?.await() else {
                return
            }
            
            self?.text = points.count.description
        }
    }
}

struct TestingAsyncView: View {
    @ObservedObject var model: TestingAsyncModel
    
    var body: some View {
        Text(model.text)
    }
}

Crash using recursion inside a coroutine

Hi, I am experiencing crashes in our code when using intense recursion (lots of recursive calls) inside a coroutine block. I have been able to reproduce it in a test inside the project. This is the code:

    func testRecursive() {
        let exp = expectation(description: "testRecursive")
        exp.expectedFulfillmentCount = 1
        DispatchQueue.global().startCoroutine {
            try self.recursiveFunction(count: 0)
            exp.fulfill()
        }
        wait(for: [exp], timeout: 3)
    }
    
    private func recursiveFunction(count: Int) throws {
        let _ = try Coroutine.await { callback in
            DispatchQueue.global().async {
                callback("random_response")
            }
        }
        print(count)
        if count < 10000 {
            try recursiveFunction(count: count + 1)
        }
    }

The number of iterations that made the code crash depends on the size of the returned result in the callback function; a more complex object will make the code crash before.

I've tried using Coroutine.await as in this sample code, but also using CoFuture but it'll always crash eventually. Is it a memory issue? Am I doing something conceptually wrong here?

Thank you!

Issues with receiving with CoChannel (and possibly CoScope)

I noticed some weird behavior in my projects concerning CoChannels, and I wasn't sure if I was using it wrong or there was something buggy going on.

I have a scoped coroutine running and

  1. The coroutine crashes when self is captured with unowned.
  2. The receiving end slows down as new coroutines are launched using the same channel.

Not sure if I'm explaining the situation correctly, so I have a demo target here.

I also noticed that all the CoScopes are kepts around when the memory graph debugger is run like so:
Screen Shot 2021-01-31 at 3 49 41 PM

The objects that own the CoScope instances are deallocated as expected.

The slowing down (or rather the skipping values) corresponds to the number of zombie CoScope instances.
So when there are four CoScope instances lying around, the log prints like so

9122080394873498997
showInt(_:) 9122080394873498997
4655395568503796474
432049987236061310
1887288328159798314
1946205301628222178
showInt(_:) 1946205301628222178

(I also noticed other weird behavior with my real project like objects captured by the SwiftCoroutine and not deallocating, but I'm not sure if it's in any way related to the issue demonstrated by the sample project. I can provide further information if you're interested.)

Sorry about the haphazard reporting, but it was hard to determine if they all pointed to the same cause or if they were all separate, so I decided to just lay it out.

Pure Swift Possible?

This library looks great. I have been trying to integrate it in an XCFramework I have. There is an issue, I am having, because it defines a C module, it turns on "Defines Module" if you turn on "Defines Module" and BUILD_LIBRARIES_FOR_DISTRIBUTION then the SwiftInterface files are not generated for that module. Not sure if this is correct behavior but it is the behavior, none the less.

See this project for an example of the issue (turning off Defines Module lets it generate the swiftinterface files). https://github.com/possen/HostApp. Turning it off, means it won't import in Application because the swiftintface files are missing.

The question becomes is there a way to either not enable "defines module" for the whole project, just that one C module, or do a pure Swift implementation?

ReactiveKit Bindings/Extensions for Migration

Do you have any plans to include or create ReactiveKit type Bindings/Extensions for those of us who want to migrate a ReactiveKit style project to Coroutines?

So something like: mySignal.await() to be able to call within a coroutine function.

A certain nested coroutines causes LLDB RPC Server crash on a breakpoint

For the following code, if I put a breakpoint on line where let a is in Xcode, LLDB debug server will crash.

If I start the initial coroutine on main queue instead of global, or if I remove the middle CoFuture, no crashes would happen when the breakpoint hits.

import UIKit
import SwiftCoroutine

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        DispatchQueue.global().startCoroutine {
            try CoFuture<Void> {
                try DispatchQueue.main.await {
                    let a = 1 /* SET BREAKPOINT ON THIS LINE*/
                }
            }.await()
        }
    }

}
Message from debugger: The LLDB RPC server has crashed. The crash log is located in ~/Library/Logs/DiagnosticReports and has a prefix 'lldb-rpc-server'. Please file a bug and attach the most recent crash log.

Unfortunately, when this crash happens, no actual diagnostic files are actually generated.

Not able to build SwiftCoroutine for previews in xcode

Getting this error when building/resuming my project for previews with SwiftCoroutine whereas normal build is successful.

in file CoPromise.swift, line: 19
extension CoPromise {
@inlinable public convenience init() {
self.init(_result: nil) --> Initializer 'init(_result:)' is internal and cannot be referenced from an '@inlinable' function
}

Xcode 13 error compilation

Hi,

The word await make a compilation error because apple have deployed his concurrency async await.

Can you fix this issues simple refactored methods name func await() to
func `await`()
Capture d’écran 2021-09-23 à 17 45 13

Buffer Overflow?

I have been experiencing random crashes some of which seem to involve random memory corruption. I have since found a probable cause, but did run across this while I was searching for issues.

I ran address sanitizer on my code and it spit out the following. There is a warning of potential false positives...

==47182==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x70000f1bb000; bottom 0x00010a1da000; size: 0x6fff04fe1000 (123141091102720)
False positive error reports may follow
For details see google/sanitizers#189

==47182==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x00010a1db9e1 at pc 0x000100136a7a bp 0x70000f1b9bb0 sp 0x70000f1b9370
READ of size 5664 at 0x00010a1db9e1 thread T2
#0 0x100136a79 in wrap_memmove+0x169 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1da79)
#1 0x109ce5d60 in SharedCoroutine.saveStack()+0x830 (goSwiftlyTests:x86_64+0xdad60)
#2 0x109cedc9d in SharedCoroutineQueue.start(dispatcher:scheduler:task:)+0x47d (goSwiftlyTests:x86_64+0xe2c9d)
#3 0x109ceac4a in closure #1 in SharedCoroutineDispatcher.execute(on:task:)+0x22a (goSwiftlyTests:x86_64+0xdfc4a)
#4 0x109cbd932 in thunk for @escaping @callee_guaranteed () -> ()+0x92 (goSwiftlyTests:x86_64+0xb2932)
#5 0x1001613ba in __wrap_dispatch_async_block_invoke+0xca (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x483ba)
#6 0x7fff72cb56c3 in _dispatch_call_block_and_release+0xb (libdispatch.dylib:x86_64+0x16c3)
#7 0x7fff72cb6657 in _dispatch_client_callout+0x7 (libdispatch.dylib:x86_64+0x2657)
#8 0x7fff72cbbc43 in _dispatch_lane_serial_drain+0x254 (libdispatch.dylib:x86_64+0x7c43)
#9 0x7fff72cbc5d5 in _dispatch_lane_invoke+0x16a (libdispatch.dylib:x86_64+0x85d5)
#10 0x7fff72cc5c08 in _dispatch_workloop_worker_thread+0x253 (libdispatch.dylib:x86_64+0x11c08)
#11 0x7fff72f10a3c in _pthread_wqthread+0x121 (libsystem_pthread.dylib:x86_64+0x2a3c)
#12 0x7fff72f0fb76 in start_wqthread+0xe (libsystem_pthread.dylib:x86_64+0x1b76)

0x00010a1db9e1 is located 190945 bytes inside of 200704-byte region [0x00010a1ad000,0x00010a1de000)
allocated by thread T2 here:
#0 0x100162870 in wrap_posix_memalign+0xb0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x49870)
#1 0x7fff7262bcd1 in swift_slowAlloc+0x41 (libswiftCore.dylib:x86_64+0x2f2cd1)
#2 0x109cd817b in CoroutineContext.init(stackSize:guardPage:)+0x4fb (goSwiftlyTests:x86_64+0xcd17b)
#3 0x109cd7c68 in CoroutineContext.__allocating_init(stackSize:guardPage:)+0x38 (goSwiftlyTests:x86_64+0xccc68)
#4 0x109ced426 in SharedCoroutineQueue.init(stackSize:)+0x5b6 (goSwiftlyTests:x86_64+0xe2426)
#5 0x109cece58 in SharedCoroutineQueue.__allocating_init(stackSize:)+0x28 (goSwiftlyTests:x86_64+0xe1e58)
#6 0x109ceb158 in SharedCoroutineDispatcher.getFreeQueue()+0x438 (goSwiftlyTests:x86_64+0xe0158)
#7 0x109ceac2f in closure #1 in SharedCoroutineDispatcher.execute(on:task:)+0x20f (goSwiftlyTests:x86_64+0xdfc2f)
#8 0x109cbd932 in thunk for @escaping @callee_guaranteed () -> ()+0x92 (goSwiftlyTests:x86_64+0xb2932)
#9 0x1001613ba in __wrap_dispatch_async_block_invoke+0xca (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x483ba)
#10 0x7fff72cb56c3 in _dispatch_call_block_and_release+0xb (libdispatch.dylib:x86_64+0x16c3)
#11 0x7fff72cb6657 in _dispatch_client_callout+0x7 (libdispatch.dylib:x86_64+0x2657)
#12 0x7fff72cbbc43 in _dispatch_lane_serial_drain+0x254 (libdispatch.dylib:x86_64+0x7c43)
#13 0x7fff72cbc5d5 in _dispatch_lane_invoke+0x16a (libdispatch.dylib:x86_64+0x85d5)
#14 0x7fff72cc5c08 in _dispatch_workloop_worker_thread+0x253 (libdispatch.dylib:x86_64+0x11c08)
#15 0x7fff72f10a3c in _pthread_wqthread+0x121 (libsystem_pthread.dylib:x86_64+0x2a3c)
#16 0x7fff72f0fb76 in start_wqthread+0xe (libsystem_pthread.dylib:x86_64+0x1b76)

Thread T2 created by T1 here:

Thread T1 created by T0 here:

SUMMARY: AddressSanitizer: stack-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1da79) in wrap_memmove+0x169
Shadow bytes around the buggy address:
0x10002143b6e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10002143b730: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[01]f3 f3 f3
0x10002143b740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10002143b780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
2020-11-06 15:47:39.270045-0700 xctest[47182:2741407] ==47182==WARNING: ASan is ignoring requested __asan_handle_no_return: stack top: 0x70000f1bb000; bottom 0x00010a1da000; size: 0x6fff04fe1000 (123141091102720)
2020-11-06 15:47:39.270161-0700 xctest[47182:2741407] False positive error reports may follow
2020-11-06 15:47:39.270244-0700 xctest[47182:2741407] For details see google/sanitizers#189
2020-11-06 15:47:39.270366-0700 xctest[47182:2741407] =================================================================
2020-11-06 15:47:39.270476-0700 xctest[47182:2741407] ==47182==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x00010a1db9e1 at pc 0x000100136a7a bp 0x70000f1b9bb0 sp 0x70000f1b9370
2020-11-06 15:47:39.270527-0700 xctest[47182:2741407] READ of size 5664 at 0x00010a1db9e1 thread T2
2020-11-06 15:47:39.270648-0700 xctest[47182:2741407] #0 0x100136a79 in wrap_memmove+0x169 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1da79)
2020-11-06 15:47:39.270708-0700 xctest[47182:2741407] #1 0x109ce5d60 in SharedCoroutine.saveStack()+0x830 (goSwiftlyTests:x86_64+0xdad60)
2020-11-06 15:47:39.270798-0700 xctest[47182:2741407] #2 0x109cedc9d in SharedCoroutineQueue.start(dispatcher:scheduler:task:)+0x47d (goSwiftlyTests:x86_64+0xe2c9d)
2020-11-06 15:47:39.270892-0700 xctest[47182:2741407] #3 0x109ceac4a in closure #1 in SharedCoroutineDispatcher.execute(on:task:)+0x22a (goSwiftlyTests:x86_64+0xdfc4a)
2020-11-06 15:47:39.270955-0700 xctest[47182:2741407] #4 0x109cbd932 in thunk for @escaping @callee_guaranteed () -> ()+0x92 (goSwiftlyTests:x86_64+0xb2932)
2020-11-06 15:47:39.271008-0700 xctest[47182:2741407] #5 0x1001613ba in __wrap_dispatch_async_block_invoke+0xca (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x483ba)
2020-11-06 15:47:39.271119-0700 xctest[47182:2741407] #6 0x7fff72cb56c3 in _dispatch_call_block_and_release+0xb (libdispatch.dylib:x86_64+0x16c3)
2020-11-06 15:47:39.271189-0700 xctest[47182:2741407] #7 0x7fff72cb6657 in _dispatch_client_callout+0x7 (libdispatch.dylib:x86_64+0x2657)
2020-11-06 15:47:39.271266-0700 xctest[47182:2741407] #8 0x7fff72cbbc43 in _dispatch_lane_serial_drain+0x254 (libdispatch.dylib:x86_64+0x7c43)
2020-11-06 15:47:39.271346-0700 xctest[47182:2741407] #9 0x7fff72cbc5d5 in _dispatch_lane_invoke+0x16a (libdispatch.dylib:x86_64+0x85d5)
2020-11-06 15:47:39.271396-0700 xctest[47182:2741407] #10 0x7fff72cc5c08 in _dispatch_workloop_worker_thread+0x253 (libdispatch.dylib:x86_64+0x11c08)
2020-11-06 15:47:39.271445-0700 xctest[47182:2741407] #11 0x7fff72f10a3c in _pthread_wqthread+0x121 (libsystem_pthread.dylib:x86_64+0x2a3c)
2020-11-06 15:47:39.271534-0700 xctest[47182:2741407] #12 0x7fff72f0fb76 in start_wqthread+0xe (libsystem_pthread.dylib:x86_64+0x1b76)
2020-11-06 15:47:39.271578-0700 xctest[47182:2741407]
2020-11-06 15:47:39.271621-0700 xctest[47182:2741407] 0x00010a1db9e1 is located 190945 bytes inside of 200704-byte region [0x00010a1ad000,0x00010a1de000)
2020-11-06 15:47:39.271667-0700 xctest[47182:2741407] allocated by thread T2 here:
2020-11-06 15:47:39.271708-0700 xctest[47182:2741407] #0 0x100162870 in wrap_posix_memalign+0xb0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x49870)
2020-11-06 15:47:39.271749-0700 xctest[47182:2741407] #1 0x7fff7262bcd1 in swift_slowAlloc+0x41 (libswiftCore.dylib:x86_64+0x2f2cd1)
2020-11-06 15:47:39.271861-0700 xctest[47182:2741407] #2 0x109cd817b in CoroutineContext.init(stackSize:guardPage:)+0x4fb (goSwiftlyTests:x86_64+0xcd17b)
2020-11-06 15:47:39.271926-0700 xctest[47182:2741407] #3 0x109cd7c68 in CoroutineContext.__allocating_init(stackSize:guardPage:)+0x38 (goSwiftlyTests:x86_64+0xccc68)
2020-11-06 15:47:39.272024-0700 xctest[47182:2741407] #4 0x109ced426 in SharedCoroutineQueue.init(stackSize:)+0x5b6 (goSwiftlyTests:x86_64+0xe2426)
2020-11-06 15:47:39.272134-0700 xctest[47182:2741407] #5 0x109cece58 in SharedCoroutineQueue.__allocating_init(stackSize:)+0x28 (goSwiftlyTests:x86_64+0xe1e58)
2020-11-06 15:47:39.272253-0700 xctest[47182:2741407] #6 0x109ceb158 in SharedCoroutineDispatcher.getFreeQueue()+0x438 (goSwiftlyTests:x86_64+0xe0158)
2020-11-06 15:47:39.272323-0700 xctest[47182:2741407] #7 0x109ceac2f in closure #1 in SharedCoroutineDispatcher.execute(on:task:)+0x20f (goSwiftlyTests:x86_64+0xdfc2f)
2020-11-06 15:47:39.272388-0700 xctest[47182:2741407] #8 0x109cbd932 in thunk for @escaping @callee_guaranteed () -> ()+0x92 (goSwiftlyTests:x86_64+0xb2932)
2020-11-06 15:47:39.272434-0700 xctest[47182:2741407] #9 0x1001613ba in __wrap_dispatch_async_block_invoke+0xca (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x483ba)
2020-11-06 15:47:39.272518-0700 xctest[47182:2741407] #10 0x7fff72cb56c3 in _dispatch_call_block_and_release+0xb (libdispatch.dylib:x86_64+0x16c3)
2020-11-06 15:47:39.272628-0700 xctest[47182:2741407] #11 0x7fff72cb6657 in _dispatch_client_callout+0x7 (libdispatch.dylib:x86_64+0x2657)
2020-11-06 15:47:39.272735-0700 xctest[47182:2741407] #12 0x7fff72cbbc43 in _dispatch_lane_serial_drain+0x254 (libdispatch.dylib:x86_64+0x7c43)
2020-11-06 15:47:39.272836-0700 xctest[47182:2741407] #13 0x7fff72cbc5d5 in _dispatch_lane_invoke+0x16a (libdispatch.dylib:x86_64+0x85d5)
2020-11-06 15:47:39.272911-0700 xctest[47182:2741407] #14 0x7fff72cc5c08 in _dispatch_workloop_worker_thread+0x253 (libdispatch.dylib:x86_64+0x11c08)
2020-11-06 15:47:39.273034-0700 xctest[47182:2741407] #15 0x7fff72f10a3c in _pthread_wqthread+0x121 (libsystem_pthread.dylib:x86_64+0x2a3c)
2020-11-06 15:47:39.273105-0700 xctest[47182:2741407] #16 0x7fff72f0fb76 in start_wqthread+0xe (libsystem_pthread.dylib:x86_64+0x1b76)
2020-11-06 15:47:39.273255-0700 xctest[47182:2741407]
2020-11-06 15:47:39.273320-0700 xctest[47182:2741407] Thread T2 created by T1 here:
2020-11-06 15:47:39.273371-0700 xctest[47182:2741407]
2020-11-06 15:47:39.273523-0700 xctest[47182:2741407]
2020-11-06 15:47:39.273596-0700 xctest[47182:2741407] Thread T1 created by T0 here:
2020-11-06 15:47:39.273647-0700 xctest[47182:2741407]
2020-11-06 15:47:39.273745-0700 xctest[47182:2741407]
2020-11-06 15:47:39.273816-0700 xctest[47182:2741407] SUMMARY: AddressSanitizer: stack-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1da79) in wrap_memmove+0x169
2020-11-06 15:47:39.273872-0700 xctest[47182:2741407] Shadow bytes around the buggy address:
2020-11-06 15:47:39.273990-0700 xctest[47182:2741407] 0x10002143b6e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274067-0700 xctest[47182:2741407] 0x10002143b6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274157-0700 xctest[47182:2741407] 0x10002143b700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274265-0700 xctest[47182:2741407] 0x10002143b710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274326-0700 xctest[47182:2741407] 0x10002143b720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274419-0700 xctest[47182:2741407] =>0x10002143b730: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[01]f3 f3 f3
2020-11-06 15:47:39.274529-0700 xctest[47182:2741407] 0x10002143b740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274609-0700 xctest[47182:2741407] 0x10002143b750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274754-0700 xctest[47182:2741407] 0x10002143b760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274823-0700 xctest[47182:2741407] 0x10002143b770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274904-0700 xctest[47182:2741407] 0x10002143b780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2020-11-06 15:47:39.274969-0700 xctest[47182:2741407] Shadow byte legend (one shadow byte represents 8 application bytes):
2020-11-06 15:47:39.275105-0700 xctest[47182:2741407] Addressable: 00
2020-11-06 15:47:39.275183-0700 xctest[47182:2741407] Partially addressable: 01 02 03 04 05 06 07
2020-11-06 15:47:39.275238-0700 xctest[47182:2741407] Heap left redzone: fa
2020-11-06 15:47:39.275349-0700 xctest[47182:2741407] Freed heap region: fd
2020-11-06 15:47:39.275440-0700 xctest[47182:2741407] Stack left redzone: f1
2020-11-06 15:47:39.275499-0700 xctest[47182:2741407] Stack mid redzone: f2
2020-11-06 15:47:39.275594-0700 xctest[47182:2741407] Stack right redzone: f3
2020-11-06 15:47:39.275647-0700 xctest[47182:2741407] Stack after return: f5
2020-11-06 15:47:39.275709-0700 xctest[47182:2741407] Stack use after scope: f8
2020-11-06 15:47:39.275749-0700 xctest[47182:2741407] Global redzone: f9
2020-11-06 15:47:39.275838-0700 xctest[47182:2741407] Global init order: f6
2020-11-06 15:47:39.275905-0700 xctest[47182:2741407] Poisoned by user: f7
2020-11-06 15:47:39.275996-0700 xctest[47182:2741407] Container overflow: fc
2020-11-06 15:47:39.276094-0700 xctest[47182:2741407] Array cookie: ac
2020-11-06 15:47:39.276177-0700 xctest[47182:2741407] Intra object redzone: bb
2020-11-06 15:47:39.276229-0700 xctest[47182:2741407] ASan internal: fe
2020-11-06 15:47:39.276335-0700 xctest[47182:2741407] Left alloca redzone: ca
2020-11-06 15:47:39.276429-0700 xctest[47182:2741407] Right alloca redzone: cb
2020-11-06 15:47:39.276583-0700 xctest[47182:2741407] Shadow gap: cc
==47182==ABORTING
Warning: hit breakpoint while running function, skipping commands and conditions to prevent recursion.
AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
(lldb) thread info -s
thread #3: tid = 0x29d49f, 0x000000010016ab20 libclang_rt.asan_osx_dynamic.dylib`__asan::AsanDie(), queue = 'GoSwiftly[1]', stop reason = Stack buffer overflow

{
"access_size": 5664,
"access_type": 0,
"address": 4464687585,
"description": "stack-buffer-overflow",
"instrumentation_class": "AddressSanitizer",
"pc": 4296239738,
"stop_type": "fatal_error"
}
(lldb)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.