Why isn't this code executing correctly (video)? - c#

I'm using Unity (3.4) Monodevelop (2.4.2) and it's not executing the code properly when I step through it in the debugger. Here's a link to the video that shows it, please run it at 720p and fullscreen it...
http://www.youtube.com/watch?v=LGN7kxMUqjA
Also, here are some screenshots showing the debugger displaying really strange values when I mouseover a variable. Here's what it looks like when it correctly shows the value of the xSectionPixel in the first if block...
And here's what it looks like when it incorrectly shows the value of the xSectionPixel in the second if block...
This is also the line of code where it starts executing code incorrectly.
What would cause this?
I've tried reinstalling the tools, using a fresh copy of the code from the repository, I even set it all up on a different computer with a different OS (Win 7) and it always does the same thing. Doesn't that mean it has to be my code then?
It's also worth noting that I'm using SVN to push/pull the code from a repository and my local copy exists in my Dropbox folder.
Thanks so much in advance for your wisdom! Here's the code as well if you can spot anything that might be breaking things (i.e. the way I'm using floats and ints maybe?)
Vector2 textureCoordToHexGridCoord(int textX, int textY)
{
Vector2 hexGridCoord = new Vector2();
float m = hexH / hexR;
int xsection = (int)(textX / (hexH + hexS));
int ysection = (int)(textY / (2 * hexR));
int xSectionPixel = (int)(textX - xsection * (hexH + hexS));
int ySectionPixel = (int)(textY - ysection * (2 * hexR));
//A Section
if(xsection % 2 == 0)
{
hexGridCoord.x = xsection;
hexGridCoord.y = ysection;
if(xSectionPixel < (hexH - ySectionPixel * m))
{
hexGridCoord.x--;
hexGridCoord.y--;
}
if(xSectionPixel < (-hexH + ySectionPixel * m))
{
hexGridCoord.x--;
}
}
//B Section
else
{
if(xSectionPixel >= hexR)
{
if(ySectionPixel < (2 * hexH - xSectionPixel * m))
{
hexGridCoord.x = xsection - 1;
hexGridCoord.y = ysection - 1;
}
else
{
hexGridCoord.x = xsection;
//hexGridCoord.y = ysection;
hexGridCoord.y = ysection - 1;
}
}
if(xSectionPixel < hexR)
{
if(ySectionPixel < (xSectionPixel * m))
{
hexGridCoord.x = xsection;
//hexGridCoord.y = ysection - 1;
hexGridCoord.y = ysection;
}
else
{
hexGridCoord.x = xsection - 1;
hexGridCoord.y = ysection;
}
}
}
return hexGridCoord;
}

I have no specific experience with the frameworks you use, but I do have a lot of experience with debuggers.
The debugger behavior you see can happen in one of two scenarios (that I can think of...)
The symbol files and executing code are not synchronized with your source code, usually the IDE should detect that, but it some cases it doesn't, the solution is to delete all binaries, recompile and try again.
A bug in the debugger or the debugger extension (used to debug in the specific environment your are in, i.e. unity/monodevelop).
If you are unable to resolve it, I would add logging to your code and use it to really understand what happens.

I saw similar behavior on MonoDevelop with WinForms applications, solved with reinstalling debugger.
Have you tried that or using Visual Studio to verify that the problem is in the code?

Do you have optimizations turned on? If so, does disabling them make stepping any less erratic?
Enabling optimizations is one thing I can think of that no one else has mentioned yet that could potentially cause what you are seeing.

Can you try removing you breakpoints, setting a new one, and stepping through the code?
The reason I ask is there are ways that you can set values using breakpoints. A very similar thing happened to me and was convinced that there was a compiler bug. After stepping through the CLR and number of other things with no answer, we stumbled across a breakpoint that was set earlier for testing, and never removed.

That kind of behavior usually happens to me when I'm debugging a multithreaded part of an application.
What happens is that while you debug several threads at once, the debugger in visual studio keeps switching between them without notifying you by default.
Now since threads are not executing the same lines at the same time, you got unexpected "jumps".
I believe it is widely used in game developpement, so in your case you got two choices:
1) Make only one thread run while you make your debugging.
2) Make unit tests <= That's the "best practice".
You can start by having a look at NUnit

The first issue most likely has something to do with the sequence points in the JITed code. These are the points where the debugger can stop. They're computed by the runtime based on the IL and debug symbols generated by the compiler, therefore this is most likely a runtime or compiler bug. I don't know what version of the Mono runtime and compiler is being used by Unity, but it's quite that this has been fixed in a newer version. If you can reproduce this using a "normal" console app using the latest official MonoDevelop and Mono 2.10.x, please file a bug at http://bugzilla.xamarin.com with a test case. If not, please ask Unity to upgrade their version of Mono.
The second issue looks like an issue in MonoDevelop's expression resolver that's used to resolve the symbol under the mouse. This may have been fixed in a newer version of MonoDevelop - likewise, please try to repro with the official MonoDevelop 2.8.4, and file a bug if it's still an issue.

Related

Word Statusbar gets reset when I use range.Information

I have the following code (simplified to show the problem):
var wdApp = new Application();
var wdDoc = wdApp.Documents.Open("C:\foo.docx");
wdApp.StatusBar = "Updating...";
var rng = wdDoc.Range(10, 10);
if ((bool)rng.Information(WdInformation.wdWithInTable))
{
}
//StatusBar value is gone...
What could be the reason?
How can I prevent it?
Do you know of other situations where this can happen?
Here screenshots of the problem
1 F10 (step over) later
Edit:
The provided code uses NetOffice and not the interop library from Microsoft directly, therefor the syntax is correct. You may notice in the provided screenshots that they are taken from a running application. Breakpoint, highlighting of current line of code executing, aswell as the actual result of the code in the word application on the right. Where at first there is the desired statusbar "Tabelle 8 von 17 wird neu erstellt." (Table 8 out of 17 is recreating) and at the next step my statusbar is gone and its the default stuff "165 von 8227 Wörtern" (165 out of 8227 words)
What could be the reason?
I believe this is to do with the library you are using. I tested your code but with the Word Interop library, and the only way I could get the status bar to reset was to manually click/type within the Word window.
How can I prevent it?
I would say take a look into the code base of library you are using. It is likely that it is doing something that is causing the behaviour. Unless there is a specific reason you are using NetOffice I would suggest switching to the either the standard Interop or VSTO.
Do you know of other situations where this can happen?
As above, I could only get the status bar to reset if I manually carried out some sort of input into the window.

Saving Modules correctly using Access-Interop

Even though my last questions weren't accepted well, I will give it another try.
I'm working on a program that is capable of controlling a lot of office-application behaviour by using the COM/Interop-Interface Microsoft provided for Word/Access/Excel. Still some functions differ from each other in the way that they are kept specific for the program that gets addressed.
My ambition is to Insert Macro-Code to an existing Access-Database and run the code while the Database is open and delete the code before the Database closes down. Partially this works as wished by using following C# code:
VBProject found = null;
Access.Application currApplication = this._currentInstance.Application;
if (target.Equals("") || scriptText.Equals(""))
return false;
foreach (VBProject vb in currApplication.VBE.VBProjects)
{
if (currApplication.CurrentDb().Name.Equals(vb.FileName))
{
found = vb;
break;
}
}
if (found != null)
{
foreach (VBComponent foundComponent in found.VBComponents)
{
if (foundComponent.Name.Equals(target))
{
return true;
}
}
VBComponent module = found.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule);
module.Name = target;
module.CodeModule.AddFromString(scriptText);
return true;
}
else
{
return false;
}
Now in particular, Access makes a diversion between VBA-Code-Modules which are visible in the Code-Editor and Modules which are loaded into the Database itself. For inserting the Module into the Database, it needs to be saved another time. When using the GUI, there's a window that popsup and asks for the Name to be used when saving it into the DB. It already takes the correct one etc. and it's fine after doing it by hand.
Besides the manual solution I found no way to do this step programatically.
Initial thoughts were:
currApplication.DoCmd.OpenModule(target, Type.Missing);
currApplication.DoCmd.Save(Access.AcObjectType.acMacro, target);
or
found.VBE.ActiveVBProject.SaveAs("");
The only two methods I could imagine would be doing the step I wanted. VBE in it's new .NET compatible form is documented very bad. Methods that would have applied to the native version are not guilty anymore. So I'm stuck with it now.
In case someone asks, why would you save the module at all, because once it's inserted in VBE it can be run like any other module listed in Access also, that's true, but for some unknown reasons this seems to be more fault-prone then to save it twice. Got runtime errors (like 2501) while launching the macro, which is not the case when it's saved properly.
Keeping it forever in the Access-Databases would be the last option but since those are many MDBs and thus they are changing frequently, I thought it would be nice to have it dynamic.
Hope somebody understands what I wrote here, (not so easy for me), and is enabled to help somehow :)
Thanks for all the reading. Looking forward for some good results, from the best community, hehe.

emgu FindContours fails in debug build

I have some Emgu code that was working in both debug and release builds. Somewhere along the way, it quit working, but I was deep into adding something else so I didn't pursue it at the time.
When I did finally getting around to trying to fix it, I find that a release build works, but not a debug build. Between the time it was working, and not, I did not change any references or referenced DLLs. I spent some time investigating that anyhow as I had read somewhere that open CV has some trouble debug vs release somewhere, but never found anything.
I just applied the last version of Emgu, and the same problem exists; works perfect in release, not at all in debug.
The relevant code snippet is;
var filteredFrame =
channels[0].SmoothGaussian(VisionData.SmoothGaussians)
.Erode(VisionData.Erodes)
.Dilate(VisionData.Dialates);
using (MemStorage stor = new MemStorage())
for (
Contour<System.Drawing.Point> contour =
filteredFrame.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL, stor);
contour != null;
contour = contour.HNext)
if ((contour.Area > (VisionData.ContourMinArea * VisionData.ContourMinArea))
&& (contour.Area < (VisionData.ContourMaxArea * VisionData.ContourMaxArea)))
CurrentFrame.Draw(contour.GetMinAreaRect(), RectBrush, 2);
d.InvokeAsync(() =>
{
DataModel.CameraImageSource = Emgu.CV.WPF.BitmapSourceConvert.ToBitmapSource(CurrentFrame);
DataModel.FilteredImageSource = Emgu.CV.WPF.BitmapSourceConvert.ToBitmapSource(filteredFrame);
});
The input filtered frame(image) looks identical in both debug and release.

Application changes not taking effect

I have made a change to a method used in a Functiod in a mapping file but it seems the new code is not taking effect, ever.
I have deployed properly, started the application, restarted related host instance (actually all host instances I could find) and still, the old code seems to execute.
Here's the, simple, method:
public string RemoveNonNumericChars(string stIn, int maxLength)
{
string strOut;
try
{
strOut = Regex.Replace(stIn, "[^0-9]", "");
System.Diagnostics.EventLog.WriteEntry("BizTalk Server 2009", strOut);
return strOut.Substring(0, maxLength);
}
catch
{
return string.Empty;
}
}
I added the writing to EventLog line to see that this code is indeed being executed, but I don't get anything in "Application" event logs.
I do NOT get an empty string being returned, so it really does seem like the old code that's being executed prior to me fixing the method.
What am I missing exactly ?
Thank you.
For some reason, the script is not able to correctly retrieve the Build Config selected in Visual Studio, it's taken from Debug when I'm actually trying to build it for a Test environment. I should have known, thanks anyways.

C# - Load existing system environment variables when the current process don't have them loaded

On Windows, I have a C# assembly that is COM visible. It references other assemblies to control an application in the machine. It works fine.
However, under Apache Web Server and using CGI, it doesn't work. After doing some debuging, I found out that the problem is that, while running under Apache's CGI, the environment variables SYSTEMROOT and SYSTEMDRIVE, which aparently are needed by the referenced assemblies, are not loaded.
I can configure Apache to pass those environemtn variables too, but before doing so, I'd really like to know if there's some command I can put on my C# COM visible assembly to make it load environment variables as if it was, let's say, the SYSTEM user or something like that, so it doesn't have to relay on the environment passed by the starting application.
How do you force loading an existent system environment variable in C#, when IT IS NOT SET in the current process (or it was process-deleted by the launching process)?
Thanks in advance for any suggestions!
EDIT 1 - ADDED INFO: Just to make it more clear (as I see in the current answers it's not so clear): Apache intendedly deletes a lot of environment variables for CGI processes. It's not that Apache cannot see them, it can, but it won't pass them to CGI processes.
This should do the trick:
Environment.GetEnvironmentVariable("variable", EnvironmentVariableTarget.Machine);
I did a small test and it is working:
//has the value
string a = Environment.GetEnvironmentVariable("TMP");
Environment.SetEnvironmentVariable("TMP", null);
//does not have has the value
a = Environment.GetEnvironmentVariable("TMP");
//has the value
a = Environment.GetEnvironmentVariable("TMP", EnvironmentVariableTarget.Machine);
SOLUTION: Marco's answer was great and technically answered my question - except that I found out that the environment variables SYSTEMROOT and SYSTEMDRIVE are not really set in the registry where all environment variables are set, so, the chosen answer works for all variables except those two, which I specified in the OP.
SYSTEMROOT is defined on the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot, and apparently (after more research), SYSTEMDRIVE is generated as a substring of SYSTEMDRIVE.
So, to get SYSTEMDRIVE and SYSTEMROOT from registry and load them into the environment:
using Microsoft.Win32;
namespace MySpace
{
public class Setup
{
public Setup()
{
SetUpEnvironment();
}
private void SetUpEnvironment()
{
string test_a = Environment.GetEnvironmentVariable("SYSTEMDRIVE", EnvironmentVariableTarget.Process);
string test_b = Environment.GetEnvironmentVariable("SYSTEMROOT", EnvironmentVariableTarget.Process);
if (test_a == null || test_a.Length == 0 || test_b == null || test_b.Length == 0)
{
string RegistryPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
string SYSTEMROOT = (string) Registry.GetValue(RegistryPath, "SystemRoot", null);
if (SYSTEMROOT == null)
{
throw new System.ApplicationException("Cannot access registry key " + RegistryPath);
}
string SYSTEMDRIVE = SYSTEMROOT.Substring(0, SYSTEMROOT.IndexOf(':') + 1);
Environment.SetEnvironmentVariable("SYSTEMROOT", SYSTEMROOT, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("SYSTEMDRIVE", SYSTEMDRIVE, EnvironmentVariableTarget.Process);
}
}
}
}
Then you can just call Setup setup = new Setup(); from other classes. And that's it. :-)
Environment.GetEnvironmentVariable
see reference here.
e.g.
Environment.CurrentDirectory = Environment.GetEnvironmentVariable("windir");
DirectoryInfo info = new DirectoryInfo(".");
lock(info)
{
Console.WriteLine("Directory Info: "+info.FullName);
}
Are the variables set as system wide?
If they are not, that is what you need to do, otherwise create user variables for the user the COM is running under.
Thank you. I cannot state with any certainty that this has once and for all driven a stake through the heart of the vampire, but amazingly enough, the error has disappeared (for now). The odd thing is that access to the statement
Environment.GetEnvironmentVariable("variable", EnvironmentVariableTarget.Machine);
is a real oddity in the debugger. It does not show up in Intellisense and does not even appear to fire, which leads me to suspect, which you all knew already, that this is some sort of magic runtime object Environment that has no instantiation in the debugger but also can be benignly jumped over. Oh well.
Oh and I should mention that after you see that error, you will note oddities in your Windows OS, which is worrisome. In particular, you will see, if you try to use the Control Panel /System/Advanced Properties (whatever) that it cannot load the dialog for the environment variables any more, indicating that %windir% has been seriously hosed (compromised) across all applications. Bad bad bad....

Categories

Resources