Program crashes only when opened from terminal but not in Xcode


#1

I’m implementing a Markov chain music generator. Everything works fine in debug mode. However, if I open it from the terminal by typing “open MarkovMusic.app” (I’m on Mac OS) the program crashes. I tried commenting out several parts of my program to narrow down the scope and it seems the error has something to do with my own “MidiPaser” class in which I get the midi events and put them in some std containers:

void MainComponent::playButtonClicked() {
    vector<std::pair<int, double>> noteSequence = midiParser.getNoteSequenceForTrack(audioFilePath, 3);
}



vector<pair<int, double>> MidiParser::getNoteSequenceForTrack(String path, int index) {
    vector<pair<int, double>> resSequence; //!< midi pitch and note duration pair
    vector<pair<MidiMessage, double>> noteOnSequence;  //!< midi message and note duration pair
    MidiFile localMidiFile;
    File targetFile(path);
    FileInputStream stream(targetFile);
    localMidiFile.readFrom(stream);
    localMidiFile.convertTimestampTicksToSeconds();
    const MidiMessageSequence* sequence = localMidiFile.getTrack(index);    
    double duration = 0;
    for (int i = 0; i < sequence->getNumEvents(); i++) {
        if (sequence->getEventPointer(i)->message.isNoteOn()) {
            duration = sequence->getTimeOfMatchingKeyUp(i) - sequence->getEventPointer(i)->message.getTimeStamp();
            noteOnSequence.push_back(std::make_pair(MidiMessage (sequence->getEventPointer(i)->message), duration));
        }
    }
    // other processing I commented out
    return resSequence;
}

Although I hard code the index parameter, since it works properly in debug mode, I guess the problem might not be caused by the invalid index value. Does the snippet here have any bug?


#2

Didn’t go into detail but the first thing I see: You open a file and do not check if it was successfully opened. You should always handle this potential error. Is path absolute or relative? Relative paths are a potential error source, as the directory they are actually relative to may depend on where you open your application from.


#3

Thanks for your reply! the path is relative… So usually, if I want to use another resource like the midi file in my case, and may also want to publish my project, how should I refer to that file in xcode?


#4

I’m really no expert in building ready-to-ship standalone applications for mac OS, so I waited if anyone with more practical experience kicks in with an answer. So let me tell what I know from theory :smiley: As you might have already noticed an .app on your mac is not the binary itself but a folder usually containing something like Contents/Ressources/ where all the files an application relies on are placed. Just take a look into the application bundles of some apps on your mac to get an idea.

Now I’d change the signature of your function so that it takes a File& instead of the String as an argument. This way you could pass it the default file from the Resources folder which can be accessed somehow like this (untested!):
File defaultFile = File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile).getChildFile ("Contents/Resources/yourDefaultFile.something")

Now you could pass this File object to your function. Alternatively - if it makes any sense for your use-case - you are now also able to use the result of a FileChooser dialogue window.

And please implement some error handling in your getNoteSequenceForTrack function so that an invalid file won’t lead to a crash but provides you useful error handling and/or debugging information!