Thread: Back Tracking a Bad Line of Code - Need Help with Outputting to Find It

  1. #1
    Registered User
    Join Date
    Jul 2006
    Posts
    49

    Question Back Tracking a Bad Line of Code - Need Help with Outputting to Find It

    I have to back track through C code of a DLL that I didn't write to find why my C# application executes fine the first time, but then gets garbled results the second time. I have tracked it down to this function:

    Code:
    static GrowListEntry BZNA_GetBest(BecStruct *bzs)
    {
       int i;
       int MaxI, MaxScore;
       GrowListEntry RetVal;
    
       MaxScore = -1;
       
       for (i = 0; i < bzs->GrowListCount; i++)
       {
          if (bzs->GrowList[i].Score > MaxScore)
          {
             MaxI = i;
    
             MaxScore = bzs->GrowList[i].Score;
    
    	/* MaxScore is the first variable that differs on second run */
            ti_record_time("MaxScore %i", MaxScore);
          }
       }
    
       /* hang on to best */
       RetVal = bzs->GrowList[MaxI];
    
       /* move last slot to emptying best slot and decrement count */
       bzs->GrowList[MaxI] = bzs->GrowList[--bzs->GrowListCount];
       return RetVal;
    }
    MaxScore is the first variable that differs on the second run, so I need to find a way to find out what is getting messed up before that in order to find the line of code that is really causing the problem. I guess I need to find a way to output something in the line of code: bzs->GrowList[i].Score > MaxScore and go from there to find the needle in the haystack.

    I'm not use to C, so I don't know exactly the way to do this. Currently, I have been using the function ti_record_time() to output variables to the screen and then it is outputted to a text file so I can compare the first run to the second run. However, I don't know what I need to output this time. Any help is appreciated. And here's more of the C code that is relevant:

    Code:
    typedef struct tag_GrowListEntry
    {
       unsigned short Score;
       signed char X;
       signed char Y;
    } GrowListEntry;
    
    typedef struct tag_BecStruct
    {
       GrowListEntry GrowList[2851];
       int GrowListCount;
    } BecStruct;

  2. #2
    Jaguar
    Join Date
    Sep 2006
    Posts
    12
    Hey,

    Post aligned code. Difficult to understand.

    Jag

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You mean indented? It looks indented to me, and the post wasn't edited. (No last edited at line.)

    RetVal is pretty much the same as MaxScore . . . I'm guessing you added MaxScore.

    There is a better way to go that, unless bzs->GrowList[i].Score is always positive.

    There's at least one thing wrong with that function that jumps out at me: when bzs->GrowListCount is zero (or all the elements are negative), you'll get a segfault. You don't set MaxI to anything.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    Code in the .c file that is relevant:
    Code:
    static GrowListEntry BZNA_GetBest(BecStruct *bzs);
    
    static GrowListEntry BZNA_GetBest(BecStruct *bzs)
    {
       int i;
       int MaxI, MaxScore;
       GrowListEntry RetVal;
    
       MaxScore = -1;
       
       for (i = 0; i < bzs->GrowListCount; i++)
       {
          if (bzs->GrowList[i].Score > MaxScore)
          {
             MaxI = i;
    
             MaxScore = bzs->GrowList[i].Score;
    
    	/* MaxScore is the first variable that differs on second run */
            ti_record_time("MaxScore %i", MaxScore);
          }
       }
    
       /* hang on to best */
       RetVal = bzs->GrowList[MaxI];
    
       /* move last slot to emptying best slot and decrement count */
       bzs->GrowList[MaxI] = bzs->GrowList[--bzs->GrowListCount];
       return RetVal;
    }
    code in the .h file that is relevant:
    Code:
    typedef struct tag_GrowListEntry
    {
       unsigned short Score;
       signed char X;
       signed char Y;
    } GrowListEntry;
    
    typedef struct tag_BecStruct
    {
       GrowListEntry GrowList[2851];
       int GrowListCount;
    } BecStruct;
    
    extern void *ti_record_time(const char *string,... );

  5. #5
    Jaguar
    Join Date
    Sep 2006
    Posts
    12
    Hey,

    If all the numbers are positive(guess they are socres), the program works as you expected. I don't know what ti_record_time means. Try with printf instead of it.

    Good luck

    Jag

  6. #6
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    The problem is most likely with the Microsoft compiler...and I'm just trying to find where the compiler is garbling the values...so I can figure out what line of code it is and have one of the originators of this code fix the problem...I'm stuck on finding the needle in the haystack though . The code itself IS good...it executes PERFECTLY the first time. However, the second time it is executed, the compiler seems to garble something and the output is different the second time.

    dwks:
    "RetVal is pretty much the same as MaxScore . . . I'm guessing you added MaxScore." <--nope, this is the original code...I didn't add anything but this:

    Code:
    	/* MaxScore is the first variable that differs on second run */
            ti_record_time("MaxScore %i", MaxScore);
    which is what told me that MaxScore was different on the second run of the application.

    "bzs->GrowList[i].Score is always positive" <--yes, but how do I output the array to see when/if those values are right?

    jaguar23:
    ti_record_time works just like printf for me

    Thanks for any help

  7. #7
    Registered User
    Join Date
    Jul 2006
    Posts
    49
    Okay this might assist someone trying to help me figure out what to do and how to find my problem.

    I stepped through and the first time I run the application where it works, here are my results:

    azs 0x01337fa8
    MaxI 33193536
    MaxScore -1
    i 0
    RetVal {Score=1024 X=0 '' Y=0 ''}

    then MaxI goes to 0 when it hits MaxScore = azs->GrowList[i].Score;
    then MaxScore goes to 1248 when it finishes the for loop
    then i goes to 1 when it hits RetVal = azs->GrowList[MaxI];
    then RetVal goes to {Score=1248 X=0 '' Y=0 ''} when it hits azs->GrowList[MaxI] = azs->GrowList[--azs->GrowListCount];
    And then it finishes the entire application and produces the correct results.

    On the second run, here are my results:

    azs 0x01337fa8
    MaxI 704957632
    MaxScore -1
    i 0
    RetVal {Score=1024 X=0 '' Y=0 ''}

    then MaxI goes to 0 when it hits MaxScore = azs->GrowList[i].Score;
    then MaxScore goes to 2568 when it finishes the for loop
    then i goes to 1 when it hits RetVal = azs->GrowList[MaxI];
    then RetVal goes to {Score=2568 X=0 '' Y=0 ''} when it hits azs->GrowList[MaxI] = azs->GrowList[--azs->GrowListCount];
    And then it finishes the entire application and produces incorrect results.

    What can I do to track down the problem? Thanks!

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > BecStruct
    Where is this allocated?

    What you seem to be describing is a struct which is allocated as a local variable on the stack in one function, being returned (as a pointer to that local variable, illegally), so that when you invoke another function, the struct and the local variables of the new function essentially overlap.
    Code:
    ti_record_time("bzs at %p to %p, local stack frame at %p", bzs, (char*)bzs + sizeof *bzs, &i );
    If your local vars are between those two addresses, or even close, then I'd say something is returning pointers to local variables.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help in debugging this code
    By jaggesh in forum C Programming
    Replies: 4
    Last Post: 02-09-2008, 08:47 AM
  2. What does this line of code mean?
    By diagonalArg in forum C++ Programming
    Replies: 3
    Last Post: 07-28-2005, 12:59 PM
  3. Need the missing line of code
    By mayhem in forum C Programming
    Replies: 3
    Last Post: 06-20-2005, 04:21 PM
  4. Bad code or bad compiler?
    By musayume in forum C Programming
    Replies: 3
    Last Post: 10-22-2001, 09:08 PM
  5. Hotmail Hacked In One Line of code
    By no-one in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 09-01-2001, 09:45 AM