I'm developing C# application for windows phone 8.1 (Silverlight). Lately I've came across the problem connected to application falling asleep and storyboards.
The construction goes as follows:
class X : DependencyObject
{
public static readonly DependencyProperty vProperty =
DependencyProperty.Register("v", typeof(double), typeof(X), new PropertyMetadata(0.0));
public double v
{
get
{
return (double)GetValue(vProperty);
}
set
{
SetValue(vProperty, value);
}
}
private Storyboard _storyboard;
void Prepare()
{
_storyboard = new Storyboard();
var animation= new DoubleAnimation
{
From = 0,
To = 1,
BeginTime = 0,
Duration = 0,
};
_storyboard.Children.Add(animation);
Storyboard.SetTarget(animation, this);
Storyboard.SetTargetProperty(animation, vProperty);
}
void Go()
{
_storyboard.Begin();
}
}
There is a NullReferenceException thrown from inside of _storyboard.Begin() if application is placed in background between "Prepare" and "Go" (about 10% reproduction rate). Of course it ends up with crash.
I was not able to determine problem source and as I need quickfix for that I've decided to just catch this NullRefereneceException in this rare scenario. This is where real question starts. I've changed "Go" implementation to:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (NullReferenceException)
{
Debug.WriteLine("BreakPoint 2");
}
}
Afterwards the crash is not reproducible at all, but the problem is that "BreakPoint 2" is never hit (no printout in Output either). "BreakPoint 1" is normally hit and printed as well. Changing NullReferenceException to other Exception type (not parent type ofc) causes crash to reappear.
So... What's going on here? Is this crash cached or not? What kind of weird behavior is that? Is it safe to assume that it will work as expected?
Additional question: Maybe you know why the original code crashes in the first place?
EDIT:
End of stack trace of internalException of TargetInvocationExceptions looks as follows:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.Storyboard_Begin(Storyboard storyboard)
at System.Windows.Media.Animation.Storyboard.Begin()
at X.Go()
I know that you've said that you've tried to use parent types for NullReferenceException, but please try the following without running in the debugger:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (Exception)
{
Debug.WriteLine("BreakPoint 2");
System.Diagnostics.Debugger.Break();
}
}
My suspicion is that the catch is not firing because you are running from within the debugger. Also try System.Diagnostics.Debugger.Launch(); in the catch if .Break(); does not work. And finally also try throw; in the catch if .Launch(); does not work.
If the debugger attempts to launch in either case, then you have another clue.
UPDATE:
I can't give you all of the reasons why this might happen as it may not be possible to determine precisely what is causing it in your situation.
I've seen behavior like this due to use of multithreading. Multithreading can behave differently when running with a debugger attached then without. Timing issues and race conditions can prevent exceptions from being thrown while in the debugger that otherwise may occur frequently when there is no debugger attached.
I've also encountered instances where System.Diagnostics.Debugger.IsAttached was used in third party code and even my team's code which caused the application to behave differently based on if statements using this check.
And lastly, I've had times where I could not come up with a specific reason why the behavior was occurring. I've learned to use the System.Diagnostics.Debugger.Break() method whenever I see behavior exhibited differently depending on whether a debugger is attached or not. Sometimes it really is just a gut feeling.
Related
I have a small program in C# that loads the R.Net library to outsource some calculations that I can't do in c#, namely the Twitter anomaly detection library. Unfortunately, when the code finishes the console window it runs in hangs. If I run it in debug, code execution seems to be error free, so I suspect it's something to do with cleanup of the REngine as I (eventually) get an error as per this image.
After which I'll get another pop up from VS stating "Debugging is stopped but is not yet complete, either force it to stop by pressing this button or continue to wait".
Code is approximately as follows:
class SHESD_Test
{
private static REngine engine;
internal SHESD_Test(IEnumerable<Double> d)
{
try
{
if(engine==null)
{
engine = REngine.GetInstance();
engine.Initialize();
engine.Evaluate("library(AnomalyDetection)"); //Loads Twitter library
}
var dInR = engine.CreateNumericVector(d.toArray());
engine.SetSymbol("data", dInR);
var outVar = engine.Evaluate("outVar <- AnomalyDetectionVec(data, max_anoms=0.02, direction='both', plot=FALSE, period=96)");
/* Some other stuff that grabs data out of outVar in R and stores in member variables */
}
catch (Exception e)
{ /* Log error */ }
}
//Called from elsewhere once everything is complete, but behaviour is the same if I don't call it
internal static void cleanup()
{
engine.ForceGarbageCollection();
engine.Dispose();
engine == null;
}
}
Googling the error code, it looks like a timeout has expired, but for the life of me I can't figure out why.
The code itself executes fine, it's only in the exit from main(), and not the bit where the REngine falls out of scope, so perhaps in garbage collection things are going awry?
Digging further, the root cause is in the library function generating a plot window in it's return value, even when told not to. Their code is:
# Lastly, return anoms and optionally the plot if requested by the user
if(plot){
return (list(anoms = anoms, plot = xgraph))
} else {
return (list(anoms = anoms, ***plot = plot.new()***)) # <-Looky here!
}
Adding to my code the following line when I'm done with the engine:
engine.Evaluate("graphics.off()");
closes the strange empty window, which doesn't seem to be able to be closed by either the ForceGarbageCollection or Dispose methods - probably leaving things hanging about waiting for something that will never happen, and thus triggering this timeout exception window.
Recently, I was running into a problem which I'm still breaking my head over. In an application, I registered a dispatcher exception handler. In the same application, a third-party-component (DevExpress Grid Control) causes an exception within the event handler for Control.LayoutUpdated. I expect, that the dispatcher exception handler is triggered once. But instead, I get a stack overflow. I produced a sample without the third party component and discovered, that it happens in every WPF application.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace MyApplication
{
/* App.xaml
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApplication.App"
Startup="OnStartup"
/>
*/
public partial class App
{
private void OnStartup(object sender, StartupEventArgs e)
{
DispatcherUnhandledException += OnDispatcherUnhandledException;
MainWindow = new MainWindow();
MainWindow.Show();
}
private static void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
e.Handled = true;
}
}
public class MainWindow : Window
{
private readonly Control mControl;
public MainWindow()
{
var grid = new Grid();
var button = new Button();
button.Content = "Crash!";
button.HorizontalAlignment = HorizontalAlignment.Center;
button.VerticalAlignment = VerticalAlignment.Center;
button.Click += OnButtonClick;
mControl = new Control();
grid.Children.Add(mControl);
grid.Children.Add(button);
Content = grid;
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
mControl.LayoutUpdated += ThrowException;
mControl.UpdateLayout();
mControl.LayoutUpdated -= ThrowException;
}
private void ThrowException(object sender, EventArgs e)
{
throw new NotSupportedException();
}
}
}
Is there any way to prevent this behavior? It happens with .NET framework 3.0, 3.5, 4.0 and 4.5. I can't just wrap a try-catch around the LayoutUpdated event handler since it is in a third party component and I don't think, a stack overflow should happen.
I think Florian GI is right about the message box, but if instead of a message box you did something else (or nothing i.e. just set Handled to true) in the OnDispatcherUnhandledException method it still loops forever and doesn't get to the mControl.LayoutUpdated -= ThrowException; line.
So I thought I would have a little snop through the code with dotPeek...
When you call UpdateLayout on the control, ultimately it gets to the method ContextLayoutManager.UpdateLayout and a snippet of this method looks like this:
// ... some code I snipped
bool flag2 = true;
UIElement element = (UIElement) null;
try
{
this.invalidateTreeIfRecovering();
while (this.hasDirtiness || this._firePostLayoutEvents)
{
//... Loads of code that I think will make sure
// hasDirtiness is false (since there is no reason
// for anything remaining dirty - also the event is
// raised so I think this is a safe assumption
if (!this.hasDirtiness)
{
this.fireLayoutUpdateEvent();
if (!this.hasDirtiness)
{
this.fireAutomationEvents();
if (!this.hasDirtiness)
this.fireSizeChangedEvents();
}
}
//... a bit more
flag2 = false;
}
}
finally
{
this._isUpdating = false;
this._layoutRequestPosted = false;
//... some more code
if (flag2)
{
//... some code that I can't be bothered to grok
this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Delegate) ContextLayoutManager._updateLayoutBackground, (object) this);
}
}
// ... and for good measure a smidge more code
I'm going to take a punt and suggest that the _firePostLayoutEvents flag is true in your case.
The only place where _firePostLayoutEvents is set to false is in the fireAutomationEvents method so let's assume that somewhere before the end of the fireAutomationEvents method your exception is thrown (I would guess the fireLayoutUpdateEvent method) so this flag will not get set to false.
But, of course, the finally is outside the loop so it will not loop forever (and if it did you'd not get a StackOverflowException).
Right, onward, so we are invoking the UpdateLayoutBackground function, which actually just calls NeedsRecalc so let's look at that...
private void NeedsRecalc()
{
if (this._layoutRequestPosted || this._isUpdating)
return;
MediaContext.From(this.Dispatcher).BeginInvokeOnRender(ContextLayoutManager._updateCallback, (object) this);
this._layoutRequestPosted = true;
}
Rightyho, that is calling the UpdateLayoutCallback so squinting at that...
private static object UpdateLayoutCallback(object arg)
{
ContextLayoutManager contextLayoutManager = arg as ContextLayoutManager;
if (contextLayoutManager != null)
contextLayoutManager.UpdateLayout();
return (object) null;
}
Oooooh, that is interesting - it's calling UpdateLayout again - I would, therefore, hazzard a slightly educated guess that that is the root cause of your problem.
Therefore, I don't think there is anything much you can do about it I am afraid.
I am not quite sure about the following, but maybe it's a guess in the right direction.
In MSDN it sais:
However, LayoutUpdated can also occur at run time during the object
lifetime, for a variety of reasons: a property change, a window
resizing, or an explicit request (UpdateLayout or ApplyTemplate).
So it might get also fired after a MessageBox has shown?
If thats the case a MessageBox would open through an unhandled exception, which fires the LayoutUpdated-EventHandler and this again raises an unhandled exception. This would lead to an endless loop and after a while to the stack overflow.
If you do not throw an unhandled exception in the LayoutUpdated-EventHandler, but call the MessageBox.Show()-method it also ends in an endless loop, what would proof my point.
I realize I'm over four years late to the party, but maybe someone will find this useful...
Your application's dispatcher does not stop responding to input and layout events during the call to MessageBox.Show(). The LayoutUpdated event fires any time there is any layout-related work to do, which happens far more often than you might expect. It will continue to fire while the message box is displayed, and if whatever condition triggered the error continues to persist, new exceptions will be raised, and your handler will show more and more message boxes. And because MessageBox.Show() is a blocking call, it's not going to disappear from the call stack until it returns. Subsequent invocations of your handler will be pushed deeper and deeper into the dispatcher's call stack until it overflows.
You really have two separate problems:
Your code to display a crash dialog is reentrant.
Your application continues to raise exceptions on the dispatcher thread while your crash dialog is being displayed.
You could solve the first issue with a non-reentrant queue. Rather than displaying the crash dialog immediately, have your handler place the exception in a queue. Have your handler process the queue only if you are not already processing it farther up the stack. This prevents multiple crash dialogs from being shown simultaneously, and should keep your call stack from growing too deep, thus avoiding your stack overflow issue.
To address the second problem, you should probably shut down the offending part of your application as soon as you see the first exception (and before you show the crash dialog). Alternatively, you could devise a way to filter out duplicate exceptions and ensure that equivalent errors don't end up in the queue at the same time. But given how rapidly the exceptions are recurring, I would choose the first option.
Keep in mind that you need to address both of these issues. If you don't address the second issue, you'll likely end up trading in your StackOverflowException for an OutOfMemoryException. Or you'll show an infinite number of crash dialogs, one after the other. Either way, it'll be bad.
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?