浅析C++ StackTrace 堆栈轨迹

来源:互联网 发布:如何在淘宝投诉卖家 编辑:程序博客网 时间:2024/05/17 00:13
堆栈轨迹:如果你需要打印出某个时间的调用堆栈状态,你将产生一个堆栈轨迹。
stack trace 中包括三部分,分别为:.bss .text .data
bss: 表示程序中未初始化的全局变量的一块内存区域
text: 表示程序中已初始化的全局变量的一块内存区域
data:表示存放程序执行代码的一块内存区域

     我们在学习函数调用时,都知道每个函数都拥有自己的栈空间。一个函数被调用时,就创建一个新的栈空间。那么通过函数的嵌套调用最后就形成了一个函数调用堆栈。在c#中,使用StackTrace记录这个堆栈。你可以在程序运行过程中使用StackTrace得到当前堆栈的信息。

class Program
{
staticvoid Main(string[] args)
{
Program a =new Program();
a.FuncA();
Console.ReadLine();
}

int FuncA()
{
FuncB();
return 0;
}


privatevoid FuncB()
{
MethodInfo method0 = (MethodInfo)(new StackTrace().GetFrame(0).GetMethod());
MethodInfo method1 = (MethodInfo)(new StackTrace().GetFrame(1).GetMethod());
MethodInfo method2 = (MethodInfo)(new StackTrace().GetFrame(2).GetMethod());

Console.WriteLine("Current Method is : {0}",method0.Name);
Console.WriteLine("Parent Method is : {0}", method1.Name);
Console.WriteLine("GrandParent Method is : {0}", method2.Name);
}

}

程序的输出结果是:
Current Method is : FuncB
Parent Method is : FuncA
GrandParent Method is : Main

其中调用GetFrame得到栈空间,参数index 表示栈空间的级别,0表示当前栈空间,1表示上一级的栈空间,依次类推。
除了可以获取方法信息外,还可以调用StackFrame类的成员函数,在运行时得到代码的文件信息及行号和列号等。详情可以参考msdn上的一个example


下面的代码示例引发一个 Exception,然后捕捉该异常,并使用StackTrace 属性显示堆栈跟踪

// Example for the Exception::HelpLink, Exception::Source,// Exception::StackTrace, and Exception::TargetSite properties.using namespace System;namespace NDP_UE_CPP{   // Derive an exception; the constructor sets the HelpLink and    // Source properties.   public ref class LogTableOverflowException: public Exception   {   private:      static String^ overflowMessage = "The log table has overflowed.";   public:      LogTableOverflowException( String^ auxMessage, Exception^ inner )         : Exception( String::Format( "{0} - {1}", overflowMessage, auxMessage ), inner )      {         this->HelpLink = "http://msdn.microsoft.com";         this->Source = "Exception_Class_Samples";      }   };   public ref class LogTable   {   public:      LogTable( int numElements )      {         logArea = gcnew array<String^>(numElements);         elemInUse = 0;      }   protected:      array<String^>^logArea;      int elemInUse;   public:      // The AddRecord method throws a derived exception if       // the array bounds exception is caught.      int AddRecord( String^ newRecord )      {         try         {            logArea[ elemInUse ] = newRecord;            return elemInUse++;         }         catch ( Exception^ ex )          {            throw gcnew LogTableOverflowException( String::Format( "Record \"{0}\" was not logged.", newRecord ),ex );         }      }   };   // Create a log table and force an overflow.   void ForceOverflow()   {      LogTable^ log = gcnew LogTable( 4 );      try      {         for ( int count = 1; ; count++ )         {            log->AddRecord( String::Format( "Log record number {0}", count ) );         }      }      catch ( Exception^ ex )       {         Console::WriteLine( "\nMessage ---\n{0}", ex->Message );         Console::WriteLine( "\nHelpLink ---\n{0}", ex->HelpLink );         Console::WriteLine( "\nSource ---\n{0}", ex->Source );         Console::WriteLine( "\nStackTrace ---\n{0}", ex->StackTrace );         Console::WriteLine( "\nTargetSite ---\n{0}", ex->TargetSite->ToString() );      }   }}int main(){   Console::WriteLine( "This example of \n   Exception::Message, \n"   "   Exception::HelpLink, \n   Exception::Source, \n"   "   Exception::StackTrace, and \n   Exception::"   "TargetSite \ngenerates the following output." );   NDP_UE_CPP::ForceOverflow();}/*This example of   Exception::Message,   Exception::HelpLink,   Exception::Source,   Exception::StackTrace, and   Exception::TargetSitegenerates the following output.Message ---The log table has overflowed. - Record "Log record number 5" was not logged.HelpLink ---http://msdn.microsoft.comSource ---Exception_Class_SamplesStackTrace ---   at NDP_UE_CPP.LogTable.AddRecord(String newRecord)   at NDP_UE_CPP.ForceOverflow()TargetSite ---Int32 AddRecord(System.String)*/


原创粉丝点击