0

I've written a C program which runs on a windows PC.

I wrote a text file for debugging purposes which writes when the code gets to certain parts, and if certain parts are true or false.

I completed my code and it works exactly as desired/expected. However when I comment out the code to create and write to file, to try and release the file the program freezes. I've had this before in embedded systems but never on a PC OS before.

Is this a common issue? Are there some causes I should know about?

Below is my code in main.

int main(int argc, char** argv)
{
    BOOL running = TRUE;
    BOOL get;

    //Open debug file
#ifdef DEBUG
    FILE* debugFile = openFile("debugFile.txt", "w+");
#endif

    //Print start up message to console
    printStartUpMessage();

    //Initialise variables
    initialiseVariables();        

    while(running)
    {
#ifdef DEBUG
        fprintf(debugFile, "%s", "1. In start of main loop")
#endif
        if(_kbhit())
            handleButtonPress();
#ifdef DEBUG
        fprintf(debugFile, "%s", "2. Handled buttons");
#endif
        do
        {
            get = getSourceOne();
        }while(get);

        do
        {
#ifdef DEBUG
            fprintf(debugFile,"%s","3. Getting source two\n");
#endif
            get = getSourceTwo();
#ifdef DEBUG
            fprintf(debugFile,"%s %d","4. Got source two...\n", get);
#endif
        }while(get);

        parseInformation();

#ifdef DEBUG
            fprintf(debugFile,"%s","5. Parsed\n");
#endif

        running = stillRunning();
    }
}
Luke
  • 1,077
  • 13
  • 33
  • at a guess you forgot a place you are writing to the file and writing to file pointer that isn't initialized – Keith Nicholas Feb 04 '15 at 02:53
  • or possibly trying to close the file? – Keith Nicholas Feb 04 '15 at 02:53
  • @KeithNicholas the FILE is open and closed within the main function and was only written a handful (5) of times (all within said function). These have all definitely been removed when the FILE* was removed as they are all within a #ifdef DEBUG – Luke Feb 04 '15 at 02:56
  • 5
    My guess, and it's only a guess since I can't see your code, is that you have incorrect behavior in your program and the debug logging subtly changed the way the program worked which masked the actual problem. It could be a slight change in timing or order of operations. You should try reducing your code to a short simple demonstration of the problem you can post here. If you're lucky the act of reducing the code will show you where the problem is so you can fix it. – Retired Ninja Feb 04 '15 at 02:59
  • Where the program freezes would be useful information. Why not debug and set breakpoints and narrow down where the program freezes up? Divide and conquer until you find the spot in your code where you messed up. – BitTickler Feb 04 '15 at 03:10
  • @user2225104, The program is designed to be running on an embedded XP PC so can't run in with MVS debugger. (Thats why the text file is used). Fairly confident that it is freezing at getSourceTwo which is a type of user specific serial interface. – Luke Feb 04 '15 at 03:18
  • @RetiredNinja. Thanks I added code from main. Belief the problem is most likely occuring in the second do/while – Luke Feb 04 '15 at 03:21
  • @Luke In roughly 20 years of embedded programming I never had code which I could not run as well on my PC. Yes, you have to plan for this right from the start, but it pays off. If you now are in a situation, where you cannot find this easy problem by running your PC-build and if you suspect your debug interface causes the problem, I would try to remove that debug interface from the release compile, maybe by replacing it with an empty stub. – BitTickler Feb 04 '15 at 03:29
  • You have two `fprintf` calls not wrapped in `#ifdef DEBUG`. But, since the code shouldn't even compile without that defined I'd guess it isn't the problem. You should wrap your debug logging in a function so you only have one place to disable when you want to turn it off. – Retired Ninja Feb 04 '15 at 03:34
  • @user2225104 There is debugging I can run on the PC, which does 90% of the testing. However the simulation DLLs do not behave exactly the same as the real communication DLLs which is why there is this issue where it works with MVS on Windows 7 but is freezing on the intended product – Luke Feb 04 '15 at 03:34
  • @RetiredNinja Thanks for pointing that out, that was a typo only on the uploaded version. – Luke Feb 04 '15 at 03:37
  • I agree with @RetiredNinja about trying to reduce it, but also suggest putting a sleep in your loops to see if what was making it work was timing – Foon Feb 04 '15 at 03:42
  • @Luke Then most likely your debug traces do not cause your hangs. You have so many do {} while(get) loops - if those ``get`` assume values which keep you in the loops, it might look like hanging. Maybe on the target, some of your assumptions on when get == 0 is not holding. Maybe they can only get 0 on some specific timings. And your traces change the timings. – BitTickler Feb 04 '15 at 03:42
  • are you changing between DEBUG and RELEASE modes? – Keith Nicholas Feb 04 '15 at 03:43
  • The nice thing about wrapping the debug code in a function is you could easily replace the actual file writing with delays and see if that also fixes it which would help you narrow it down to a timing issue. – Retired Ninja Feb 04 '15 at 03:51
  • possible duplicate of [What are some reasons a Release build would run differently than a Debug build](http://stackoverflow.com/questions/312312/what-are-some-reasons-a-release-build-would-run-differently-than-a-debug-build) – Keith Nicholas Feb 04 '15 at 03:52
  • @user2225104 that does definitely seem a viable reason. I will try removing the traces and introduce delays as suggested by RetiredNinja and will update you on if it is successful – Luke Feb 04 '15 at 03:54
  • @KeithNicholas I have done a #define DEBUG and built it as a Release. This might not be standard but I can confirm the variables are initialised correctly in memory – Luke Feb 04 '15 at 03:58
  • This is why I no longer use any embedded board without a 'real' JTAG debugger. – Martin James Feb 04 '15 at 09:15
  • Does the `getSourceTwo()` something asynchronously. Without the two `fprintf`it could be that two consecutive calls of the function clash in some fashion. – Sebastian Stigler Feb 04 '15 at 09:53
  • An update. The program is working properly now. The updated communication DLLs varied slightly from a previous version and so required more time to record messages which are being sent(getSourceOne returns values received while getSourceTwo echos values being sent). As result the program now needs more time. So I currently have a sleep immediately after getSouceTwo so the program will late and allows the CPU to be shared with other programs to prevent hogging – Luke Feb 08 '15 at 21:01

1 Answers1

0

I'm assuming your claim [made in a comment] is true that no code, other than what you have shown, attempts to write to the debug file.

You need to examine your other code (i.e. not the I/O statements, as they are almost certainly the innocent victim rather than the cause of the problem) more carefully. I'll bet there is an instance of undefined behaviour in there somewhere.

That's the punchline - explanation follows.

I/O statements (in fact, almost any code) affect the memory layout of a program (e.g. to represent the FILE pointer, store string literals being used as format strings or simply being output).

If some code is writing over an area of memory it shouldn't, removing I/O statements changes WHAT is being overwritten. For whatever reason, the operating system was not detecting the original problem but - now - it does so it terminates your program. Voila! A program that is now crashing, despite you only removing code that doesn't - in itself - do anything wrong.

The symptoms of undefined behaviour can be subtle and indirect like that.

Rob
  • 1,966
  • 9
  • 13
  • if it was crashing due to memory overwritten wouldn't I expect an exception to be caused rather than the console program to freeze up? Thanks – Luke Feb 04 '15 at 20:54
  • No - in fact, although not beyond realms of possibility, throwing an exception is an unlikely response in practice. Detecting symptoms of the problem is a prerequisite to signalling the program (e.g. throwing an exception). If symptoms are not detected, anything can happen. Hanging is a common result, but certainly not the only possibility. From a C++ standard perspective, the behaviour is undefined - which means ANYTHING is permitted (hanging, abnormal program termination, crashing the host system, or whatever). – Rob Feb 05 '15 at 09:22
  • thanks, it is worth knowing for the future. I have solved this problem , it appears to be a timing change in the updated DLLs used by the program. – Luke Feb 08 '15 at 21:02