Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split a stacktrace line into namespace, class, method file and line number?

C# stack traces take the following form:

   at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21
   at Foo.Core.Test.AnotherMethod(Bar bar)
   at Foo.Core.Test.AMethod() in C:\Projects\src\Core.Tests\Test.cs:line 6
   at Foo.Core.Test.<>c__DisplayClass7.<SomeAnonDelegate>b__6(Object _) in C:\Projects\src\Core.Tests\Test.cs:line 35

How can I retrieve namespace, class, method, file and line number from each line?

  • Are there any existing classes to do this?
  • If not what would be the the best approach?
  • Regex? How would I greedily match the namespace but leave the class and method?
  • Custom parser?

Would appreciate some ideas and input.

like image 278
chillitom Avatar asked Feb 28 '11 22:02

chillitom


2 Answers

If you're getting this from a StackTrace, then you can loop through the StackFrames via GetFrame and call GetMethod, GetFileName, and GetFileLineNumber. Namespace and class can be retrieved from the method.

EDIT
In response to the first comment (unfortunately we get the traces from Exception.StackTrace), you can call the StackTrace(Exception) constructor.

EDIT
I should've linked to this constructor instead -- StackTrace(Exception,bool).

like image 118
Austin Salonen Avatar answered Oct 17 '22 20:10

Austin Salonen


I read the Austin Salonen's answer and it's obvious better, but I've already started with regex. so I'll write it anyway.

Regex r = new Regex(@"at (?<namespace>.*)\.(?<class>.*)\.(?<method>.*(.*)) in (?<file>.*):line (?<line>\d*)");
var result = r.Match(@"at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21");
if (result.Success)
{
    string _namespace = result.Groups["namespace"].Value.ToString();
    string _class = result.Groups["class"].Value.ToString();
    string _method = result.Groups["method"].Value.ToString();
    string _file = result.Groups["file"].Value.ToString();
    string _line = result.Groups["line"].Value.ToString();
    Console.WriteLine("namespace: " + _namespace);
    Console.WriteLine("class: " + _class);
    Console.WriteLine("method: " + _method);
    Console.WriteLine("file: " + _file);
    Console.WriteLine("line: " + _line);
}
like image 24
Homam Avatar answered Oct 17 '22 19:10

Homam