@chrisbia posted a new topic, subject "EXC_BAD_ACCESS triggered without any output to console using Xcode 13.2.1 on macOS 11.6.5". It read:

   ##  Update
    
    This is the last entry in the stack trace and presumably where the `EXC_BAD_ACCESS` error is triggered:
    
    > 0 swift8b7c:f320:99b9:690f:4595:cd17:293a:c069ResolveAsSymbolicReferen8b7c:f320:99b9:690f:4595:cd17:293a:c069operator()(swift8b7c:f320:99b9:690f:4595:cd17:293a:c069mangl8b7c:f320:99b9:690f:4595:cd17:293a:c069__runtim8b7c:f320:99b9:690f:4595:cd17:293a:c069SymbolicReferenceKind, swift8b7c:f320:99b9:690f:4595:cd17:293a:c069mangl8b7c:f320:99b9:690f:4595:cd17:293a:c069__runtim8b7c:f320:99b9:690f:4595:cd17:293a:c069Directness, int, void const*)
    
    ##  Original
    
    I'm creating an AWS Swift Lambda. There are `async` methods which I'm using and decided to run in a `Task` instead of implementing `AsyncLambdaHandler` — `AsyncLambdaHandler` has a method requirement with a default implementation, but only on for macOS 12+, and I wasn't immediately sure how I'd implement it myself. So I ran the `async` methods in the `Task` and the program immediately crashed ("EXC_BAD_ACCESS"). It didn't even get to the line which instantiates the `Task`; it just crashes right on the line before it. But I presume the `Task` is the problem because when I comment out instantiation of the task and the usage of the `async` code, no crash occurs.
    
    I've created a minimal reproducible example of the error here. There is a sample payload in the README.md, that should work using a POST request, but it will not when using the `Task`. Task creation — and only `Task` creation — is in the method `API.handle(context:event:callback:)` in API.swift.

Then @0xTim (Tim) said

    Nothing is holding on to the `Task` as you're mixing async code and callbacks, so I suspect the function is going out of scope, cleaning itself up then the task gets executed and tries to call a callback in a scope that no longer exists, hence the bad access error

To which @chrisbia replied

    But that's always the case with AWS Swift Lambda's — they are executed asynchronously. That's why they're given the closure because it's not expected that by time that `LambdaHandler.handle(context:event:callback:)` returns that the request will have been completed. So if it is expected that the callback may be executed in a scope that no longer exists anyway, then why would it matter if it is done from within a closure given to a `Task` or a closure given to some method that invokes it on completion of some other asynchronous task like a HTTP request.
    
    Also, in all the examples I saw of `Task` being used I've never seen it held onto. I also placed a breakpoint in the task and it's never reached; although I do know that that's not always a sign that the code at the breakpoint is not executed, it is more often than not though.

@0xTim (Tim) replied

    Which examples have you seen that create a `Task`? The issue is that you're mixing async styles. All the examples of using the completion handler show it being called synchronously, e.g. whatever work that you're doing will be blocking. If you don't want to block and you can't use async/await you'll need to use `EventLoopFuture`s where you return a promise instead of invoking the completion handler

To which @chrisbia replied

    No examples of creating a `Task` in the context of AWS Swift Lambda — just general Swift use cases of using `Task` and `async`/`await`. That's part of the problem, there's barely any examples of AWS Swift jacksonvincent@example.net.
    
    Furthermore, the documentation for `Lambda.InitializationContext.eventLoop` explicitly states
    
    > Most importantly the `EventLoop` must never be blocked.
    
    Which makes it seem as if blocking, synchronous code should not be ran on invocations of the Lambda lest its `EventLoop` be blocked.
    
    Thanks for the clarity though, it does make sense at the moment that you'd use `EventLoopFutures` when you're responding to the Lambda request asynchronously rather than invoking a given callback at some later point in the future, maybe.
    
    I would have just used `AsyncLambdaHandler`, but all the code regarding it is marked `@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)`, and I'm on macOS 11.6.5; so it makes it seem like it is unsafe to use in spite of my OS supporting Swift 5.5.

After which, @0xTim (Tim) added

    You could always build it in a Linux container using VSCode Remote Dev etc. It's not available on macOS 11 as the concurrency runtime isn't fully implemented on there

To which @chrisbia replied

    0xTim:
    
    > Nothing is holding on to the `Task` as you're mixing async code and callbacks
    
    I tried going the pure `AsyncLambdaHandler` approach, but I'm still getting an `EXC_BAD_ACCESS` error. I created a minimal reproducible example of the error. Unlike with the first example, this one doesn't event get to the waiting phase of the lambda — it crashes (same error — even looks like the same culprit as before in the stack trace) as soon as the Lambda starts to spin up.
    
    From what I've read it appears that Swift _Concurrency was backported to macOS 10.15 — I'm running macOS 11.6.5 — and yet it seems like the problem I'm facing is caused by using _Concurrency API's.

To which @0xTim (Tim) replied

    _Some_ of the concurrency runtime was backported but not everything so I'm not sure what's going on. It could be a compiler bug in the way the back porting is working or it's just not supported

To which @chrisbia replied

    I'm just trying to figure out whether this is something that I'm doing wrong or something wrong with Swift/Xcode. If it's something I'm doing wrong, then I will put in the effort to fix it for the benefits of being able to use the concurrency API's. If it's not something I'm doing wrong, then I need to stop trying to incorporate Swift Concurrency into my Lambda now and start trying to find ways to work around the dependencies that have already incorporated it into their API's.
    
    0xTim:
    
    > _Some_ of the concurrency runtime was backported but not everything
    
    If everything wasn't backported, then why would Xcode include this in their release notes for version 13.2:
    
    >   * You can now use Swift Concurrency in applications that deploy to macOS Catalina 10.15, iOS 13, tvOS 13, and watchOS 6 or newer. This support includes `async` / `await` , actors, global actors, structured concurrency, and the task APIs. (70738378)
    > 
    
    
    Are applications that deploy to macOS 10.15 Catalina, but are not necessarily Mac apps (the Lambda I'm trying to run from Xcode) not included under that umbrella?

So @0xTim (Tim) replied

    chrisbia:
    
    > Are applications that deploy to macOS 10.15 Catalina, but are not necessarily Mac apps (the Lambda I'm trying to run from Xcode) not included under that umbrella?
    
    I'm not 100% sure on the specific requirements for concurrency stuff and the back deployment stuff but we've deliberately not enabled it in Vapor as it requires a lot of code duplication and there's no guarantee that it will be work reliably. I still think you're best bet is remote dev with VSCode if you can't upgrade to macOS 12 and want to use async stuff


{'source': 'discourse', 'url': 'https://forums.swift.org/t/exc-bad-access-triggered-without-any-output-to-console-using-xcode-13-2-1-on-macos-11-6-5/56362', 'title': 'EXC_BAD_ACCESS triggered without any output to console using Xcode 13.2.1 on macOS 11.6.5', 'views': 460, 'has_accepted_answer': False, 'word_count': 1175, 'like_count': 0, 'reply_count': 8, 'participant_count': 2, 'posts': 10, 'tags': '', 'author': '@chrisbia', 'participants': '@chrisbia, @0xTim (Tim)', 'image_url': [None], 'created_at': '2022-03-31T02:26:34.721Z', 'last_posted_at': '2022-04-06T12:46:09.577Z'}