У нас есть служба, которая будет регистрировать необработанные исключения на уровне домена приложения (через Log4net).исключение без трассировки стека - как?
Мы вошли:
2014-01-28 16: 49: 19636 ОШИБКА [49] FeedWrapperService - необработанное System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
В этом исключении отсутствует трассировка стека. Как это возможно без каких-либо сумасшедших вещей для объекта исключения?
Наш код обработки:
AppDomain.CurrentDomain.UnhandledException += LogAnyExceptions;
private void LogAnyExceptions(object sender, UnhandledExceptionEventArgs e)
{
log.Error("unhandled", (Exception)e.ExceptionObject);
throw (Exception)e.ExceptionObject;
}
Это происходит со мной, что повторный бросок здесь бессмысленно, потому что AppDomain сойдет вместе с процессом так или иначе, но я не думаю, что это влияет на нашу ситуацию.
Средство просмотра событий приложения Windows также показывает только это исключение null ref и отсутствие следа.
Я проверил регистрацию обработчика исключений и успешно выполнил протоколирование трассировки стека и любого внутреннего исключения. Если бы он был брошен нашим кодом, мы увидели бы трассировку стека. Если он был брошен третьей библиотекой C#, то снова мы увидим трассировку стека хотя бы одного метода (будь то повторное исключение или нет). Здесь мы видим управляемое исключение без трассировки стека. Я не знаю, как это возможно.
Рассматривая декомпилированную стороннюю библиотеку, он разговаривает с неуправляемым кодом, и событие, вызвавшее это исключение, вероятно, находится на неуправляемой земле, но как могла такая ситуация вызвать исключение с помощью null null без stacktrace?
Причина этой проблемы является прерывистой. Мы запускаем этот код в производстве в течение нескольких месяцев и видим, как он это делает. Это довольно причудливо.
Генеральный консенсус в том, что система, ответственная за эту проблему, должна быть отброшена в дочерний процесс, чтобы мы могли решить проблему и перезапустить ее безопасно и автоматически, но было бы неплохо узнать, что происходит.
Редактировать включить комментарий снизу:
Мое исключение не является стандартным повторно бросить, потому что трассировка стека либо нулевым или пустым. В нем нет имени метода повторного броска. Копаясь дальше, класс Exception может быть построен из сериализованной информации, и похоже, что сериализованная информация может содержать пустые строки для трассировки стека и потенциально может быть создана без возникновения других ошибок. Я думаю, это может произойти оттуда, но я не знаю, как это произошло.
[Эта нить] (http://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace) может помочь – Andrei
Finger poking: попытайтесь проверить ['Environment.StackTrace'] (http://msdn.microsoft.com/en-us/library/system.environment.stacktrace.aspx) и, возможно, внутреннее исключение? – Sinatr
@ Аndrei это интересное чтение, но у моего исключения нет даже одного метода в его трассировке стека, который я бы имел, если бы это был обычный повторный бросок. Далее, класс Exception может быть построен из сериализованной информации, и похоже, что сериализованная информация может содержать нулевые строки для трассировки стека без возникновения ошибок. Я думаю, это может произойти оттуда, но я не знаю, как это произошло. – Skym