Subroutine uses wrong value

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • drhowarddrfine
    Recognized Expert Expert
    • Sep 2006
    • 7434

    Subroutine uses wrong value

    I have a subroutine that receives a filename from another. This sub has worked with three other calling programs but, today, I added another and for some reason it finds some other file name to use. iow, I call the routine xml_load_file(D EALS) where DEALS is elsewhere defined as "../options/deals.xml". The argument is defined as a char*. If I print out the filename at the beginning of xml_load_file() , it shows an entirely different path and file: ../carts/12345 which is a legitimate filename but I don't have a clue how it got that.

    What really throws me for a loop is I create "test_load( char *p)" which does nothing but print out what *p is, put it in the same file as xml_load_file() and that shows the correct file name.

    Does this ring a bell with anyone? Using gcc on Linux.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Sounds very strange to me Doc.

    I would step through the program using gdb and see what is actually happening if it is not obvious from code examination.

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      Reading between the lines, I assume that the relevant portion of your program looks something like this:
      Code:
      #define DEALS "../options/deals.xml"
      
      void test_load(char *p) {
         printf("%s\n", p);
         }
      
      void xml_load_file(char *p) {
         test_load(p);
         printf("%s\n", p);
         }
      
      int main(void) {
         xml_load_file(DEALS);
         return 0;
         }
      And that your output looks something like this:
      Code:
      ../options/deals.xml
      ../carts/12345
      Is this correct? Please be precise about any discrepancies.

      I look forward to your response. In the absence of evidence, the only mechanism that comes to mind is if DEALS is a pointer variable rather than a macro, and if it points to freed memory. In that case it wouldn't be terribly surprising if the contents of the freed memory (ie, the string) changed spontaneously.

      Comment

      • drhowarddrfine
        Recognized Expert Expert
        • Sep 2006
        • 7434

        #4
        Pretty much what you show. Calling it from main works. test_load(), though I show it differently, does not. Calling from this one particular subroutine does not. I also did a strcpy of the filename to a s[FILENAME] and called the sub with a pointer to that but it fails.

        What mystifies me is if I put a print statement on the first line of xml_load_file() , it shows the wrong filename; it never receives the correct one.
        Code:
        #define DEALS "../options/deals.xml"
         
        void test_load(char *p) {
           printf("%s\n", xml_load_file(DEALS);
           }
         
        void xml_load_file(char *p) {
           printf("%s\n", p);
           }
         
        int main(void) {
           xml_load_file(DEALS);
           return 0;
           }

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          Wow -- I'm baffled.

          In the spirit of blindly poking around, why don't you try changing the way you pass the argument to xml_load_file. Try something like this, so we're passing an explicit pointer to string:
          Code:
          char *DEALS = "../options/deals.xml";
          ...
          xml_load_file(DEALS);
          Perhaps it is a cut-and-paste error here in the forum, but you show test_load printing the return value from xml_load_file (which returns void!) rather than its pointer argument. For that matter, I don't see anybody calling test_load.

          So, are you saying that xml_load_file gets the correct string if it is called directly by main; but that it gets the wrong string if it is called by test_load, which is called by main?

          By the way, is the xml_load_file argument a char* or a const char*? If the former, then is there any chance that somebody is overwriting the string before you print it?

          Comment

          • drhowarddrfine
            Recognized Expert Expert
            • Sep 2006
            • 7434

            #6
            If I call xml_load_file from main, it receives the correct file name. If I call xml_load_file from the problem module, it receives the incorrect file name.

            I created test_load in the same file as xml_load_file just to see what would happen. From main it works. From the problem module it doesn't.

            I'm thinking there must be something strange in that file causing this and I might spend time today moving that stuff to another file one at a time to see what happens.

            I'd use gdb but it's a web app and I can't remember how I tie into that when it starts up. I've looked at the assembly and it appears to be pointing at a reasonable address but haven't had a chance to delve deeper into it.

            I feel better having others say the same as I feel (baffled). Most of my posts here are when I'm panicing under pressure or stupid mistakes from exhaustion. This may be both but I just don't see it.

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              Different modules ... that sounds like a variable-scope issue.

              Try changing test_load from
              Code:
              void test_load(char *p) { 
                 printf("%s\n", xml_load_file(DEALS)); 
                 }
              to
              Code:
              void test_load(char *p) {
                 printf("%s\n", p);
                 xml_load_file(p);
                 }
              That is, have test_load use its pointer argument rather than be hard-coded for DEALS.

              If you call test_load from main, then the scope of the DEALS passed to xml_load_file is the same regardless of whether main calls test_load or xml_load_file.

              By the way, is DEALS defined using the __FILE__ built-in macro? That is one way to make sure it has a different value in different modules.

              Comment

              • drhowarddrfine
                Recognized Expert Expert
                • Sep 2006
                • 7434

                #8
                I had already tried what you show. Don't use __FILE__.

                I narrowed it down to a line where I can get it to work to that point but I have to leave for the day.

                Comment

                • drhowarddrfine
                  Recognized Expert Expert
                  • Sep 2006
                  • 7434

                  #9
                  Just passing through.

                  I created an exact copy of xml_load_file as xml_load_file2. In both routines I do:
                  Code:
                  xml_load_file(DEALS);
                  xml_load_file2(DEALS);
                  
                  void
                  xml_load_file(char* p)
                  {
                     printf("%s\n",p);
                  }
                  The first prints the wrong file name. The second works.

                  I have to leave but this is just too bizarre. I'm going to look at the assembly of that last compile tonight. I'll probably compile it on my FreeBSD box to see what's different. I even did a virus scan. I'm wondering if something's gone wrong with this install of the compiler or something but everything else I've done since works fine.

                  Comment

                  • donbock
                    Recognized Expert Top Contributor
                    • Mar 2008
                    • 2427

                    #10
                    Are you certain that neither xml_load_file nor any of the library functions it calls write via the pointer argument? If so, then the first call to xml_load_file might corrupt the string, leading to the mysterious symptoms you're seeing.

                    Whether or not string literals are const is platform dependent, so it is not necessarily impossible to corrupt them.

                    It might be interesting to see what compiler warnings you get if you change xml_load_file to take a "const char*" argument.

                    Comment

                    • Oralloy
                      Recognized Expert Contributor
                      • Jun 2010
                      • 988

                      #11
                      Two questions:
                      1) Is it possible that you are linking with an out-of-date object module.
                      2) Are you sure that you aren't overriding the macro

                      Try using full compiler warnings and see if anything useful pops out.

                      Comment

                      • weaknessforcats
                        Recognized Expert Expert
                        • Mar 2007
                        • 9214

                        #12
                        I am not able to reproduce your error. Your otiginal code works OK. So does a copy of xml_load_file as xml_load_file2.

                        I am using Visual C++.NET 2008 and I built both a C and C++ with no errors each time.

                        Comment

                        • drhowarddrfine
                          Recognized Expert Expert
                          • Sep 2006
                          • 7434

                          #13
                          This has gotten just too bizarre. I'm going to do some picking apart.

                          In the mean time, i've got a new puppy today!!!

                          Comment

                          • Oralloy
                            Recognized Expert Contributor
                            • Jun 2010
                            • 988

                            #14
                            Originally posted by drhowarddrfine
                            This has gotten just too bizarre. I'm going to do some picking apart.

                            In the mean time, i've got a new puppy today!!!
                            Congratulations !

                            Comment

                            • drhowarddrfine
                              Recognized Expert Expert
                              • Sep 2006
                              • 7434

                              #15
                              Found it. Some older code I call free'd an allocation too early for this implementation. It's been sitting in this for ages so reusing it should cause no harm, I thought. Unfortunately, the string pointed to is in that area. The simple fix is to copy the string instead.

                              Comment

                              Working...