Visual Studio Variable Not Created When Manually Setting Next Statement - visual-studio-2010

I just started using a new Windows 7 x64 machine today and experienced something new during debugging. I have code that can be thought of as the following:
if(/*Some criteria that evaluates to false*/)
{
int weekNum = (int)DateTime.Now.Subtract(_myObject.StartDate).TotalDays/7;
//Do something with weekNum
}
I wanted to debug through the code within the if block. In my current circumstances, it's much easier just to set the next statement to the first line inside the block than to make my data meet the criteria so I set the next execution line to int weekNum... This gives a null reference exception because it, apparently, is not instantiating weekNum. I've verified that nothing on the right side expression is null and can successfully get a result by copying and pasting the right side into the watch or immediate window. If I literally replace it with if(true), it works fine. Choosing the next execution statement in scenarios like this has been a pretty routine way of debugging for me. Why is it behaving this way?
Edit: I have verified that the current build configuration is not optimized.
Edit: I cannot reproduce this in another test project. I modified my original code to remove my object from the equation and here is the new full code that gets the exception in the original project:
private void SelectDefaultLearningUnit()
{
TODLogic.LearningUnit currentLu = null;
//If sce is active get the learning unit for the current week.
if (!_sce.IsCancelled && !_sce.IsCancelled
&& _sce.StartDate <= DateTime.Now
&& _sce.EndDate > DateTime.Now)
{
//Get number of weeks since semester started
int currentWeek = (int)4; //THIS LINE STILL BLOWS UP
//Find the first learning unit for the current week
currentLu = _LearningUnits.Where(lu => lu.StartWeek <= currentWeek && lu.EndWeek >= currentWeek).FirstOrDefault(); //May be null
}
if (currentLu == null)
currentLu = _LearningUnits.FirstOrDefault();
cbLearningUnit.SelectedItem = currentLu;
}
Again, it only gets the exception if I manually set the execution inside of the if block when it would've otherwise been skipped. The only difference I see is if I put a watch on the variable in the test project it says the value of currentWeek is 0 until it hits the line and then it gets assigned. In the project where it blows up, it shows a red excalamation mark to the left of current week and the value says '' is null. I would expect it to either say the value is 0 or 'currentWeek' is undefined! This is why I originally thought it thought currentWeek was "not instantiated" i.e. didn't exist.

Related

SCAN command with spring redis template

I am trying to execute "scan" command with RedisConnection. I don't understand why the following code is throwing NoSuchElementException
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
Cursor c = redisConnection.scan(scanOptions);
while (c.hasNext()) {
c.next();
}
Exception:
java.util.NoSuchElementException at
java.util.Collections$EmptyIterator.next(Collections.java:4189) at
org.springframework.data.redis.core.ScanCursor.moveNext(ScanCursor.java:215)
at
org.springframework.data.redis.core.ScanCursor.next(ScanCursor.java:202)
Yes, I have tried this, in 1.6.6.RELEASE spring-data-redis.version. No issues, the below simple while loop code is enough. And i have set count value to 100 (more the value) to save round trip time.
RedisConnection redisConnection = null;
try {
redisConnection = redisTemplate.getConnectionFactory().getConnection();
ScanOptions options = ScanOptions.scanOptions().match(workQKey).count(100).build();
Cursor c = redisConnection.scan(options);
while (c.hasNext()) {
logger.info(new String((byte[]) c.next()));
}
} finally {
redisConnection.close(); //Ensure closing this connection.
}
I'm using spring-data-redis 1.6.0-RELEASE and Jedis 2.7.2; I do think that the ScanCursor implementation is slightly flawed w/rgds to handling this case on this version - I've not checked previous versions though.
So: rather complicated to explain, but in the ScanOptions object there is a "count" field that needs to be set (default is 10). This field, contains an "intent" or "expected" results for this search. As explained (not really clearly, IMHO) here, you may change the value of count at each invocation, especially if no result has been returned. I understand this as "a work intent" so if you do not get anything back, maybe your "key space" is vast and the SCAN command has not worked "hard enough". Obviously, as long as you're getting results back, you do not need to increase this.
A "simple-but-dangerous" approach would be to have a very large count (e.g 1 million or more). This will make REDIS go away trying to search your vast key space to find "at least or near as much" as your large count. Don't forget - REDIS is single-threaded so you just killed your performance. Try this with a REDIS of 12M keys and you'll see that although SCAN may happily return results with a very high count value, it will absolutely do nothing more during the time of that search.
To the solution to your problem:
ScanOptions options = ScanOptions.scanOptions().match(pattern).count(countValue).build();
boolean done = false;
// the while-loop below makes sure that we'll get a valid cursor -
// by looking harder if we don't get a result initially
while (!done) {
try(Cursor c = redisConnection.scan(scanOptions)) {
while (c.hasNext()) {
c.next();
}
done = true; //we've made it here, lets go away
} catch (NoSuchElementException nse) {
System.out.println("Going for "+countValue+" was not hard enough. Trying harder");
options = ScanOptions.scanOptions().match(pattern).count(countValue*2).build();
}
}
Do note that the ScanCursor implementation of Spring Data REDIS will properly follow the SCAN instructions and loop correctly, as much as needed, to get to the end of the loop as per documentation. I've not found a way to change the scan options within the same cursor - so there may be a risk that if you get half-way through your results and get a NoSuchElementException, you'll start again (and essentially do some of the work twice).
Of course, better solutions are always welcome :)
My old code
ScanOptions.scanOptions().match("*" + query + "*").count(10).build();
Working code
ScanOptions.scanOptions().match("*" + query + "*").count(Integer.MAX_VALUE).build();

Solving tcsncpy_s.inl assertion (line 24)

I've a fairly simple program which needs user input in the form of a text string. I've a CLR form with an edit box and I need to take that input and pass it into my class which just copies it to a member variable.
In the Form.h code, handling the TextChanged event is...
int textLength = m_userDest->TextLength;
if (textLength > 2 && textLength < 5)
{
// Could be an ICAO code in here
char dest[5];
String^ text = m_userDest->Text->ToUpper();
sprintf_s(dest, 5, "%s", text);
airTraffic.SetUserDest(dest);
}
My class (airTraffic) SetUserDest function is just
void CAirTraffic::SetUserDest(char* dest)
{
strncpy_s(m_userDest, 5, dest, 5);
}
When this is run I get this debug assertion, it doesn't stay on the screen and automatically clears after a few seconds.
Debug Assertion Failed!
Program: ...sual Studio 2010\Projects\FSAirTraffic\Debug\FSAirTraffic.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\tcsncpy_s.inl
Line: 24
Expression: ((_Dst)) != NULL && ((_SizeInBytes)) > 0
I don't have an f:\ drive so I'm guessing this is some internal Microsoft(?) code so I can't see the context of the assertion and exactly what it's problem is. I don't have a file called tcsncpy_s.inl on my machine.
If I don't call my class function then there's no assertion so I assumed that was the problem.
Curiously though, when stepping through the debugger the assertion occurs as I step out of the TextChanged event, with the rest of the functions operating as intended (as far as I can see).
Does anyone know what the problem is and how I can go about solving it?
I don't understand how your code works. You use m_userDest twice, first it appears to be a pointer to a structure of some sort, maybe a handle to a TextBox control:
int textLength = m_userDest->TextLength;
Later you pass it to strncpy_s, which needs a char*, not a pointer to some structure.
void CAirTraffic::SetUserDest(char* dest)
{
strncpy_s(m_userDest, 5, dest, 5);
}
While it's possible for a structure to implicitly convert to a char*, it's not possible for a structure pointer to do so. Perhaps there's a smart pointer involved? Or you are using the same member variable name for completely different purposes in different classes1?
In any case, strncpy_s is inspecting the value of its first argument and not liking it.
1 Note that the new "wisdom" saying not to use Hungarian notation has destroyed the ability to understand this code in textual form. We don't have an IDE providing mouseover information about the data type of variables. Applications Hungarian is still a good idea in the real world, despite how many "best practices" documents decry it. Amazing how many code style documents are written from a purely theoretical basis.

Incorrect Resharper Suggestion - "Merge Conditional Expression"

Given an oracle query which is returning a single string value, to get the value from the query I use the following two lines:
var result = cmd.ExecuteOracleScalar();
return result != null ? ((OracleString)result).Value : null;
The "!= null" in this statement is underlines with the suggestion to "Merge Conditional Expression". If I accept the suggestion it changes it to:
return ((OracleString)result).Value;
Which throws an exception because the value returned will be null for a number of executions.
Is there anyway to use the ternary operator but not have this warning?
Note that if I change the code to:
var result = cmd.ExecuteOracleScalar();
if (result == null)
return null;
return ((OracleString)result).Value;
Resharper then first suggests that I "Convert to Return Statement" which just changes it back to use the ternary operator.
Any Suggestions?
This looks like exactly the bug identified in RSRP-434610:
given original code that checks an object reference for nullity, and accesses a property of the object if the object reference is not null
R# proposes a refactoring that always accesses the property, and will therefore fail when the object reference is null
The issue has a fix version of 9.1, which was released just a few days ago, although watch out trying to upgrade from within VS.

Unit Test Only Passes in Debug Mode, Fails in Run Mode

I have the following UnitTest:
[TestMethod]
public void NewGamesHaveDifferentSecretCodesTothePreviousGame()
{
var theGame = new BullsAndCows();
List<int> firstCode = new List<int>(theGame.SecretCode);
theGame.NewGame();
List<int> secondCode = new List<int>(theGame.SecretCode);
theGame.NewGame();
List<int> thirdCode = new List<int>(theGame.SecretCode);
CollectionAssert.AreNotEqual(firstCode, secondCode);
CollectionAssert.AreNotEqual(secondCode, thirdCode);
}
When I run it in Debug mode, my code passes the test, but when I run the test as normal (run mode) it does not pass. The exception thrown is:
CollectionAssert.AreNotEqual failed. (Both collection contain same elements).
Here is my code:
// constructor
public BullsAndCows()
{
Gueses = new List<Guess>();
SecretCode = generateRequiredSecretCode();
previousCodes = new Dictionary<int, List<int>>();
}
public void NewGame()
{
var theCode = generateRequiredSecretCode();
if (previousCodes.Count != 0)
{
if(!isPreviouslySeen(theCode))
{
SecretCode = theCode;
previousCodes.Add(previousCodes.Last().Key + 1, SecretCode);
}
}
else
{
SecretCode = theCode;
previousCodes.Add(0, theCode);
}
}
previousCodes is a property on the class, and its Data type is Dictionary key integer, value List of integers. SecretCode is also a property on the class, and its Data type is a List of integers
If I were to make a guess, I would say the reason is the NewGame() method is called again, whilst the first call hasn't really finished what it needs to do. As you can see, there are other methods being called from within the NewGame() method (e.g. generateRequiredSecretCode()).
When running in Debug mode, the slow pace of my pressing F10 gives sufficient time for processes to end.
But I am not really sure how to fix that, assuming I am right in my identification of the cause.
What happens to SecretCode when generateRequiredSecretCode generates a duplicate? It appears to be unhandled.
One possibility is that you are getting a duplicate, so SecretCode remain the same as its previous value. How does the generator work?
Also, you didn't show how the BullsAndCows constructor is initializing SecretCode? Is it calling NewGame?
I doubt the speed of keypresses has anything to do with it, since your test method calls the functions in turn without waiting for input. And unless generateReq... is spawning a thread, it will complete whatever it is doing before it returns.
--after update--
I see 2 bugs.
1) The very first SecretCode generated in the constructor is not added to the list of previousCodes. So the duplicate checking won't catch if the 2nd game has the same code.
2) after previousCodes is populated, you don't handle the case where you generate a duplicate. a duplicate is previouslySeen, so you don't add it to the previousCodes list, but you don't update SecretCode either, so it keeps the old value.
I'm not exactly sure why this is only showing up in release mode - but it could be a difference in the way debug mode handles the random number generator. See How to randomize in WPF. Release mode is faster, so it uses the same timestamp as seed, so it does in fact generate exactly the same sequence of digits.
If that's the case, you can fix it by making random a class property instead of creating a new one for each call to generator.

emit code crashes at runtime but not in debug, why

I have some code, that build up a proxy from a type. It work perfekt.
Then I have add in the setter emit code, that it has to push a isDirty bit, when it is call. This fail, why?
If I run the code without the isDirty bit, it works.
If I run the code with the isDirty bit, it works in debug, but is start the disassembly window up in visual studio.
If I run the code with the isDirty (without-debug) the program crash (not responding) but when I hit cancel, it starts working and show all de rigth data.
PropertyBuilder property = proxy.DefineProperty(propertyInfo.Name, propertyInfo.Attributes, propertyInfo.PropertyType, null);
MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual;
MethodBuilder setMethod = proxy.DefineMethod("set_" + propertyInfo.Name, attributes, typeof(void), new Type[] { propertyInfo.PropertyType });
ILGenerator setIL = setMethod.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0); // load this on the stack - where this is the type we are creating
setIL.Emit(OpCodes.Ldarg_1); // load first parameter on the stack
setIL.Emit(OpCodes.Call, propertyInfo.GetSetMethod());
{
//error here: when this is uncomment, it fails
// // set the isDirty bit
// setIL.Emit(OpCodes.Ldarg_0); // load this on the stack
// setIL.Emit(OpCodes.Ldc_I4_1, 1); // push a number on the stack
// setIL.Emit(OpCodes.Stfld, isDirtyField); // save the value on the stack in field
}
setIL.Emit(OpCodes.Ret);
property.SetSetMethod(setMethod);
I have a hard time, seeing why this fails? Need some help from the experts :)
// dennis
I'm not sure if this is your only issue, but you are using the wrong Emit overload when emitting your Ldc_I4_1 opcode. You should do either:
setIL.Emit(OpCodes.Ldc_I4_1)
or
setIL.Emit(OpCodes.Ldc_I4, 1)
The first option will result in a slightly smaller IL method body since it uses a specialized opcode, whereas the second one is not specific to the number being loaded.

Resources