Skip to content

stack overflow on repeated async function invocation #722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
stefanspringer1 opened this issue Aug 23, 2022 · 7 comments
Closed

stack overflow on repeated async function invocation #722

stefanspringer1 opened this issue Aug 23, 2022 · 7 comments

Comments

@stefanspringer1
Copy link

stefanspringer1 commented Aug 23, 2022

I am trying to use swift-win32 to log into a window. Using the UICatalog example I added the following logger (so access to the TextView instance is regulated):

public actor GUILogger {

    private let textView: TextView

    public init(textView: TextView) {
        self.textView = textView
    }

    public func log(_ message: String) async {
        textView.text = (textView.text ?? "") + "\n" + message
    }

}

When I add the following after the call window.makeKeyAndVisible() the messages are written into the text view and the window stays open, so it is working fine:

    Task {
          let logger = GUILogger(textView: textview)

          await logger.log("test message 1")
          await logger.log("test message 2")
          await logger.log("test message 3")
    }

But when I use the following code, the window closes when logging:

    Task {
          let logger = GUILogger(textView: textview)

          await [
              "test message 1",
              "test message 2",
              "test message 3",
          ]
              .forEachAsync { message in
                  await logger.log(message)
              }

    }

The definition of forEachAsync is:

public extension Sequence {

    func forEachAsync(
            _ operation: (Element) async -> Void
    ) async {
        for element in self {
            await operation(element)
        }
    }

}

What could be the cause?

@stefanspringer1 stefanspringer1 changed the title Window closes when writing into a text view asynchonously Window closes when writing into a text view asynchronously Aug 23, 2022
@compnerd
Copy link
Owner

compnerd commented Aug 23, 2022

Hmm, what architecture are you building on? If it is x86_64, I think that this is due to the use of concurrency. There is a bug in LLVM that needs to be resolved still which sometimes results in stack exhaustion depending on how things are scheduled. This shouldn't be a problem on ARM64 and may be a good way to test. Another way to test might be to replace the use of the concurrency with dispatch perhaps.

@stefanspringer1
Copy link
Author

The architecture is x86_64.

If this is indeed an LLVM bug, I consider it not bad news, so it could be resolved (?) and then the code could/should work like this...

The form the the logger is mandatory in my real setting (the logger actually conforming to an according protocol), so changing the code here is probably no option.

@compnerd
Copy link
Owner

If this is indeed an LLVM bug, I consider it not bad news, so it could be resolved (?) and then the code could/should work like this...

I'd say it is closer to must be resolved ... we really do need to fix this. Unfortunately, the bug is a bit complicated and requires some dedicated time to work on, and there are a number of other things in the queue :-(.

The form the the logger is mandatory in my real setting (the logger actually conforming to an according protocol), so changing the code here is probably no option.

Understood. I think that one other option might be to do something particularly heinous like having the async method just push it on a dispatch queue and return rather than await. That might give us sufficient breathing room.

The issue is actually the continuous awaits on the single actor, which results in the stack never being cleaned up as it expects to be able to do the tail call optimization which will release the associated stack space. That is currently unsupported on Windows x86_64 and causes trouble. Should we try to enable the use of the mandatory tail call handling, we will abort here: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/X86/X86FrameLowering.cpp#L1514

The issue tracking this is swiftlang/swift#57976.

@compnerd
Copy link
Owner

Oh another two ways to verify that the assumptions here are correct: once the process terminates, run echo %ERRORLEVEL% from the cmd that you launch the process from OR just run it under a debugger and verify that it is an abnormal exit (specifically a stack overflow).

@stefanspringer1
Copy link
Author

echo %ERRORLEVEL% gives -1073740791.

Thank you for your precise answers, would wish I could help with the issue. So I hope it will be resolved.

I will try to test my sample program on ARM64 (I actually also have an ARM64-Windows running on my Mac). I remember having seen a Windows ARM64 toolchain on Azure, but could not find it now, where can I get it (I am currently using 5.6.1)? Thanks.

@compnerd
Copy link
Owner

You're welcome :) I am hopeful as well, it's a matter of time and help really. But this is something that is pretty important to get resolved IMO, so hopefully either someone else or I can get to it soon.

https://dev.azure.com/compnerd/swift-build/_build/results?buildId=59855&view=results has the latest ARM64 toolchain build that succeeds. I need to repair the builds after the rebranch to get the newer snapshots going for x64 (and thus ARM64).

-1073740791 = 0xc0000409 = STATUS_STACK_BUFFER_OVERRUN - it is the expected stack overflow.

@compnerd compnerd changed the title Window closes when writing into a text view asynchronously stack overflow on repeated async function invocation Aug 23, 2022
@compnerd
Copy link
Owner

This is an underlying Swift issue rather than an issue with this framework. Going to mark it as closed.

@compnerd compnerd closed this as not planned Won't fix, can't repro, duplicate, stale Aug 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants