Thread: Working app crashes on other computers

  1. #16
    Registered User
    Join Date
    May 2007
    Posts
    77
    Well that's all I wanted to know... Was there an easier way to do that, or was I doing the best thing I could? LOL. Anyway, all of this still hasn't solved the problem of it not working on other computers... And before you suggest it, I'm already putting in lots of checkpoints to test how far it gets before it stops working (on XP, it throws up the original save file invalid error I set up if the pointer was null... on x64 Vista, it just stops working altogether, though I suspect that's more an x64 thing).

  2. #17
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well post your current code, then.

  3. #18
    Registered User
    Join Date
    May 2007
    Posts
    77
    Alright, this is what I have now:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    
    main(int argc, char *argv[])
    {
        FILE* originalSave;
        FILE* newSave;
        long fileSize;
        long finalSize;
        uint32_t *buffer, result = 0;
        int x;
        char *originalSaveName = argv[1],
             *newSaveName = malloc(strlen(argv[0]) + strlen("Wii64 Saves") + 1),
             *chr,
             *ext;
             
        if(argv[1] == NULL)
        {
            puts("Error: no file provided.  Quitting.");
            system("PAUSE");
            return(0);
        }
    
        ext = strrchr(originalSaveName,'.');
        
        if((strcmp(ext, ".fla") != 0) && (strcmp(ext, ".sra") != 0))
        {
            puts("Error: invalid file type.  Quitting.");
            system("PAUSE");
            return(0);
        }
        
        originalSave = fopen(argv[1], "rb");
        if(originalSave == NULL)
        {
            printf("Error:  could not open file: %s", originalSave);
            return(1);
        }
        
        chr = strrchr(argv[0],'\\');
        if(chr == NULL)
        {
            puts("Error:  unable to find \"\\\" in arg[0]!");
        }
        strncpy(newSaveName, (char*)argv[0], chr-argv[0]+1);
        
        chr = strrchr(argv[1],'\\');
        if(chr == NULL)
        {
            puts("Error:  unable to find \"\\\" in arg[1]!");
        }
        strcat(newSaveName, "Wii64 Saves");
        strcat(newSaveName, chr);
        
        newSave = fopen(newSaveName, "wb");
        if(newSave == NULL)
        {
            printf("Error:  could not open file: %s", newSave);
            return(1);
        }
    
        fseek(originalSave, 0, SEEK_END);
        fileSize = ftell(originalSave);
        rewind(originalSave);
        
        if (fileSize <= 32768)
            finalSize = 32768;
        else if (fileSize <= 131072)
            finalSize = 131072;
        else if (fileSize > 131072){
            printf("Error:  invalid save size: %d", fileSize/1024);
            return 1;}
    
        buffer = malloc(sizeof(uint32_t));
        
        for (x = 0; x < fileSize/sizeof(uint32_t); x++)
        {
            fread(buffer, 1, sizeof(uint32_t), originalSave);
            result = ((*buffer << 24) & 0xFF000000) | 
            ((*buffer << 8) & 0x00FF0000) |
            ((*buffer >> 8) & 0x0000FF00) |
            ((*buffer >> 24) & 0x000000FF);
            fwrite(&result, 1, sizeof(uint32_t), newSave);
        }
        
        result = 11111111;
        
        for (x = 0; x < (finalSize-fileSize); x++)
        {
            fwrite(&result, 1, 1, newSave);
        }
    
        fclose(newSave);
        fclose(originalSave);
        free(buffer);
        free(newSaveName);
    
        return 0;
    }

  4. #19
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >>if((strcmp(ext, ".fla") != 0) && (strcmp(ext, ".sra") != 0))

    You should probably check that 'ext' isn't NULL, beforehand.

    >> printf("Error: could not open file: %s", originalSave);

    Why are you attempting to print a file pointer?

    >> if(chr == NULL)

    That's a good start, but then you continue on to use it, even when it's NULL.

  5. #20
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    There are also potential cases where 'finalSize' may be uninitialized (even negative).

  6. #21
    Registered User
    Join Date
    May 2007
    Posts
    77
    Yeah, but still none of that is helping the problem. In fact, I figured out that the problem is in fact this block of code:
    Code:
    strncpy(newSaveName, (char*)argv[0], chr-argv[0]+1);
        
        chr = strrchr(argv[1],'\\');
        if(chr == NULL)
        {
            puts("Error:  unable to find \"\\\" in arg[1]!");
        }
        strcat(newSaveName, "Wii64 Saves");
        strcat(newSaveName, chr);
        
        newSave = fopen(newSaveName, "wb");
        if(newSave == NULL)
        {
            printf("Error:  could not open file: %s", newSave);
            return(1);
        }
    And in fact, it turned out to be the strncpy, because I was able to hardcode the path (to c:\wii64saveSwap, where even that wouldn't work with the old way) and have it work just fine.

    I just don't understand why that would break from one computer to the next...

  7. #22
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I thought we had done the "don't forget to make sure the \0 gets put on the end of your string because strncpy sure as hell won't put it on there for you" speech already.

  8. #23
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Ah, right. Well strncpy doesn't guarantee null-termination (see post #11), so that could in fact be the problem.

  9. #24
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Molokai View Post
    I just don't understand why that would break from one computer to the next...
    ....
    Quote Originally Posted by MK27 View Post
    Probably because of memory segmentation.

    Remember, a bug is not something that is guaranteed to happen. A bug is something that might happen. So if you make a mistake -- such as a buffer overflow -- and nothing bad happens, you don't notice. Rearrange the executable a bit and then bang -- the problem becomes apparent.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #25
    Registered User
    Join Date
    May 2007
    Posts
    77
    Quote Originally Posted by MK27 View Post
    ....
    And to think it was a simple case of buffer overflow this whole time (or possibly buffer underflow)... I totally did not see those two words in your post the first time...

    I finally figured to put some output information to find out what exactly the path was on other computers, and I found out that on the other ones it was copying garbage data into the newSaveName path. *facepalm*. So I did some reworking of the copying lengths and came up with this:
    Code:
    chr = strrchr(argv[0],'\\');
        if(chr == NULL)
        {
            puts("Error:  unable to find \"\\\" in argv[0]!");
            system("PAUSE");
            return(0);
        }
        
        fName = strrchr(argv[1],'\\');
        if(fName == NULL)
        {
            puts("Error:  unable to find \"\\\" in arg[1]!");
            system("PAUSE");
            return(0);
        }
        
        newSaveName = malloc(strlen(argv[0]) - strlen(chr) + strlen("Wii64 Saves") + strlen(fName));
        
        strncpy(newSaveName, (char*)argv[0], strlen(argv[0])-strlen(chr));
        
        if(newSaveName[strlen(newSaveName)-1] != '\\')
            newSaveName[strlen(newSaveName)] = '\\';
    That last little bit also takes care of the trailing backslash (for some reason, I wasn't getting a trailing backslash on my laptop, but on my other computers, I was).

  11. #26
    Registered User
    Join Date
    May 2007
    Posts
    77
    OK, new problem with the file name creator. Here's what I've got so far (for that):
    Code:
        chr = strrchr(argv[0],'\\');
        if(chr == NULL)
        {
            puts("\nError:  unable to find \"\\\" in argv[0]!\n");
            system("PAUSE");
            return 0;
        }
        printf("\nFull app path verified.  App name:\n%s\n", chr);
        system("PAUSE");
        
        fName = strrchr(argv[1],'\\');
        if(fName == NULL)
        {
            puts("\nError:  unable to find \"\\\" in arg[1]!\n");
            system("PAUSE");
            return 0;
        }
        printf("\nFull save path verified.  Save name:\n%s\n", fName);
        system("PAUSE");
        
        newSaveName = malloc(strlen(argv[0]) - strlen(chr) + strlen("Wii64 Saves") + strlen(fName));
        
        strncpy(newSaveName, (char*)argv[0], strlen(argv[0])-strlen(chr));
        printf("\nNew save path copied.  New save path:\n%s\nLength of path:\n%d\n", newSaveName, strlen(newSaveName));
        system("PAUSE");
        newSaveName[strlen(argv[0])-strlen(chr)] = 0;
        printf("\nNull terminator set.  New save path:\n%s\nLength of path:\n%d\n", newSaveName, strlen(newSaveName));
        system("PAUSE");
        
        if(newSaveName[strlen(newSaveName)-1] != '\\')
            newSaveName[strlen(newSaveName)] = '\\';
        
        //chr = strrchr(argv[1],'\\');
        strcat(newSaveName, "Wii64 Saves");
        strcat(newSaveName, fName);
        
        printf("\n%s\n", newSaveName);
        
        system("PAUSE");
    This gives me this output:
    Code:
    Full app path verified.  App name:
    \wii64converter.exe
    Press any key to continue . . .
    
    Full save path verified.  Save name:
    \ZELDA MAJORA'S MASK(U).fla
    Press any key to continue . . .
    
    New save path copied.  New save path:
    C:\Documents and Settings\Rhydon\My Documents\wii64saveSwap\Common Files
    Length of path:
    72
    Press any key to continue . . .
    
    Null terminator set.  New save path:
    C:\Documents and Settings\Rhydon\My Documents\wii64saveSwap
    Length of path:
    59
    Press any key to continue . . .
    
    C:\Documents and Settings\Rhydon\My Documents\wii64saveSwap\Common FilesWii64 Sa
    ves\ZELDA MAJORA'S MASK(U).fla
    Press any key to continue . . .
    Why would it do that bolded part? I set the null terminator, and strcat completely ignores it. strncat doesn't do anything different.

  12. #27
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by Molokai View Post
    Why would it do that bolded part? I set the null terminator, and strcat completely ignores it. strncat doesn't do anything different.
    Because you overwrite the null terminator.
    Code:
        if(newSaveName[strlen(newSaveName)-1] != '\\')
            newSaveName[strlen(newSaveName)] = '\\'; // Here you overwrite the null terminator
    bit∙hub [bit-huhb] n. A source and destination for information.

  13. #28
    Registered User
    Join Date
    May 2007
    Posts
    77
    Ugh... *double facepalm*... Thanks, bithub.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Numeric addresses for computers
    By great in forum C Programming
    Replies: 4
    Last Post: 08-23-2010, 11:53 AM
  2. Replies: 8
    Last Post: 05-07-2009, 11:31 AM
  3. Max/min function not working correctly
    By En-Motion in forum C++ Programming
    Replies: 6
    Last Post: 03-19-2009, 12:28 AM
  4. Matrix and vector operations on computers
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 05-11-2004, 06:36 AM
  5. Stop errors on networked computers.
    By Bajanine in forum Networking/Device Communication
    Replies: 5
    Last Post: 11-02-2003, 01:00 PM