Вы могли бы попробовать ленивое размонтирование:
umount -l
Хорошо, теперь я понимаю, к чему вы клоните ... Извините за путаницу с встраиванием.
«Стек» в перехваченном исключении - это только дельта от текущего выполняемого блока перехвата до места, где было сгенерировано исключение. Концептуально такое поведение является правильным, поскольку Exception.StackTrack сообщает вам, где возникло исключение в контексте этого блока try / catch. Это позволяет пересылать стеки исключений через «виртуальные» вызовы, сохраняя при этом точность. Классическим примером этого являются исключения .Net Remoting.
Таким образом, если вам нужен полный отчет о стеке в блоке catch, вы должны добавить текущий стек в стек исключения, как в примере ниже. Единственная проблема в том, что это может быть дороже.
private void InternalMethod()
{
try
{
ThrowSomething();
}
catch (Exception ex)
{
StackTrace currentStack = new StackTrace(1, true);
StackTrace exceptionStack = new StackTrace(ex, true);
string fullStackMessage = exceptionStack.ToString() + currentStack.ToString();
}
}
Как сказал csharptest, это сделано специально. StackTrace останавливается на блоке попытки. Более того, в структуре нет перехватчика, который вызывается при возникновении исключения.
Лучшее, что вы можете сделать, - это что-то в этом роде, это абсолютное требование для получения трассировки полного стека (сохранение полной трассировки при создании исключений):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace ConsoleApplication15 {
[global::System.Serializable]
public class SuperException : Exception {
private void SaveStack() {
fullTrace = Environment.StackTrace;
}
public SuperException() { SaveStack(); }
public SuperException(string message) : base(message) { SaveStack(); }
public SuperException(string message, Exception inner) : base(message, inner) { SaveStack(); }
protected SuperException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
private string fullTrace;
public override string StackTrace {
get {
return fullTrace;
}
}
}
class Program {
public void ExternalMethod() {
InternalMethod();
}
public void InternalMethod() {
try {
ThrowIt();
} catch (Exception ex) {
Console.WriteLine(ex.StackTrace);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void ThrowIt() {
throw new SuperException();
}
static void Main(string[] args) {
new Program().ExternalMethod();
Console.ReadKey();
}
}
}
Выводы:
at System.Environment.get_StackTrace() at ConsoleApplication15.SuperException..ctor() in C:\Users\sam\Desktop\Source \ConsoleApplication15\ConsoleApplication15\Program.cs:line 17 at ConsoleApplication15.Program.ThrowIt() in C:\Users\sam\Desktop\Source\Cons oleApplication15\ConsoleApplication15\Program.cs:line 49 at ConsoleApplication15.Program.InternalMethod() in C:\Users\sam\Desktop\Sour ce\ConsoleApplication15\ConsoleApplication15\Program.cs:line 41 at ConsoleApplication15.Program.Main(String[] args) in C:\Users\sam\Desktop\S ource\ConsoleApplication15\ConsoleApplication15\Program.cs:line 55 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C ontextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
Невозможно ввести это поведение в существующие исключения, определенные Системой, но .Net имеет богатую инфраструктуру для упаковки исключений и повторного создания, поэтому это не должно быть огромной проблемой.
Я знаю, что в блоке catch, если вы выполняете throw ex;
, он усекает трассировку стека в этой точке. Возможно, что это сделано «намеренно» для throw, поскольку просто throw;
не усекает стек в catch. То же самое может происходить здесь, поскольку вы генерируете новое исключение.
Что произойдет, если вы вызовете фактическое исключение (например, int i = 100/0;
)? Трассировка стека все еще усечена?
Это часто вызвано оптимизацией компилятора.
Вы можете украсить методы, которые не хотите встраивать, используя следующий атрибут:
[MethodImpl(MethodImplOptions.NoInlining)]
public void ExternalMethod()
{
InternalMethod();
}