Subscribe in a reader

Who Called Me? - Guy kolbis
Monday, December 01, 2008 6:04 AM kolbis

Who Called Me?

Sometimes it is important to understand who called a given method.

I have used it for logging purposes.

Microsoft had used it, for example the Visual Studio Team Profiler, where there is the Caller/Callee View:

image

Ever wondered how they do it?

My Solution

As I mentioned before, I have used it for logging purposes. Here is a sample code that will help you getting started:

StackTrace st = new StackTrace(3);

StackFrame sf = st.GetFrame(0);

string caller = string.Format("{0}.{1}()", sf.GetMethod().DeclaringType.FullName, sf.GetMethod().Name);

 

If you will print it you will get the method that called this code that is located 3rd from top in the call stack. You can modify the code:

StackTrace st = new StackTrace(3);
StackTrace st = new StackTrace(2);
StackTrace st = new StackTrace(1);
 
This will print the top 3 methods in the call stack.
 
Enjoy!
kick it on DotNetKicks.com תגים:,

תוכן התגובה

# Who Called Me?

DotNetKicks.com כתב/ה

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Monday, December 01, 2008 6:47 AM

# re: Who Called Me?

Adrian Aisemberg כתב/ה

Indeed a useful method.

There is one issue that should be considered when playing with the StackTrace:

Method Inlining.

The resulting caller may be different when in Debug or Release code.

Use the MethodImpl(MethodImplOptions.NoInlining) attribute on fixed methods in the stack.

Monday, December 01, 2008 7:32 AM

# re: Who Called Me?

kolbis כתב/ה

That is correct... thanks!

Monday, December 01, 2008 9:12 AM

# re: Who Called Me?

plinth כתב/ה

This will not work in all cases, as I discovered recently: www.atalasoft.com/.../stupid-nunit-tricks-3-foiled.aspx

There is a difference in implementation of .NET in 64 bit that doesn't have the correct calling information if a method was called through reflection.

Monday, December 01, 2008 2:28 PM

# re: Who Called Me?

liviu כתב/ה

What if the methods are inlined? Try to run your smart code in release mode. If you've  searched with google you've discovered that you haven't discovered anything.

Monday, December 01, 2008 6:09 PM

# re: Who Called Me?

nobody כתב/ה

@liviu well, i discovered that you're an angry person. post a counter-point on your blog and explain yourself. no, wait, being a smart-ass in the comments *is* much easier. please continue.

Monday, December 01, 2008 10:37 PM

# re: Who Called Me?

chris כתב/ה

Well, apart from what others already said, concerning the example you give about the profiler, it is far more likely that they have actually used on of the ICorDebug or ICorProfile* native CLR interfaces.

Tuesday, December 02, 2008 2:56 AM

# re: Who Called Me?

kolbis כתב/ה

Hi Chris, Thanks for the response. It is possible that they did it. Here is a link talking about it:

blogs.msdn.com/.../237954.aspx

I am trying to investgated that issue, will let you know if anything comes up.

Tuesday, December 02, 2008 3:18 AM

# Reflective Perspective - Chris Alcock » The Morning Brew #235

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #235

Tuesday, December 02, 2008 4:59 AM

# re: Who Called Me?

Karl Agius כתב/ה

Even if it doesn't work in 100% of the cases, it's great for testing. Good stuff; not something I'd suggest using in production code though.

Have you considered using AOP for this? Logging is the poster child for AOP. My personal favourite is PostSharp, though there are several other options if you dig around.

Tuesday, December 02, 2008 7:11 AM

# re: Who Called Me?

Jelle Hissink כתב/ה

Guy,

When you say:

  StackTrace st = new StackTrace(3);

  StackTrace st = new StackTrace(2);  

  StackTrace st = new StackTrace(1);

  This will print the top 3 methods in the call stack.

You create multiple StackTrace objects wich are possibly expensive to create and the GC has to clean them. So instead just create one:

  StackTrace st = new StackTrace(1);

and then use GetFrame(x) to the chain of callers

 StackFrame sf0 = st.GetFrame(0);

 StackFrame sf1 = st.GetFrame(1);

 StackFrame sf2 = st.GetFrame(2);

You can use the st.FrameCount to inspect howmany frames are available.

Wednesday, December 03, 2008 4:32 PM

# re: Who Called Me?

kolbis כתב/ה

Hi Jelle,

Thanks for the comment, I will surely check it up.

Thursday, December 04, 2008 1:10 AM

שלח תגובה

(שדה חובה) 
(שדה חובה) 
(אופציונלי)
(שדה חובה) 

Enter the numbers above: