Git Product home page Git Product logo

Comments (18)

orchetect avatar orchetect commented on May 25, 2024 1

I ran into this issue a long time ago and it was hard to pin down. Thanks to the ancient implementation of CoreMIDI, you can get random exceptions in Swift.

  • snip -

I'm still looking into it.

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

does it happen consistently?

from webmidikit.

raduvarga avatar raduvarga commented on May 25, 2024

I only caught this once, then once I caught it sending some junk bytes (these were SysEx messages).
Apart from that, no matter how hard I tried, I couldn't get this to happen again ¯_(ツ)_/¯

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

@orchetect do you want to create a PR?

from webmidikit.

raduvarga avatar raduvarga commented on May 25, 2024

I ran into this issue a long time ago and it was hard to pin down. Thanks to the ancient implementation of CoreMIDI, you can get random exceptions that are hard to trace if you just pass MIDIPacketList.packet directly into MIDIPacketNext.

You need to do this instead:

p = withUnsafePointer(to: &p) { MIDIPacketNext($0).pointee }

@orchetect Unfortunately I caught a new EXC_BAD_ACCESS today with this new line.
I'm thinking it might be due to some thread syncronization issues?

from webmidikit.

orchetect avatar orchetect commented on May 25, 2024

@raduvarga Yes, was a red herring. Turns out the unsafe pointer access wasn't the issue.

  • snip -

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

This is crazy. I’m tempted to look at the disassembly.

from webmidikit.

orchetect avatar orchetect commented on May 25, 2024

Welp, back to square one. After further testing, the crashes persist.

I did however stumble on a possible solution in another repo.

Check out:

https://github.com/krevis/MIDIApps/blob/main/Frameworks/SnoizeMIDI/SMMIDIUtilities.m

I'm not sure if that fully resolves the crashes, but another Swift-based CoreMIDI library had to resort to using a C function to iterate packets in a packetlist.

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

I used to have some C code in the package a while back. Do you want to make a PR?

from webmidikit.

orchetect avatar orchetect commented on May 25, 2024

I have a stable fix in my own code based on that C method, along with some unsafe memory access on the Swift side.

It's in a couple production apps now so I will see if any issues/crashes are reported back.

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

Ok. What are your apps btw?

from webmidikit.

raduvarga avatar raduvarga commented on May 25, 2024

@orchetect Sounds good! How did you test the crashes?
In my case it usually happened when sending many long SysEx messages, but couldn't consistently produce a crash.

My approach (in my fork) in the meantime was to use a dispatch queue to solve some thread synchronization issues found in the library (found with the Thread Sanitizer in XCode), in case those were the culprit.
Not sure if that specifically helped, but I haven't seen any crashes or received crash reports since (also using it in production apps).

from webmidikit.

raduvarga avatar raduvarga commented on May 25, 2024

@orchetect @adamnemecek I found the issue!

Turns out MIDIPacketNext was called too many times and the last one was the one always causing the crash.
For example, if numPackets is 1, MIDIPacketNext is called 2 times.
So all we need is to avoid calling it for the last element.

I have a use case that was producing consistent crashes with the old code, now with the one below it works:

public func makeIterator() -> AnyIterator<Element> {
        var p: MIDIPacket = packet
        var i = (0..<numPackets).makeIterator()
        var index = 0
        
        return AnyIterator {
            defer {
                if (index < numPackets) {
                    p = withUnsafePointer(to: &p) { MIDIPacketNext($0).pointee }
                    index += 1
                }
            }
            
            return index < numPackets ? i.next().map { _ in .init(packet: &p) } : nil
        }
    }
}

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

How about this from AudioKit? https://github.com/Joachimholst95/Tunit2_0/blob/0a15fee2fdacdcc0c7d5f8c402559eb127622687/AudioKit/Common/MIDI/Packets/MIDIPacketList%2BSequenceType.swift

extension MIDIPacketList: Sequence {
    public typealias Element = MIDIPacket

    public var count: UInt32 {
        return self.numPackets
    }

    public func makeIterator() -> AnyIterator<Element> {
        var p: MIDIPacket = packet
        var idx: UInt32 = 0

        return AnyIterator {
            guard idx < self.numPackets else {
                return nil
            }
            defer {
                p = MIDIPacketNext(&p).pointee
                idx += 1
            }
            return p
        }
    }
}

from webmidikit.

raduvarga avatar raduvarga commented on May 25, 2024

Looks more elegant. In our case just needs a return .init(packet: &p) and we're sorted.

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

Want to submit a PR?

from webmidikit.

raduvarga avatar raduvarga commented on May 25, 2024

Just did.

from webmidikit.

adamnemecek avatar adamnemecek commented on May 25, 2024

Hopefully fixed by #30.

from webmidikit.

Related Issues (17)

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.