Skip to content
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

Runtime EXC_BAD_ACCESS in AsyncSequence (SkieSwiftFlow) #31

Closed
twinkelbauer opened this issue Oct 30, 2023 · 5 comments
Closed

Runtime EXC_BAD_ACCESS in AsyncSequence (SkieSwiftFlow) #31

twinkelbauer opened this issue Oct 30, 2023 · 5 comments

Comments

@twinkelbauer
Copy link

We are currently switching from the native Coroutines Plugin to SKIE and are especially interested in the SkieSwiftFlow. We just noticed that we are receiving runtime crashes on iOS, when collecting from the SkieSwiftFlow .

Code

KMP

class SkieTest {
    fun intFlow() = flow {
        do {
            emit(rand())
        } while (true)
    }
}

iOS App

let task = Task {
    let intStream = SkieTest().intFlow()
    for await intValue in intStream {
        Logger().debug("Debug \(intValue)")
    }
}

Error:

Thread 3: EXC_BAD_ACCESS (code=1, address=0x0)

What we already know:
When add a transformation like map or compatMap and just return the element like it came, all is running fine. This is will be our current solution for that problem.

extension AsyncSequence {
    @preconcurrency @inlinable public func toAsyncSequence() -> AsyncMapSequence<Self, Element> { return self.map { element in element } }
}

We also noticed you are doing the same in your example: https://github.com/touchlab/SKIEDemoSample/blob/a9df32055e5d88c39d4dc60ef7dfe06fa49998b6/ios/ios/TickDemo.swift#L24

let secondCounter = TickProvider.shared.ticks()
    .scan(0) { acc, _ in
        acc + 1
    }

Question

Since we need to use this on all SkieSwiftFlows to use it properly it should be handled by SKIE.

Also please note: I did just try this in our current KMP project, so a misconfiguration isn't that unlikely. Our current configuration for SKIE is:

extensions.configure<SkieExtension> {
    analytics {
        enabled.set(false)
    }

    features {
        group("io.ktor.client.plugins.cache.storage") {
            EnumInterop.Enabled(false)
            SealedInterop.Enabled(false)
            FlowInterop.Enabled(false)
            SuspendInterop.Enabled(false)
        }
    }
}

Versions:

skie = "0.5.0"
kotlin = "1.9.10"

In case it's relevant the generated .h file:

__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("SkieTest")))
@interface PrefixSkieTest : PrefixBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
- (id<PrefixKotlinx_coroutines_coreFlow>)intFlow __attribute__((swift_name("intFlow()")));
@end
@FilipDolnik
Copy link
Member

Hi! I tried the example code, and it didn't crash. So we need to figure out what is different about your and mine setup.

Likely it will be a different version of something. What version of the following SW do you have?

  • Coroutines
  • Xcode
  • macOS
  • iOS (for the device that runs the binary)

The SKIE configuration doesn't contain anything that should cause this problem.
Would you be able to create a new project just with this piece of code to see if it still crashes?

The error message points to some null pointer exception - do you know where in the code it crashes (it will likely show you some line in assembly code)?

Also, is the error reliably reproducible for you, and if so how often and how quickly does it happen (for example, it crashes immediately without printing anything vs. it can print +- 100 numbers and then crash)?

@PiotrPrus
Copy link

I had the same issue today on version 0.5.0 of SKIE. Downgrade back to 0.4.2 and everything works as expected.

@twinkelbauer
Copy link
Author

Hello @FilipDolnik,

we are using

  • coroutines 1.7.3
  • XCode 15
    • tools 15
    • simulator 15 (didn't try on real device yet)
    • MacOS 14.0
    • deploymentTarget 15

The error message points to some null pointer exception - do you know where in the code it crashes (it will likely show you some line in assembly code)?

Exactly, here a small dump

`partial apply for thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out τ_0_0):

->  0x1000890bc <+0>:  orr    x29, x29, #0x1000000000000000
    0x1000890c0 <+4>:  sub    sp, sp, #0x20
    0x1000890c4 <+8>:  stp    x29, x30, [sp, #0x10]
    0x1000890c8 <+12>: str    x22, [sp, #0x8]
    0x1000890cc <+16>: add    x29, sp, #0x10
    0x1000890d0 <+20>: ldr    x9, [x22]
    0x1000890d4 <+24>: str    x9, [sp]
    0x1000890d8 <+28>: mov    x8, x29
    0x1000890dc <+32>: sub    x8, x8, #0x8
    0x1000890e0 <+36>: str    x9, [x8]
    0x1000890e4 <+40>: ldr    x0, [x9, #0x18]
    0x1000890e8 <+44>: ldr    x8, [x22]
    0x1000890ec <+48>: mov    x10, x29
    0x1000890f0 <+52>: sub    x10, x10, #0x8
    0x1000890f4 <+56>: str    x8, [x10]
    0x1000890f8 <+60>: str    x8, [x9, #0x10]
    0x1000890fc <+64>: bl     0x102be1af0               ; symbol stub for: swift_task_dealloc

Also, is the error reliably reproducible for you, and if so how often and how quickly does it happen (for example, it crashes immediately without printing anything vs. it can print +- 100 numbers and then crash)?

It just crashes on the first collection so none of the values get ever emitted

I can also validate @PiotrPrus's claim and with 0.4.20 everything works as expected. Going further I checked your tag 0.5.2 from yesterday and there also everything works. So it's just the 0.5.0 version which produces the EXC_BAD_ACCESS.

My solution would then be to use 0.5.2. Is it safe to use yet?

@FilipDolnik
Copy link
Member

Hi! Yeah, yesterday, we were able to create a reproducer for a similar crash and subsequently fix it in 0.5.2 - so it's good to hear that it also fixed your project. The key to reproducing it was to use XCFramework instead of a regular framework, which is what we use in the tests.

Is it safe to use yet?

Yes, you can go ahead and use it. It's a regular release; we just haven't had the time yet to put out release notes / make a public announcement, which will happen today.

@twinkelbauer
Copy link
Author

Great! Thanks for your support!

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

3 participants