2

I would like to record the call stack on an object that gets passed around through some complicated multi-threaded code. Environment.StackTrace gives you that call stack but it's very difficult to read.

at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n at System.Environment.get_StackTrace()\r\n at Foo.Bar.Biz(Monolith monolith) in C:\\Users\\Me\\Google\\Source\\Search.cs :line 70\r\n at Blah.Nonsense.Business(Monolith monolith) in C:\\Users\\Me\\Google\\Source\\Prediction.cs :line 129\r\n at ... you get the point 

I just need to see the file, class, method, and line. Is there a correct way to get that information? Below is the method that I wrote but it's pretty ugly because of all the string manipulation.

public static List<string[]> GetCallstack() { List<string[]> callstack = new List<string[]>(); string stackTrace = Environment.StackTrace; string[] stackInstances = stackTrace.Split(new string[] { "\r\n" }, StringSplitOptions.None); foreach (string stackInstance in stackInstances) { var stackInstanceComponents = stackInstance.Split(new string[] { ") in ", ":line " }, StringSplitOptions.None); if (stackInstanceComponents.Length == 3) { string classAndMethod = string.Join(".", stackInstanceComponents[0].Split('.').Reverse().Take(2).Reverse().ToArray()) + ")"; string path = string.Join("/", stackInstanceComponents[1].Split(System.IO.Path.DirectorySeparatorChar).Reverse().Take(2).Reverse().ToArray()).Replace("at ", ""); string line = stackInstanceComponents[2]; if (classAndMethod != "Utility.GetCallstack()") { callstack.Add(new string[] { classAndMethod, path, line }); } } } return callstack; } 
1
  • 1
    The MSDN's samples are rarely very helpful, but in this case they sort of are. Commented Oct 24, 2019 at 15:56

2 Answers 2

3

See http://www.csharp-examples.net/reflection-callstack/

using System.Diagnostics; [STAThread] public static void Main() { StackTrace stackTrace = new StackTrace(); // get call stack StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) // write call stack method names foreach (StackFrame stackFrame in stackFrames) { Console.WriteLine(stackFrame.GetMethod().Name); // write method name } } 

Use StackTrace.GetFrames() to get all frames and then each StackFrame has all required methods: GetFileName(), GetMethod(), GetFileLineNumber() and for the classname you use GetMethod().DeclaringType...

Sign up to request clarification or add additional context in comments.

3 Comments

FYI: OPs requirement is I just need to see the file, class, method, and line. your code only prints the method name, so no file or line.
@RandRandom Then look at the documentation for StackFrame.... It has it all... GetFileName(), GetFileLineNumber(), GetMethod()...
I mean, how do you think I got the code I'm using? Yeah, I googled it.
1

You can use the System.Diagnostics.StackTrace class instead. It will give you a hierarchical view of your stack trace. Check out this for full details on the class and code examples that do what you want. Note however that you must also filter out what you need. However, StackTrace allows you to do it in a cleaner way. Another choice is to use the StackFrame class which provides more fine grained info. This class has the GetFileName(), GetMethod(), GetFileLineNumber() and for the class name you can use GetMethod().DeclaringType

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.