Find the Executing function’s name


Often I want to write the SAME code that will display the name of the currently executing method or function. That way I can just copy/paste the same code into multiple methods.


 


For example, in sub Form1_Load I could put this line:


        System.Diagnostics.Debug.WriteLine(“in Form1_Load”)


 


In Button1_Click I’d have to out a different line:


        System.Diagnostics.Debug.WriteLine(“in Button1_Click”)


           


 


In FoxPro, I can use the PROGRAM() function. How do you do it in .Net? Like this:


 


 


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        System.Diagnostics.Debug.WriteLine(“subroutine name = “ + (New StackTrace).GetFrames(0).GetMethod.Name)


 


    End Sub


 


The output is:


 


subroutine name = Form1_Load


 


 


I use something similar to this code in my Unit Tests (Use Visual Studio Test framework to create tests for your code) so the test code can detect what the name of the test is.


 


In fact, you can even find out the calling assembly within a program, and do something different depending on the caller!


 


 


In fact,  run this code:


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        Dim st = New StackTrace


        Dim Methods = st.GetFrames


        For Each meth In Methods


            System.Diagnostics.Debug.WriteLine(meth.GetMethod.DeclaringType.FullName + “:” + meth.GetMethod.Name)


        Next


    End Sub


 


 If you set a breakpoint in this code, you’ll see that the output shows the method names:


This is the actual debugger output:


 


 


WindowsApplication1.exe!WindowsApplication1.Form1:Form1_Load


mscorlib.dll!System.EventHandler:Invoke


System.Windows.Forms.dll!System.Windows.Forms.Form:OnLoad


System.Windows.Forms.dll!System.Windows.Forms.Form:OnCreateControl


System.Windows.Forms.dll!System.Windows.Forms.Control:CreateControl


System.Windows.Forms.dll!System.Windows.Forms.Control:CreateControl


System.Windows.Forms.dll!System.Windows.Forms.Control:WmShowWindow


System.Windows.Forms.dll!System.Windows.Forms.Control:WndProc


System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl:WndProc


System.Windows.Forms.dll!System.Windows.Forms.ContainerControl:WndProc


System.Windows.Forms.dll!System.Windows.Forms.Form:WmShowWindow


System.Windows.Forms.dll!System.Windows.Forms.Form:WndProc


System.Windows.Forms.dll!System.Windows.Forms.Control+ControlNativeWindow:OnMessage


System.Windows.Forms.dll!System.Windows.Forms.Control+ControlNativeWindow:WndProc


System.Windows.Forms.dll!System.Windows.Forms.NativeWindow:DebuggableCallback


System.Windows.Forms.dll!System.Windows.Forms.SafeNativeMethods:ShowWindow


System.Windows.Forms.dll!System.Windows.Forms.Control:SetVisibleCore


System.Windows.Forms.dll!System.Windows.Forms.Form:SetVisibleCore


System.Windows.Forms.dll!System.Windows.Forms.Control:set_Visible


System.Windows.Forms.dll!System.Windows.Forms.Application+ThreadContext:RunMessageLoopInner


System.Windows.Forms.dll!System.Windows.Forms.Application+ThreadContext:RunMessageLoop


System.Windows.Forms.dll!System.Windows.Forms.Application:Run


Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase:OnRun


Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase:DoApplicationModel


Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase:Run


WindowsApplication1.exe!WindowsApplication1.My.MyApplication:Main


mscorlib.dll!System.AppDomain:_nExecuteAssembly


mscorlib.dll!System.AppDomain:ExecuteAssembly


Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc:RunUsersAssembly


mscorlib.dll!System.Threading.ThreadHelper:ThreadStart_Context


mscorlib.dll!System.Threading.ExecutionContext:Run


mscorlib.dll!System.Threading.ThreadHelper:ThreadStart


 


 


This is the actual stack from the Call Stack window (turn off Tools->Options->Debugging->Just My Code):


 


>          WindowsApplication1.exe!WindowsApplication1.Form1.Form1_Load(Object sender = {WindowsApplication1.Form1}, System.EventArgs e = {System.EventArgs}) Line 9         Basic


            [Native to Managed Transition]  


            [Managed to Native Transition]  


            System.Windows.Forms.dll!System.Windows.Forms.Form.OnLoad(System.EventArgs e) + 0x28b bytes 


            System.Windows.Forms.dll!System.Windows.Forms.Form.OnCreateControl() + 0x52 bytes         


            System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl(bool fIgnoreVisible) + 0x172 bytes    


            System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl() + 0x1b bytes          


            System.Windows.Forms.dll!System.Windows.Forms.Control.WmShowWindow(ref System.Windows.Forms.Message m) + 0x8e bytes           


            System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x6ed bytes     


            System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x45 bytes       


            System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.WndProc(ref System.Windows.Forms.Message m) + 0x11 bytes       


            System.Windows.Forms.dll!System.Windows.Forms.Form.WmShowWindow(ref System.Windows.Forms.Message m) + 0x3e bytes    


            System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x230 bytes     


            System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes         


            System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x36 bytes       


            System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 24, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes    


            [Native to Managed Transition]  


            [Managed to Native Transition]  


            System.Windows.Forms.dll!System.Windows.Forms.Control.SetVisibleCore(bool value = true) + 0x12f bytes      


            System.Windows.Forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value = true) + 0xdc bytes          


            System.Windows.Forms.dll!System.Windows.Forms.Control.Visible.set(bool value) + 0xe bytes 


            System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.WinFormsAppContext}) + 0xee bytes           


            System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes        


            System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x15 bytes   


            Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() + 0xc0 bytes   


             Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xe4 bytes      


            Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x62 bytes     


            [Native to Managed Transition]  


            [Managed to Native Transition]  


            mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 bytes    


             Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes     


            mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes      


            mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes  


            mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes 


 


 


You can get similar results from Foxpro. Program(-1) will return the # of stack frames. SYS(16) returns the executing program, and Program(i) returns the name of the procedure at the stack level i.


 


res=func1()


?res


PROCEDURE func1


          ?PROGRAM()


          RETURN func2()


PROCEDURE func2


          ?PROGRAM()


          ?PROGRAM(-1)        


          FOR i = 1 TO PROGRAM(-1)


                   ?SYS(16)+ PROGRAM(i)


          ENDFOR


         


          RETURN 4


 


See also How to log application API calls using import module addresses


 

Comments (6)

  1. Tod McKenna says:

    Might be a silly question, but what does the RETURN 4 do in the above code? Should that be RETURN i?

    Also, I have to admit, I like the VFP implementation much better!

  2. I have a collection of almost 30,000 pictures and videos. When I add new pictures to the collection,

  3. tstmmr says:

    Thank you for this — I’ve been looking for this for years, but never put the right words together on search. I only succeeded this time because I was so frustrated I threw a bunch of words in there I thought would never work. I kept throwing ‘reflection’ in there.

    I’d offer to have your baby, but I’m too old. Sorry.