Answered by:
Strange behavior if statement related to Code Contracts

Question
-
I have a strange behavoir of an if statement and if I turn Code Contracts off, this behavior is not strange anymore.
Explanation:
Machine info:
- Windows Vista 64bits
- Visual Studio 2008 (with all updates).
My code contract properties:
x Perform Runtime Contract Checking = Full
x Perform Static Contract Checking
x Check in Background
x Build a Contract Reference Assembly
Other properties:
Build:
Platform Target: x86
x Treat warnings as errors
x All
Code Analysis
x Enable Code Analysis on Build
x For all Rules Enabled During Code Analysis: Treat Warnings as Errors ON.
01: private bool _InsertAllowed;
02: ...
03: private bool ProcessRow(DataRow row)
04: {
05: // [some code]
06: foreach (DataColumn column in row.Table.Columns)
07: {
08: _InsertAllowed = [call to another method];
09: // [some code]
10: if (!_InsertAllowed)
11: {
12: break; // out of the 'foreach column'.
13: }
14: // [some code]
15: }
16: }Now the strange behavior:
- If the _InsertAllowed is TRUE, the code DOES get into the if statement and the code breaks out of the foreach.
Setting the _InsertAllowed in line 8 forcebly to True, does not change the behavoir.
Replacing line 8-10 with:
bool x = true;
if (!x)
Does not change the behavior.
I cannot reproduce this behavior in an small consoleapplication. But on the machine of my colleague this behavior is the same.
- Restarting my machine and VS ide does not change the behavior.
- Turning MS CC off and restart the VS-IDE is the solution.
- Turning MS CC on again and restart the VS-IDE brings back this strange behavior
- Turning MS CC off again and restart the VS-IDE solves the strange behavior again.
My conclusion is that this behavior must has something to do with MS CC.Wednesday, March 25, 2009 11:08 AM
Answers
-
I haven't heard back from you, so I will close the issue for now. Feel free to reopen it if the latest release didn't fix this.
Cheers, -MaF (Manuel Fahndrich)- Marked as answer by Manuel Fahndrich Monday, May 11, 2009 6:25 PM
Monday, May 11, 2009 6:25 PM
All replies
-
Thanks. That is indeed not good. Can you confirm that the behavior goes away when you turn off "runtime checking" of contracts?
Cheers, -MaF (Manuel Fahndrich)Wednesday, March 25, 2009 5:09 PM -
Yes turning of Runtime Checking 'solves' this problem.
Btw we encountered the same problem in another assembly:
public long Wakeup
{
get
{
return _Wakeup;
}
protected set
{
#region require: At least 25 ms or 0 ms
if (value < 25 && value != 0)
{
throw new InvalidOperationException("The wakeup mechanisme is not suited for smaller periods than 25 ms.");
}
#endregion
_Wakeup = value;
}
}
private long _Wakeup;
Setting the Wakeup property to a value of 1324 resulted in an InvalidOperationException.
(we use version 1.1.20309.13 of code contracts).
Friday, March 27, 2009 1:03 PM -
I've been trying to reproduce the (bad) behavior, but have been unable to. Can you please send me the full solution (self-contained and in a zip file) that shows the problem and then I can try again?
I'm very sorry you are having problems with it!- Proposed as answer by Mike BarnettMicrosoft employee Tuesday, March 31, 2009 11:41 PM
Tuesday, March 31, 2009 11:41 PM -
@Mike Barnett,
It is undoable to send you the whole solution.
The problem occurs at my job (software company), and our 'system' is a complex system that you can only run when you have our database, 4 or 5 solutions with a total of approximately 40 assemblies. The system is based on the use of multithreading. If we want to try to reproduce this behavior on in a small solution it will take us to long.
My colleague just reported the same problem in another solution in our system, where he sets a boolean property of a class to true, and when he checks this property in an if-statement on another thread, the if-statement sees the property as false.
If he removes the Code Contract from the references, the proplem is gone.
The strange this is that my colleague does NOT use a Contract.Assert() / Contract.Ensures() / Contract.Requires() or anything else in his code.
We hope this problem is quickly solved, because we really want to use Code Contracts in our organisation.
Thursday, April 2, 2009 9:05 AM -
Hi, we understand that it is not reasonable to send us your code base. However, we don't have enough information to actually attack this problem at the moment.
Given your description, it could be that there may be multi-threading issues in conjunction with contracts. From the design of contracts, we definitely are aware of some problems that you may run into (however they should not surface in the way you describe).
If you have re-entrant method, ie., methods that acrquire locks internally to protect data structures, then it is a bad idea to have contracts on those methods (or inherited) that touch the state that is protected by these locks, as the state would be accessed while not holding the lock. Contracts need to be executed in such a way that the state that is touched during a contract is accessed by a single thread only. Since contracts are at method boundaries, this means that if the contract touches state protected by a lock, the lock needs to be already held in the caller.
Cheers, -MaF (Manuel Fahndrich)Thursday, April 2, 2009 4:22 PM -
@Manuel:
I understand that you don't have enough information to attach this problem.
If I (or one of my colleagues) comes across this issue again in a smaller assembly, we definitely will send you that code.
I understand what you're saying about re-entrant methods, but the very strange thing is that the problem occurs not in any code where contracts actually are used.
The three solutions where we came across this problem all had a reference to the CodeContracts.dll and at some places inside the code contracts are used.
But the actual code where the issue occured did not have any relation to code contracts.
It was just code where a boolean variable was checked in an if-statment.
At first I thought that a colleague had made a practical joke by overloading the == operator of the boolean, so it looked like false was true, and true was false.
But after removing the reference to the CodeContracts.dll the issue was gone...
Friday, April 3, 2009 7:01 AM -
Here's another thing we can check. If you send us the MSIL (the C# compiled IL) for the method where you see the problem, one version that went through the rewriter (with runtime checking on) and one version that did not go through the rewriter (with runtime checking off), then we can at least determine if the rewriter did something wrong to the IL.
You can send us the IL files by email if you want to to codconfb@microsoft.com.
Cheers, -MaF (Manuel Fahndrich)Thursday, April 9, 2009 4:35 PM -
I haven't heard back from you, so I will close the issue for now. Feel free to reopen it if the latest release didn't fix this.
Cheers, -MaF (Manuel Fahndrich)- Marked as answer by Manuel Fahndrich Monday, May 11, 2009 6:25 PM
Monday, May 11, 2009 6:25 PM -
Ok, I understand. For now we don't use the Contracts anymore because of this problem we had. Because we are programming on a release version, we don't have time to check if the problem still exists. I will keep you posted when we have the time again to test the use of contracts again, even if the problem does not exist anymore!!Tuesday, May 12, 2009 7:37 AM