Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Program Responds Incorrectly to 'true' Condition


This question is answered.


Permlink Replies: 14 - Last Post: Apr 20, 2016 9:33 PM Last Post By: Earl Staley
Earl Staley

Posts: 99
Registered: 4/9/07
Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 12:27 PM
I am stepping through the following code. This code is contained in the .cpp file for a package containing a component that I designed and have placed on my form.

		TDateTime Date;
		for (int i = 0; i <= 10; i++) {
			if (UseDate) {
				Date = TDateTime(FGraphXLo + i / 10.0 * (FGraphXHi - FGraphXLo));
				str = Date.DateString();
			}
			else {
				str = FGraphXLo + i / 10.0 * (FGraphXHi - FGraphXLo);
				if (fabs(FGraphXHi - FGraphXLo) <= 1)
					SetDecimal(str, 2);
				else if (fabs(FGraphXHi - FGraphXLo) <= 10)
					SetDecimal(str, 1);
				else
					SetDecimal(str, 0);
			}
 


I have a watch set on UseDate and the value is true, as it should be from my code. However when I step through the code, the debugger steps to the 'else' clause and skips the code it should execute when 'UseDate' is true. I have seen this phenomenon happen occasionally in the past, but I am not sure what causes it.

What could be the cause of the if(UseDate) {...} not being executed when 'UseDate' is true?

Thank you...
Earl Staley
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 1:24 PM   in response to: Earl Staley in response to: Earl Staley
Earl wrote:

What could be the cause of the if(UseDate) {...} not being
executed when 'UseDate' is true?

I assume UseDate is declared as a bool, and not an int or other type, correct?
You said it is true in the Watch Inspector, but what does the actual disassembly
see the value as when executing the 'if' statement on the CPU?

--
Remy Lebeau (TeamB)
Earl Staley

Posts: 99
Registered: 4/9/07
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 1:35 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy,

Thank you for the reply. Yes it is a bool. I don't know how to do this: "but what does the actual disassembly
see the value as when executing the 'if' statement on the CPU". If you can either tell me how to do that or tell me where I can find out how to perform that operation, I would appreciate it.

Regards...
Earl

Remy Lebeau (TeamB) wrote:
Earl wrote:

What could be the cause of the if(UseDate) {...} not being
executed when 'UseDate' is true?

I assume UseDate is declared as a bool, and not an int or other type, correct?
You said it is true in the Watch Inspector, but what does the actual disassembly
see the value as when executing the 'if' statement on the CPU?

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 2:35 PM   in response to: Earl Staley in response to: Earl Staley
Earl wrote:

Thank you for the reply. Yes it is a bool. I don't know how to do
this: "but what does the actual disassembly see the value as when
executing the 'if' statement on the CPU".

Put a breakpoint on the 'if' statement, run the code until the breakpoint
is hit, and then open the debugger's CPU Disassembly view and step through
the raw ASM instructions that the compiler generated for the 'if' statement.
You can watch the CPU registers being changed on each instruction. You
should be able to see the exact value of the bool that the CPU is evaluating,
and the result of the evaluation.

--
Remy Lebeau (TeamB)
Earl Staley

Posts: 99
Registered: 4/9/07
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 3:03 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy,

When I step through the code while watching the assembly language, it executes the code after line 2139 below and then jumps to the code for the else statement, line 2144. I assume this comparison: "cmp byte ptr [ecx+$004941ed],$00" is being performed to check for zero. This instruction I assume is a jump on zero: "jz $005537f5". If this: "$005537f5" is the result of the comparison, then it should not have jumped. It has been many, many years since I have done anything in assembly language and even then, I wasn't very good at it.

Hope this helps...
Earl

CPU Instructions:

StripChart.cpp.2139:
0055370E 8B8D28FDFFFF mov ecx,[ebp-$000002d8]
00553714 80B9ED41490000 cmp byte ptr [ecx+$004941ed],$00
0055371B 0F84D4000000 jz $005537f5

//the following instructions are not performed
StripChart.cpp.2140:
00553721 DB85C4F8FFFF fild dword ptr [ebp-$0000073c]
00553727 DB2DA03C5500 fld tbyte ptr [$00553ca0]
0055372D DEC9 fmulp st(1)
0055372F 8B8528FDFFFF mov eax,[ebp-$000002d8]
00553735 DD80E0414900 fld qword ptr [eax+$004941e0]
0055373B 8B9528FDFFFF mov edx,[ebp-$000002d8]
00553741 DCA2D8414900 fsub qword ptr [edx+$004941d8]
00553747 DEC9 fmulp st(1)
00553749 8B8D28FDFFFF mov ecx,[ebp-$000002d8]
0055374F DC81D8414900 fadd qword ptr [ecx+$004941d8]
00553755 83C4F8 add esp,-$08
00553758 DD1C24 fstp qword ptr [esp]
0055375B 8D85BCF8FFFF lea eax,[ebp-$00000744]
00553761 E89E6BFFFF call System::TDateTime::TDateTime(const double)
00553766 8BD0 mov edx,eax
00553768 8D85C8F8FFFF lea eax,[ebp-$00000738]
0055376E E84D060000 call System::TDateTime::operator =(const System::TDateTime &)
StripChart.cpp.2141:
00553773 66C7853CFDFFFF38 mov word ptr [ebp-$000002c4],$0738
0055377C 8D8574FDFFFF lea eax,[ebp-$0000028c]
00553782 E839E3EAFF call System::UnicodeString::UnicodeString()
00553787 8BD0 mov edx,eax
00553789 FF8548FDFFFF inc dword ptr [ebp-$000002b8]
0055378F 8D85C8F8FFFF lea eax,[ebp-$00000738]
00553795 E8EA470200 call System::TDateTime::DateString()
0055379A 8D9574FDFFFF lea edx,[ebp-$0000028c]
005537A0 8D8570FDFFFF lea eax,[ebp-$00000290]
005537A6 E88D6BFFFF call System::AnsiStringT<0>::AnsiStringT<0>(const System::UnicodeString &)
005537AB 838548FDFFFF02 add dword ptr [ebp-$000002b8],$02
005537B2 8D9570FDFFFF lea edx,[ebp-$00000290]
005537B8 8D8578FDFFFF lea eax,[ebp-$00000288]
005537BE E8690DEBFF call System::AnsiStringT<0>::operator =(const System::AnsiStringT<0> &)
005537C3 83AD48FDFFFF02 sub dword ptr [ebp-$000002b8],$02
005537CA 8D8570FDFFFF lea eax,[ebp-$00000290]
005537D0 BA02000000 mov edx,$00000002
005537D5 E8AE0CEBFF call System::AnsiStringT<0>::~AnsiStringT<0>()
005537DA FF8D48FDFFFF dec dword ptr [ebp-$000002b8]
005537E0 8D8574FDFFFF lea eax,[ebp-$0000028c]
005537E6 BA02000000 mov edx,$00000002
005537EB E83C490200 call System::UnicodeString::~UnicodeString()
StripChart.cpp.2142:
005537F0 E922010000 jmp $00553917

//execution resumes here:
StripChart.cpp.2144:
005537F5 66C7853CFDFFFF44 mov word ptr [ebp-$000002c4],$0744
005537FE DB85C4F8FFFF fild dword ptr [ebp-$0000073c]
00553804 DB2DA03C5500 fld tbyte ptr [$00553ca0]
0055380A DEC9 fmulp st(1)
0055380C 8B8D28FDFFFF mov ecx,[ebp-$000002d8]
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 3:26 PM   in response to: Earl Staley in response to: Earl Staley
El 20/04/2016 a las 0:03, Earl Staley escribió:
"cmp byte ptr [ecx+$004941ed],$00"

Step until the line "cmp byte ptr [ecx+$004941ed],$00"
Then you can view the value stored in [ecx+$004941ed] at the top of the CPU window
Earl Staley

Posts: 99
Registered: 4/9/07
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 3:58 PM   in response to: Antonio Estevez in response to: Antonio Estevez
When the arrow is at the line "cmp byte ptr [ecx+$004941ed],$00", the line at the top of CPU window says [$7FEA41FD]=$00000000 Thread #9908

Does that mean that the 'cmp' was true, and therefore it should have jumped per the 'jz' statement?

Earl

Antonio Estevez wrote:
El 20/04/2016 a las 0:03, Earl Staley escribió:
"cmp byte ptr [ecx+$004941ed],$00"

Step until the line "cmp byte ptr [ecx+$004941ed],$00"
Then you can view the value stored in [ecx+$004941ed] at the top of the CPU window
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 4:22 PM   in response to: Earl Staley in response to: Earl Staley
El 20/04/2016 a las 0:58, Earl Staley escribió:
When the arrow is at the line "cmp byte ptr [ecx+$004941ed],$00", the line at the top of CPU window says [$7FEA41FD]=$00000000 Thread #9908

Does that mean that the 'cmp' was true, and therefore it should have jumped per the 'jz' statement?

Yes. See the Remy explanation.

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 4:46 PM   in response to: Earl Staley in response to: Earl Staley
Hello Earl,

When the arrow is at the line "cmp byte ptr [ecx+$004941ed],$00", the
line at the top of CPU window says [$7FEA41FD]=$00000000

That means ECX is $7FA10010, is that a valid pointer to something that should
be holding a UseDate value?

Does that mean that the 'cmp' was true, and therefore it should
have jumped per the 'jz' statement?

It meants the value stored at memory address $7FEA41FD is 0, and when compared
to 0, the result is 0, and the ZF flag gets set to 1, thus the jump.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 4:02 PM   in response to: Earl Staley in response to: Earl Staley
Earl wrote:

When I step through the code while watching the assembly language,
it executes the code after line 2139 below and then jumps to the code
for the else statement, line 2144.

I assume this comparison: "cmp byte ptr [ecx+$004941ed],$00" is
being performed to check for zero.

That is correct. [ecx+$004941ed] is your bool variable. If the value is
0, the result of the CMP is zero, and the CPU's ZF flag is set to 1, which
the subsequent JZ (jump if zero) instruction is checking.

But, the fact that such a large offset value is being added to the ECX register
value is a bit odd. I assume ECX (which holds the value from [ebp-$000002d8])
contains an object pointer? Is UseDate a member of a class? Offsets of
class members should not be that large. If ECX is holding an object pointer,
does it actually point to a valid object in memory?

This instruction I assume is a jump on zero: "jz $005537f5".

That is correct.

If this: "$005537f5" is the result of the comparison, then it should not
have
jumped.

$005537f5 is the memory address that is jumped to if CMP sets the ZF flag
to 1.

--
Remy Lebeau (TeamB)
Earl Staley

Posts: 99
Registered: 4/9/07
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 5:10 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy,

'UseDate' is part of a TStripChart class which is part of a package:

class PACKAGE TStripChart : public TCustomControl {
...
public:
	__fastcall TStripChart(TComponent* Owner);
 
		bool Scale1, Scale2, Scale3, Scale4, Scale5, UseDate;
...
}


Is the fact that 'UseDate' is in a package explain why the offset is so large?

When the arrow is at the line "cmp byte ptr [ecx+$004941ed],$00", the line at the top of CPU window says [$7FEA41FD]=$00000000 Thread #9908, so I assume that means the 'UseData is zero, or false.

You asked if " If ECX is holding an object pointer, does it actually point to a valid object in memory?".
I have no clue if it is a valid object. How can I tell?

This problem started showing up when I began another program yesterday. Part of the troubleshooting included writing a test program with just the component installed with the minimum amount of code to set the parameters for the StripChart component. That program also failed to work correctly.

So I went to the last program I wrote which used the latest version of the StripChart component. That program worked properly. So I did a 'Build' on the program to see if the component's package had been corrupted. The 'Build' went fine and the StripChart component worked correctly with the 'UseDate' bool. I assume that a 'Build' will force a complete compile and link everything, including the package.

I then went to the program where I developed the StripChart component and added a button with an OnClick event like this: "StripChart1->UseDate=!StripChart1->UseDate;" and it successfully toggled 'UseDate' as evidenced by the display. 'UseDate' just labels the X-Axis lines on the StripChart to display as a date rather than a double.

I am at a loss as to why the component quit working properly in my latest programs, but works properly in others. When I find the answer, I will certainly post it here. It is very puzzling to me.

Earl


Remy Lebeau (TeamB) wrote:
Earl wrote:

When I step through the code while watching the assembly language,
it executes the code after line 2139 below and then jumps to the code
for the else statement, line 2144.

I assume this comparison: "cmp byte ptr [ecx+$004941ed],$00" is
being performed to check for zero.

That is correct. [ecx+$004941ed] is your bool variable. If the value is
0, the result of the CMP is zero, and the CPU's ZF flag is set to 1, which
the subsequent JZ (jump if zero) instruction is checking.

But, the fact that such a large offset value is being added to the ECX register
value is a bit odd. I assume ECX (which holds the value from [ebp-$000002d8])
contains an object pointer? Is UseDate a member of a class? Offsets of
class members should not be that large. If ECX is holding an object pointer,
does it actually point to a valid object in memory?

This instruction I assume is a jump on zero: "jz $005537f5".

That is correct.

If this: "$005537f5" is the result of the comparison, then it should not
have
jumped.

$005537f5 is the memory address that is jumped to if CMP sets the ZF flag
to 1.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Program Responds Incorrectly to 'true' Condition
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 5:41 PM   in response to: Earl Staley in response to: Earl Staley
Earl wrote:

Is the fact that 'UseDate' is in a package explain why the offset is
so large?

No. It should be an offset relative to the start of the class that declares
it. Accessing it is then a matter of adding the offset to a memory address
that points at an object of that class. Makes me wonder if the compiler
generated bad assembly code. It happens sometimes.

You asked if " If ECX is holding an object pointer, does it actually
point to a valid object in memory?".

I have no clue if it is a valid object. How can I tell?

When the breakpoint is hit, put the memory address into a Debug Inspector
and tell the Inspector to type-cast the address into a pointer to your class.
If the Inspector shows garbage for the class members, the pointer is bad.

--
Remy Lebeau (TeamB)
Keith Dopson

Posts: 63
Registered: 3/16/00
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 2:53 PM   in response to: Earl Staley in response to: Earl Staley
Earl Staley wrote:
I am stepping through the following code. This code is contained in the .cpp file for a package containing a component that I designed and have placed on my form.

		TDateTime Date;
		for (int i = 0; i <= 10; i++) {
			if (UseDate) {
				Date = TDateTime(FGraphXLo + i / 10.0 * (FGraphXHi - FGraphXLo));
				str = Date.DateString();
			}
			else {
				str = FGraphXLo + i / 10.0 * (FGraphXHi - FGraphXLo);
				if (fabs(FGraphXHi - FGraphXLo) <= 1)
					SetDecimal(str, 2);
				else if (fabs(FGraphXHi - FGraphXLo) <= 10)
					SetDecimal(str, 1);
				else
					SetDecimal(str, 0);
			}
 


I have a watch set on UseDate and the value is true, as it should be from my code. However when I step through the code, the debugger steps to the 'else' clause and skips the code it should execute when 'UseDate' is true. I have seen this phenomenon happen occasionally in the past, but I am not sure what causes it.

What could be the cause of the if(UseDate) {...} not being executed when 'UseDate' is true?

Thank you...
Earl Staley

In addition to Remy's suggestions, also notice the address of your bool variable. If possible, note, either using map or debugger windows, nearby (preceeding) variables, buffers, structures, etc.

It may be possible that some operation inside your loop is storing beyond what you think is happening, i.e., unintentionally overwriting your bool with a 0.

Closely watch your bool value while stepping the loop.

If it suddenly changes "out of the blue", look for an unintential overwrite.

k
Earl Staley

Posts: 99
Registered: 4/9/07
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 19, 2016 3:17 PM   in response to: Keith Dopson in response to: Keith Dopson
Kieth,

Thank you for your reply. I stepped through the loop and UseDate never changed, i.e. it remained 'true' throughout the loop.

The odd thing is I have used this component successfully many, many times since I wrote it almost 20 years ago. I have occasionally added features to it, the last time being Jan 17th of this year, but I have used it successfully in programs since then including the 'UseDate' portion of the code.

I have no idea why it is suddenly not working.

Earl

Keith Dopson wrote:
Earl Staley wrote:
I am stepping through the following code. This code is contained in the .cpp file for a package containing a component that I designed and have placed on my form.

		TDateTime Date;
		for (int i = 0; i <= 10; i++) {
			if (UseDate) {
				Date = TDateTime(FGraphXLo + i / 10.0 * (FGraphXHi - FGraphXLo));
				str = Date.DateString();
			}
			else {
				str = FGraphXLo + i / 10.0 * (FGraphXHi - FGraphXLo);
				if (fabs(FGraphXHi - FGraphXLo) <= 1)
					SetDecimal(str, 2);
				else if (fabs(FGraphXHi - FGraphXLo) <= 10)
					SetDecimal(str, 1);
				else
					SetDecimal(str, 0);
			}
 


I have a watch set on UseDate and the value is true, as it should be from my code. However when I step through the code, the debugger steps to the 'else' clause and skips the code it should execute when 'UseDate' is true. I have seen this phenomenon happen occasionally in the past, but I am not sure what causes it.

What could be the cause of the if(UseDate) {...} not being executed when 'UseDate' is true?

Thank you...
Earl Staley

In addition to Remy's suggestions, also notice the address of your bool variable. If possible, note, either using map or debugger windows, nearby (preceeding) variables, buffers, structures, etc.

It may be possible that some operation inside your loop is storing beyond what you think is happening, i.e., unintentionally overwriting your bool with a 0.

Closely watch your bool value while stepping the loop.

If it suddenly changes "out of the blue", look for an unintential overwrite.

k
Earl Staley

Posts: 99
Registered: 4/9/07
Re: Program Responds Incorrectly to 'true' Condition  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 20, 2016 9:33 PM   in response to: Earl Staley in response to: Earl Staley
Here are some of the additional steps I have taken to identify the problem:

1) Ran a complete virus scan using Avast. No viruses detected.
2) Ran a complete scan with Malwarebytes. No malware detected.
3) I commented out almost all of the code except the code necessary to setup the stripchart.
4) I deleted all of the files in the project's 'Debug' directory and performed a clean 'Build'.

The problem remained.

While writing this post, I went back to the IDE and saw this error message which might be a clue to the problem:

"Error executing 'C:\ProgramData{2D559015-4C05-4AE5-8C8B-7E13E1EAB09D}\Setup.exe': The parameter is incorrect"

This is the first time I have noticed the error. I went back and tried to duplicate what I had just done, i.e. deleted the 'Debug' directory files, performed a clean 'Build' and ran the program. The error message never appeared again.

I made a new application to replace the one with the bug. I carefully entered code a little at a time and compiled and ran the program to see if and when the bug reappeared. I even copy/pasted most of the code from the buggy program into the new program. The program is essentially complete and the stripchart is working exactly as it was designed to.

I have kept the buggy program because I am still very curious as to what caused the bug(s) and to learn how to troubleshoot and prevent them.

Any ideas why the I got the error message and what effect that error message might have on the program?

Also, I would still like to find out what caused the bugs in the program, even though I have completely replaced the program. Maybe it is just one of those unexplained things that happen with computers occasionally and I will never find the source of the problem.

Additionally, C++ Builder 2010 locked up the computer solid twice when I was writing the buggy program. My code probably caused the lockup, but it could be that the lockup introduced bugs in the program. Either way, I could not even use "Ctrl' 'Alt' 'Delete' to start the Task Manager. The computer was totally locked up and I had to kill the power and restart the computer.

BTW, I am using C++ Builder 2010 on a Windows 10 machine.

Thank you...
Earl Staley
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02