-2

I don't have enough reputation points to comment to ask if they solved the problem originally stated here. I have the same problem of the program crashing in construction of an ofstream. It is not multi-threaded access, but it can be called in quick succession. I believe it crashes on the 2nd time. I use scope to ensure the stream object is destroyed. Why would this happen?

I tried std::fopen too. It also results in a crash.

Here is the code using the ofstream:

static bool writeConfigFile (const char * filename, const Config & cfg)
{
    logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_INFO, "Write config file (%s stream)", filename);
    ofstream os(filename); // FIXME: Crashes here creating ofstream 2nd time
    if (os.good())
    {
        // Uses stream insertion operator to output attributes to stream 
        // in human readable form (about 2kb)
        outputConfig(cfg, os);
        if (!os.good())
        {
            logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_NOTICE, "Failed to write configuration file (%s)", filename);
            return false;
        }
        logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_INFO, "Configuration written to file (%s)", filename);
        return true;
    }
    logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_NOTICE, "Cannot write configuration file (%s)", filename);
    return false;
}

/**
 * Called when configuration settings have been read/received and validated
 * @return true if successfully set, and written to file
 */
bool Config::set (SysConfigSource source, const struct SCADA_dsconfig * p)
{
    Lock lock(mtxSet); // This is locking a mutex on construction of the lock. Release it on destruction.
    // Setup the non-current one to switch to
    Config * pCfg = pConfig.other();
    unsigned i, f, n = 0;

    // set attributes in pCfg based on the config received
    // and some constants ...

    pCfg->setWritten(writeConfigFile("test.conf", *pCfg));

    if (!pCfg->isWritten())
    {
        // Don't set system config status here. Existing one still in use.
        logsPrintLine(_SLOG_SETCODE(_SLOGC_CONFIG, 0), _SLOG_NOTICE, "Config file not written. Retain prior config.");
        return false;
    }
    pConfig.swap(); // switch-in the new config
    setSystemConfigSource(source);
    toSyslog(pCfg);
    notifyConfigChange();
    return true;
}
ozzylee
  • 181
  • 1
  • 15
  • It happens because you have a bug in your code, somewhere. That's always the reason why programs crash. – Sam Varshavchik Oct 29 '18 at 00:40
  • Yes. If only I could ask the author of the referenced issue whether they found something that might be common to mine. – ozzylee Oct 29 '18 at 00:52
  • You haven't given us much information, but there are things you can try that will narrow the problem down. Try restricting it to two iterations, to confirm that the error occurs on the second. Add a delay to prevent the quick succession. And maybe post the code and error message. – Beta Oct 29 '18 at 01:06
  • The possibility that two unrelated individuals writing two unrelated programs would end up writing the same exact bug are pretty much zero, so your attempt to "ask the author" would be, at most, a complete waste of time. Focus on figuring out the bug in your own code, and learning debugging techniques, instead of hoping someone else's bug is the same as yours'. – Sam Varshavchik Oct 29 '18 at 01:24
  • Thanks Sam. Using a debugger would be nice, but not possible. The software is embedded in a machine 600 kilometers away. All I get is a system log. There is no core dump. – ozzylee Oct 29 '18 at 01:40
  • I should also say that the file is always pre-existing. So the 2nd write that seems to be when the problem occurs is not the first re-write. – ozzylee Oct 29 '18 at 03:05
  • @Beta I've added code. There is no error message, and no core dump. – ozzylee Oct 29 '18 at 03:15
  • *I can't receive a message from the distant machine* and *there is no message* are two very different things. – Beta Oct 29 '18 at 15:19
  • @Beta I don't know what you mean in your last comment. You earlier asked me to post the error message. There is no error message. I never mentioned loss of message from the distant machine. There is no direct communication with any distant system. It only communicates with a local SCADA system from which it receives the configuration. – ozzylee Oct 29 '18 at 22:45

2 Answers2

0

Maybe post a segment of your source code in order to get an idea of where it went wrong.

Here is a very basic segment of code of how I would use fstream.. hope you will find it helpful.

#include <iostream>
#include <fstream>
#include <string>

int main() {
    while (1) {
        std::string testString;
        std::ofstream outFile;
        outFile.open("Test", std::ios_base::app); // Appends to file, does not delete existing code

        std::cout << "Enter a string: ";
        std::cin >> testString;
        outFile << testString << std::endl;

        outFile.close();
    }
}
HippoEug
  • 65
  • 1
  • 1
  • 8
0

It turned out to be a device driver bus master issue. Add "ahci nobmstr" when launching devb-ahci.

Derived via http://www.qnx.com/developers/docs/qnxcar2/index.jsp?topic=%2Fcom.qnx.doc.neutrino.user_guide%2Ftopic%2Fhardware_Troubleshooting_devb-eide.html

ozzylee
  • 181
  • 1
  • 15