Our Application is moving some files it requires to run during startup.
The application takes care (on shutdown) to properly stop every process using this files.
However, if the application crashes / or you just hit "stop" in VS on Debugging - some executables might still be running.
So, if you quickly restart the application, it might happen, that the copy-attempt is failing, due to the file is still in use.
For such a case, we just ignore the failed copy attempt - or more exactly: the failed deletion attempt which should make sure, that the latest version is available:
foreach(String entry in contents)
{
if (System.IO.File.Exists(entry))
{
try
{
System.IO.File.Delete(entry);
}catch (Exception e)
{
//ignore during this startup.
}
}
}
Now, this works perfectly fine, as there is a version of the file available for usage and the production version just ignores the exception.
The annoying Problem is, that the Debugger "breaks" everytime, this error happens.
We don't want to generally "ignore" any System.IO.IOException thrown while debugging.
We tried to annotate the method in Question with [System.Diagnostics.DebuggerStepThrough()] which works, but causes the exception to be catched at the callers position.
So, is there a way to ignore "some" exceptions raised at a certain line of code, even if general "breaking" for that kind is enabled?
Some #if (DEBUG)-Directives which will avoid the exception to be catched at this particular line of code?
Something like:
foreach(String entry in contents)
{
if (System.IO.File.Exists(entry))
{
try
{
#if (DEBUG:NoThrow)
System.IO.File.Delete(entry);
#endif
}catch (Exception e)
{
//ignore during this startup.
}
}
}
I'm still interested in an answer, cause it has "many" usecases.
For the time beeing, we used the following "workaround": Check, if the file has been accessed withing 3 minutes - then don't attempt to delete it.
(For DEBUG-Mode!)
Remember, the actual issue is only about the "debugger", not production, where Exceptions can be caught (and ignored) easily for a certain line of code.
We just want to avoid "Debugger-Breaks" kicking in if the exception can savely be ignored AT THIS line of code.
foreach (String entry in contents)
{
if (System.IO.File.Exists(entry))
{
try {
#if (DEBUG)
FileInfo fi = new FileInfo(entry);
if (fi.LastAccessTime < DateTime.Now.AddMinutes(-3))
{
#endif
System.IO.File.Delete(entry);
#if (DEBUG)
}
#endif
}
catch (Exception e)
{
//ignore
}
}
}
This is NOT a solution, it's a workaround, reducing the Debugger-Breaks at this line of code by about 99%, in case you just "Stop" Debuggin within Visual Studio!
Related
This application has a WCF web service that is called by a WinForms app. The WinForms app has a class WCFCache to manage data from the service. There is a section like this in that class to manage an optional custom configuration section that a subset of the machines have:
private bool? m_HasCustomConfiguration = null;
public bool HasCustomConfiguration
{
get
{
if (m_HasCustomConfiguration == null)
m_HasCustomConfiguration = (CustomConfiguration != null);
return (bool)m_HasCustomConfiguration;
}
}
private WCFService.CustomConfiguration m_CustomConfiguration = null;
public WCFService.CustomConfiguration CustomConfiguration
{
get
{
if (m_CustomConfiguration == null)
{
if (m_HasCustomConfiguration.HasValue
&& !m_HasCustomConfiguration.Value)
return null;
try
{
using (WCFService.WCFServiceClient wcf = new WCFService.WCFServiceClient())
{
m_CustomConfiguration =
wcf.GetCustomConfiguration(Machine.ProcessID);
// Above method returns null if no record exists.
m_HasCustomConfiguration = (m_CustomConfiguration != null);
}
} catch (Exception e) {
// Error logging & re-throw
}
}
return m_CustomConfiguration;
}
}
When I step through the debugger in code that calls either of the above properties like this:
if (!Program.WCFCache.HasCustomConfiguration)
return new List<CustomComponents>();
...it throws the following exception:
System.AccessViolationException was unhandled
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Source="System.Windows.Forms"
...
When I step onto the line containing the reference, there is a long pause, followed by a VS popup with the exception.
The exception doesn't appear when I just put a breakpoint after the above code has executed. It doesn't even appear when I put a breakpoint inside the accessors of the properties. It only occurs when I step onto a line with one of those properties from the outside. (So there is a workaround, but it can be a pain.)
Why is this happening? Can I stop it?
Edit: The whole application was written in the last year in 3.5 C#/.NET with WCF communicating between components; meaning, we don't have legacy unmanaged DLLs. Just two unmanaged calls: one to advapi32.dll when the WinForms app is loading, in the username detection procedure. The issue I'm having happens only in this one place in the code, in a place that is about as unrelated to the login section as you can get. The other is to kernel32.dll, in a GC force-flush long after anything is done with the results from calls like the one above.
Are you using any P/Invoke or other such native code? Odds are, that's where you should start looking.
This exception is a symptom of a larger problem, namely memory corruption (that what the exception says, after all). If this was a native application, you'd get a crash.
So, look at any native calls, make sure they're operating correctly, maybe run them under a debugger to try and trap the error closer to home.
Sorry, can't really give better advice given the circumstances.
I eventually found that others have encountered this situation and that it is likely a Visual Studio bug. I was using VS 2008 when the problem occurred.
I'm facing an issue which I can't seem to wrap my head around.
private void IndexEntityType(Type targetType, bool onlyNew)
{
Logger.Debug("generating index for {0}", targetType);
using (var wrapper = SessionWrapper.For(targetType, true))
{
var session = wrapper.Session;
session.FlushMode = FlushMode.Never;
session.CacheMode = CacheMode.Ignore;
var entities = GetEntities(targetType, onlyNew, session);
Logger.Debug("Indexing {0} entities", entities.Count);
// Create a Full Text session.
using (var fullTextSession = Search.CreateFullTextSession(session))
using (var transaction = fullTextSession.BeginTransaction())
{
fullTextSession.CacheMode = CacheMode.Ignore;
foreach (var entity in entities)
{
fullTextSession.Index(entity);
}
try
{
transaction.Commit();
}
catch (Exception ex)
{
Logger.Error("could not commit fulltext session transaction", ex);
}
}
Logger.Debug("generated index for {0}", targetType);
}
ReQueueTimers(onlyNew);
}
I'm trying to debug this and have set breakpoints at the first row (Logger.Debug) and the last row (ReQueueTimers).
However, when stepping through the code, the last call (ReQueueTimers(onlyNew)) is never invoked, nor hitting the breakpoint. How can that be? Does the compiler "remove it when optimizing" somehow?
Does anyone have any hint on what might trigger this behavior?
EDIT: This is run in multiple threads if that might have anything to do with it.
It could be that your code is throwing an exception - if anything other than the transaction.Commit() throws an exception, the ReQueueTimers call won't be made. You could prove this by getting Visual Studio to break on all CLR exceptions - in the Debug menu, select "Exceptions", and check the "Thrown" box on the "Common Language Runtime Exceptions" row. Then start debugging again.
On the other hand, I have sometimes had Visual Studio just give up stepping through code halfway through debugging a method. Maybe this is the cause - it might have something to do with multiple threads. If you remove the first breakpoint and leave the one on the ReQueueTimers call, does this make any difference?
As a little addition to what Graham said:
If you run on multiple threads and an exception is thrown on that thread and is not caught, the thread is aborted.
I had the very same issue from 2 days and banged my head dead until... I found this somewhere on the net:
Make sure that your target code actually builds when you build your solution/project. To do that, go to Build->Configuration Manager and make sure the corresponding project is checked (In the rightmost column).
Mind you, for some misterious reason that only Gates knows, the box was unchecked!
I have a fun issue where during application shutdown, try / catch blocks are being seemingly ignored in the stack.
I don't have a working test project (yet due to deadline, otherwise I'd totally try to repro this), but consider the following code snippet.
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
return Run(index);
}
catch(IndexNotFoundException e)
{
if(doThrow)
throw;
}
return "";
}
public static string Run(int index)
{
if(_store.Contains(index))
return _store[index];
throw new IndexNotFoundException ();
}
public static string RunAndIgnoreThrow(int index)
{
try
{
return Run(index);
}
catch(IndexNotFoundException e)
{
}
return "";
}
During runtime this pattern works famously. We get legacy support for code that relies on exceptions for program control (bad) and we get to move forward and slowly remove exceptions used for program control.
However, when shutting down our UI, we see an exception thrown from "Run" even though "doThrow" is false for ALL current uses of "RunAndPossiblyThrow". I've even gone so far as to verify this by modifying code to look like "RunAndIgnoreThrow" and I'll still get a crash post UI shutdown.
Mr. Eric Lippert, I read your blog daily, I'd sure love to hear it's some known bug and I'm not going crazy.
EDIT
This is multi-threaded, and I've verified all objects are not modified while being accessed
EDIT
Explicitly show exception is ours
EDIT
forgot to mention, this is on closing, and unfortunately visual studio cannot catch the crash directly. It's likely crashing on a thread other than the UI thread, and once the main closes, this closes. I've only been able to debug this by repeatedly running & closing the application, with task manager open, "Create Dump File" and looking at the resulting 400+mb mess in Windbg. Win7 64 for reference. Make sure this makes sense to you.
EDIT
The following code on shutdown still shows the same exception.
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
return Run(index);
}
catch
{
}
return "";
}
public static string Run(int index)
{
if(_store.Contains(index))
return _store[index];
throw new IndexNotFoundException ();
}
The only thing that seems to get rid of the exception is to go straight to
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
return Run(index);
}
catch
{
}
return "";
}
public static string Run(int index)
{
if(_store.Contains(index))
return _store[index];
return "";
}
Naturally the exception's gone, but my fears of going crazy are still present.
EDIT
it just got worse... this still crashes...
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
throw new IndexNotFoundException();
}
catch
{
}
return "";
}
EDIT
I have a distinct feeling this is going to get me nowhere. On top of the wierd behavior, I can also note that during execution of the UI in the above case, the try catch is being executed faithfully. My UI doesn't crash & it's full of empty strings. However once I start closing the UI, the crash shows itself and the try catch no longer holds back the exception.
EDIT & final
Apparently the dump file was listing in it the most recent first-chance exception. I verified this by creating a new project that threw inside a try catch & slept for 10 seconds. During the wait I got the .dmp file & sure enough, my completely caught exception was showing up.
I'll mark some points for the useful answers, however unfortunately there's still no rhyme or reason why my code is crashing...
Add an Exception as an extra catch. I think you are getting some other exception than ApplicationException and that is the one crashing your app.
There are various exceptions that cannot be caught. Stack Overflow in particular! Could one of these be occurring somewhere in your code?
See http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx
Have you tried adding a "finally" clause? just to see if it won't ignore the try/catch completely? In theory it should always jump to that line before it exits the try/catch no matter what.
If it still ignore that then there is something definitely strange about it.
Probably you catch and throw again some other exception from Run. Probably _store is null or something.
A few things that may help with diagnosis:
Register for AppDomain.CurrentDomain.UnhandledException so you can see if something is crashing on a thread other than the UI thread
Register for Application.ThreadException to catch any exceptions not being caught in the UI thread
Since this is happening during shutdown, are you using any Finalizers that could be throwing on the finalizer thread?
We have following code:
try
{
// some code throwing MyException
}
catch (MyException ex)
{
// [1]
// no (re)throw here
}
catch (Exception ex)
{
if (ex is MyException)
{
// [2]
}
}
If we run the code without a debugger attached, everything runs fine. However, if we debug the code, we don't get to point [1] but [2]. As far as I understand the language specification this should not be possible.
Even weirder, this code used to run fine even while debugging. The strange behavior started only a few days ago.
Depending on original sources, it may be related to this issue : Why can't I catch a generic exception in C#?
Check that you have done a full rebuild and are using the correct pdb files. Also check that you don't have some conditionally compiled code changing things (i.e. code between #if DEBUG statements).
I have some code which ignores a specific exception.
try
{
foreach (FileInfo fi in di.GetFiles())
{
collection.Add(fi.Name);
}
foreach (DirectoryInfo d in di.GetDirectories())
{
populateItems(collection, d);
}
}
catch (UnauthorizedAccessException ex)
{
//ignore and move onto next directory
}
of course this results in a compile time warning as ex is unused. Is there some standard accept noop which should be used to remove this warning?
Just rewrite it as
catch (UnauthorizedAccessException) {}
As Dave M. and tvanfosson said, you want to rewrite it as
catch (UnauthorizedAccessException) {}
The bigger question that should be asked, however, is why you are catching an exception on ignoring it (commonly called swallowing the exception)? This is generally a bad idea as it can (and usually does) hide problems in the application at runtime that can lead to very strange results and a difficult time debugging them.
I usually do
Debug.WriteLine(ex.message)
(that way I can just set a breakpoint in the exception, if needed, too)
Assuming the comment in your original code is an accurate description of what you're trying to do, I think you want to write it like this:
foreach (FileInfo fi in di.GetFiles())
{
//TODO: what exceptions should be handled here?
collection.Add(fi.Name);
}
// populate collection for each directory we have authorized access to
foreach (DirectoryInfo d in di.GetDirectories())
{
try
{
populateItems(collection, d);
}
catch (UnauthorizedAccessException)
{
//ignore and move onto next directory
}
}
And then you need to work on that TODO item.
I agree with the people who say it's probably a bad idea to simply ignore the exception. If you're not going to re-throw it then at the very least log it somewhere. I've written small tools that process a list of files where I didn't want errors on individual files to crash the whole program, and in such cases I would print a warning message so I could see which files were skipped.
The only time I personally ever catch an exception without naming it, as in catch(xxxException), is if I'm going to react to it in some way and then re-throw it so that I can catch it in some outer routine. E.g.:
try
{
// do something
// ...
}
catch(UnauthorizedAccessException)
{
// react to this exception in some way
// ...
// let _someone_ know the exception happened
throw;
}
Even though I'm a Java developer (not C#), #Scott Dorman is absolutely right. Why are you "swallowing the exception"? Better yet, what could throw the UnauthorizedAccessException? Here are common-sense possibilities:
The file doesn't exist
The directory doesn't exist
The current thread of control does not have the correct security privileges. In the *nix world, the current thread may be in the wrong group or the wrong user.
The disk crashed
The file's ACL is set to write only but not read. Likewise, for the directory.
The above of course is an incomplete list.