2014-01-31 8 views
13

Wir haben einen Dienst, der unbehandelte Ausnahmen auf der Ebene der App-Domäne protokolliert (über Log4net).Ausnahme ohne Stack-Trace - wie?

Wir protokolliert:

2014-01-28 16: 49: 19.636 ERROR [49] FeedWrapperService - unhandled System.NullReferenceException: Objektverweis auf eine Instanz eines Objekts eingestellt.

Diese Ausnahme hat keine Stack-Trace. Wie ist das möglich, ohne das Objekt Ausnahme zu verrücken?

Unser Umgang Code:

AppDomain.CurrentDomain.UnhandledException += LogAnyExceptions; 

private void LogAnyExceptions(object sender, UnhandledExceptionEventArgs e) 
{ 
    log.Error("unhandled", (Exception)e.ExceptionObject); 
    throw (Exception)e.ExceptionObject; 
} 

Es fällt mir, dass der Wiederwurf hier sinnlos ist, weil die AppDomain ohnehin zusammen mit dem Prozess kommen, aber ich glaube nicht, dass unsere Situation auswirkt.

Der Windows-Anwendungsereignis-Viewer zeigt auch nur diese null-ref-Ausnahme und keine Ablaufverfolgung.

Ich habe die Protokollierung der Ausnahmebehandlungsroutine getestet, und es protokolliert erfolgreich die Stack-Ablaufverfolgung und jede innere Ausnahme. Wenn es von unserem Code ausgelöst würde, würden wir einen Stack-Trace sehen. Wenn es von der C# -Bibliothek der dritten Partei ausgelöst wurde, würden wir wiederum eine Stapel-Ablaufverfolgung von mindestens einer Methode sehen (ob es sich um eine erneut geworfene Ausnahme handelte oder nicht). Hier sehen wir eine verwaltete Ausnahme ohne Stack-Trace. Ich weiß nicht, wie das möglich ist.

Mit Blick auf die dekompilierte 3rd-Party-Bibliothek spricht es mit nicht verwaltetem Code, und das Ereignis, das diese Ausnahme ausgelöst hat, ist wahrscheinlich in unmanaged Land, aber wie könnte eine solche Situation eine verwaltete Nullreferenz-Ausnahme ohne Stacktrace verursachen?

Die Ursache dieses Problems ist intermittierend. Wir haben diesen Code mehrere Monate in der Produktion laufen lassen und es einmal gesehen. Es ist ziemlich verrückt. Der allgemeine Konsens ist, dass das System, das für diese Art von Problem verantwortlich ist, in einen Kindprozess verschoben werden sollte, damit wir mit dem Problem umgehen und sicher und automatisch neu starten können, aber es wäre schön zu wissen, was vor sich geht.

bearbeiten schließen Kommentar Infos von unten:

Meine Ausnahme keinen Standard-Wiederwurf, weil der Stack-Trace entweder null oder leer ist. Es hat nicht den Namen der Methode zum erneuten Werfen. Wenn Sie weiterlesen, kann die Exception-Klasse aus serialisierten Informationen konstruiert werden, und es sieht so aus, als ob die serialisierten Informationen Null-Strings für die Stack-Trace enthalten könnten und möglicherweise erstellt werden könnten, ohne andere Fehler zu verursachen. Ich denke, es könnte von dort kommen, aber ich weiß nicht, woher es stammt.

+1

[Dieses Thema] (http://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace) – Andrei

+0

kann helfen Finger stochern: versuchen Sie zu überprüfen ['Environment.StackTrace'] (http://msdn.microsoft.com/en-us/library/system.environment.stacktrace.aspx) und vielleicht innere Ausnahme? – Sinatr

+0

@Andrei das ist eine interessante lesen, aber meine Ausnahme hat nicht einmal eine Methode in ihrem Stack-Trace, die ich hätte, wenn es ein normaler Re-Wurf wäre. Darüber hinaus kann die Exception-Klasse aus serialisierten Informationen erstellt werden, und es sieht so aus, als ob die serialisierten Informationen null Strings für Stack-Trace enthalten könnten, ohne Fehler zu verursachen. Ich denke, es könnte von dort kommen, aber ich weiß nicht, woher es stammt. – Skym

Antwort

9

Wenn Sie eine Ausnahme empfangen, aber keine entsprechende Stack-Trace, wird die Ausnahme wahrscheinlich von einem Exception-Handler ausgewertet und erneut falsch geworfen. Zum Beispiel, wenn Sie eine throw ex; machen, essen Sie die Stapelspur, die zu diesem Punkt führte.Zur Erhaltung Stapel des bestehenden Anrufs Sie wollen einfach throw; Throwing exceptions best practices

zu beachten, dass die C# Art und Weise das Gegenteil der Konvention für die Java-Sprache ist, wo Sie sollen auf throw ex; Java Referenz: Best Practice: Catching and re-throwing Java Exceptions

1

Ich bevorzuge Verwalten Sie meine Ausnahmen mit benutzerdefinierten Ausnahmen. Wenn Sie in Ihrem Fall eigene Ausnahmen verwenden, können Sie in die Klasse wechseln, in der Sie sie definiert haben, und den Stacktrace überschreiben. Beispiel:

public class YourCustomException: Exception 
{ 
    public YourCustomException() : base() { } //constructor 

    public override string StackTrace 
    { 
     get { return " at: my custom stack trace"; } 
    } 
} 
Verwandte Themen