Get stacktrace inside c# method











up vote
3
down vote

favorite












I want to implement universal logger which help me to see call stack of the methods.



I know there are some methods from System.Diagnostic but they were introduced in .net 4.0 and I'm afraid it will not work on xamarin or .net core or something like that. So I want to have more universal solution.



Another problem is asyncawait which introduce some mess.



I through about passing additional parameter in each method which store some context and help me to determinate call stack, but this solution is a bit complex.



Also I can read thread stack memory using unsafe code and check call stack by myself but it is not reliable.



Are there any other solution ?










share|improve this question


















  • 1




    You could certainly hack it around: throw an exception, catch it and read callstack from it :)
    – MarcinJuraszek
    May 8 '16 at 17:04












  • @MarcinJuraszek Nice hack:) but I'm afraid it will affect performance too much.
    – Neir0
    May 8 '16 at 17:07















up vote
3
down vote

favorite












I want to implement universal logger which help me to see call stack of the methods.



I know there are some methods from System.Diagnostic but they were introduced in .net 4.0 and I'm afraid it will not work on xamarin or .net core or something like that. So I want to have more universal solution.



Another problem is asyncawait which introduce some mess.



I through about passing additional parameter in each method which store some context and help me to determinate call stack, but this solution is a bit complex.



Also I can read thread stack memory using unsafe code and check call stack by myself but it is not reliable.



Are there any other solution ?










share|improve this question


















  • 1




    You could certainly hack it around: throw an exception, catch it and read callstack from it :)
    – MarcinJuraszek
    May 8 '16 at 17:04












  • @MarcinJuraszek Nice hack:) but I'm afraid it will affect performance too much.
    – Neir0
    May 8 '16 at 17:07













up vote
3
down vote

favorite









up vote
3
down vote

favorite











I want to implement universal logger which help me to see call stack of the methods.



I know there are some methods from System.Diagnostic but they were introduced in .net 4.0 and I'm afraid it will not work on xamarin or .net core or something like that. So I want to have more universal solution.



Another problem is asyncawait which introduce some mess.



I through about passing additional parameter in each method which store some context and help me to determinate call stack, but this solution is a bit complex.



Also I can read thread stack memory using unsafe code and check call stack by myself but it is not reliable.



Are there any other solution ?










share|improve this question













I want to implement universal logger which help me to see call stack of the methods.



I know there are some methods from System.Diagnostic but they were introduced in .net 4.0 and I'm afraid it will not work on xamarin or .net core or something like that. So I want to have more universal solution.



Another problem is asyncawait which introduce some mess.



I through about passing additional parameter in each method which store some context and help me to determinate call stack, but this solution is a bit complex.



Also I can read thread stack memory using unsafe code and check call stack by myself but it is not reliable.



Are there any other solution ?







c# logging callstack






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked May 8 '16 at 17:03









Neir0

4,8612465118




4,8612465118








  • 1




    You could certainly hack it around: throw an exception, catch it and read callstack from it :)
    – MarcinJuraszek
    May 8 '16 at 17:04












  • @MarcinJuraszek Nice hack:) but I'm afraid it will affect performance too much.
    – Neir0
    May 8 '16 at 17:07














  • 1




    You could certainly hack it around: throw an exception, catch it and read callstack from it :)
    – MarcinJuraszek
    May 8 '16 at 17:04












  • @MarcinJuraszek Nice hack:) but I'm afraid it will affect performance too much.
    – Neir0
    May 8 '16 at 17:07








1




1




You could certainly hack it around: throw an exception, catch it and read callstack from it :)
– MarcinJuraszek
May 8 '16 at 17:04






You could certainly hack it around: throw an exception, catch it and read callstack from it :)
– MarcinJuraszek
May 8 '16 at 17:04














@MarcinJuraszek Nice hack:) but I'm afraid it will affect performance too much.
– Neir0
May 8 '16 at 17:07




@MarcinJuraszek Nice hack:) but I'm afraid it will affect performance too much.
– Neir0
May 8 '16 at 17:07












1 Answer
1






active

oldest

votes

















up vote
3
down vote



accepted










You could just use Environment.StackTrace. That has been part of the Framework since the very beginning.



Environment.StackTrace will return the complete stacktrace (including the call to Environment.StackTrance itself) as a line separated string.



Something like this:




at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at WpfApplication2.MainWindow.GetStack(Int32 removeLines)

at WpfApplication2.MainWindow.Button_Click(Object sender, RoutedEventArgs e)

...

at System.Threading.ThreadHelper.ThreadStart()




All you need to do is split/parse/format it, whatever you want to do with it.



Since you'll be using this from within your own classes, remember to remove the newest X lines.



This code should work everywhere since it's deliberately low-level.



private static string GetStack(int removeLines)
{
string stack = Environment.StackTrace.Split(
new string {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);

if(stack.Length <= removeLines)
return new string[0];

string actualResult = new string[stack.Length - removeLines];
for (int i = removeLines; i < stack.Length; i++)
// Remove 6 characters (e.g. " at ") from the beginning of the line
// This might be different for other languages and platforms
actualResult[i - removeLines] = stack[i].Substring(6);

return actualResult;
}





share|improve this answer























  • Perfect. That works!
    – Neir0
    May 8 '16 at 17:31






  • 1




    One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
    – Neir0
    May 8 '16 at 17:33










  • Good thought. I'll include that in the answer for future reference.
    – Manfred Radlwimmer
    May 8 '16 at 17:46











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f37102450%2fget-stacktrace-inside-c-sharp-method%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote



accepted










You could just use Environment.StackTrace. That has been part of the Framework since the very beginning.



Environment.StackTrace will return the complete stacktrace (including the call to Environment.StackTrance itself) as a line separated string.



Something like this:




at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at WpfApplication2.MainWindow.GetStack(Int32 removeLines)

at WpfApplication2.MainWindow.Button_Click(Object sender, RoutedEventArgs e)

...

at System.Threading.ThreadHelper.ThreadStart()




All you need to do is split/parse/format it, whatever you want to do with it.



Since you'll be using this from within your own classes, remember to remove the newest X lines.



This code should work everywhere since it's deliberately low-level.



private static string GetStack(int removeLines)
{
string stack = Environment.StackTrace.Split(
new string {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);

if(stack.Length <= removeLines)
return new string[0];

string actualResult = new string[stack.Length - removeLines];
for (int i = removeLines; i < stack.Length; i++)
// Remove 6 characters (e.g. " at ") from the beginning of the line
// This might be different for other languages and platforms
actualResult[i - removeLines] = stack[i].Substring(6);

return actualResult;
}





share|improve this answer























  • Perfect. That works!
    – Neir0
    May 8 '16 at 17:31






  • 1




    One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
    – Neir0
    May 8 '16 at 17:33










  • Good thought. I'll include that in the answer for future reference.
    – Manfred Radlwimmer
    May 8 '16 at 17:46















up vote
3
down vote



accepted










You could just use Environment.StackTrace. That has been part of the Framework since the very beginning.



Environment.StackTrace will return the complete stacktrace (including the call to Environment.StackTrance itself) as a line separated string.



Something like this:




at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at WpfApplication2.MainWindow.GetStack(Int32 removeLines)

at WpfApplication2.MainWindow.Button_Click(Object sender, RoutedEventArgs e)

...

at System.Threading.ThreadHelper.ThreadStart()




All you need to do is split/parse/format it, whatever you want to do with it.



Since you'll be using this from within your own classes, remember to remove the newest X lines.



This code should work everywhere since it's deliberately low-level.



private static string GetStack(int removeLines)
{
string stack = Environment.StackTrace.Split(
new string {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);

if(stack.Length <= removeLines)
return new string[0];

string actualResult = new string[stack.Length - removeLines];
for (int i = removeLines; i < stack.Length; i++)
// Remove 6 characters (e.g. " at ") from the beginning of the line
// This might be different for other languages and platforms
actualResult[i - removeLines] = stack[i].Substring(6);

return actualResult;
}





share|improve this answer























  • Perfect. That works!
    – Neir0
    May 8 '16 at 17:31






  • 1




    One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
    – Neir0
    May 8 '16 at 17:33










  • Good thought. I'll include that in the answer for future reference.
    – Manfred Radlwimmer
    May 8 '16 at 17:46













up vote
3
down vote



accepted







up vote
3
down vote



accepted






You could just use Environment.StackTrace. That has been part of the Framework since the very beginning.



Environment.StackTrace will return the complete stacktrace (including the call to Environment.StackTrance itself) as a line separated string.



Something like this:




at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at WpfApplication2.MainWindow.GetStack(Int32 removeLines)

at WpfApplication2.MainWindow.Button_Click(Object sender, RoutedEventArgs e)

...

at System.Threading.ThreadHelper.ThreadStart()




All you need to do is split/parse/format it, whatever you want to do with it.



Since you'll be using this from within your own classes, remember to remove the newest X lines.



This code should work everywhere since it's deliberately low-level.



private static string GetStack(int removeLines)
{
string stack = Environment.StackTrace.Split(
new string {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);

if(stack.Length <= removeLines)
return new string[0];

string actualResult = new string[stack.Length - removeLines];
for (int i = removeLines; i < stack.Length; i++)
// Remove 6 characters (e.g. " at ") from the beginning of the line
// This might be different for other languages and platforms
actualResult[i - removeLines] = stack[i].Substring(6);

return actualResult;
}





share|improve this answer














You could just use Environment.StackTrace. That has been part of the Framework since the very beginning.



Environment.StackTrace will return the complete stacktrace (including the call to Environment.StackTrance itself) as a line separated string.



Something like this:




at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at WpfApplication2.MainWindow.GetStack(Int32 removeLines)

at WpfApplication2.MainWindow.Button_Click(Object sender, RoutedEventArgs e)

...

at System.Threading.ThreadHelper.ThreadStart()




All you need to do is split/parse/format it, whatever you want to do with it.



Since you'll be using this from within your own classes, remember to remove the newest X lines.



This code should work everywhere since it's deliberately low-level.



private static string GetStack(int removeLines)
{
string stack = Environment.StackTrace.Split(
new string {Environment.NewLine},
StringSplitOptions.RemoveEmptyEntries);

if(stack.Length <= removeLines)
return new string[0];

string actualResult = new string[stack.Length - removeLines];
for (int i = removeLines; i < stack.Length; i++)
// Remove 6 characters (e.g. " at ") from the beginning of the line
// This might be different for other languages and platforms
actualResult[i - removeLines] = stack[i].Substring(6);

return actualResult;
}






share|improve this answer














share|improve this answer



share|improve this answer








edited May 8 '16 at 17:47

























answered May 8 '16 at 17:11









Manfred Radlwimmer

10.3k123350




10.3k123350












  • Perfect. That works!
    – Neir0
    May 8 '16 at 17:31






  • 1




    One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
    – Neir0
    May 8 '16 at 17:33










  • Good thought. I'll include that in the answer for future reference.
    – Manfred Radlwimmer
    May 8 '16 at 17:46


















  • Perfect. That works!
    – Neir0
    May 8 '16 at 17:31






  • 1




    One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
    – Neir0
    May 8 '16 at 17:33










  • Good thought. I'll include that in the answer for future reference.
    – Manfred Radlwimmer
    May 8 '16 at 17:46
















Perfect. That works!
– Neir0
May 8 '16 at 17:31




Perfect. That works!
– Neir0
May 8 '16 at 17:31




1




1




One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
– Neir0
May 8 '16 at 17:33




One note, .net has different stack trace output for different languages, so it is necessary to be careful while removing "at" and other language depended words.
– Neir0
May 8 '16 at 17:33












Good thought. I'll include that in the answer for future reference.
– Manfred Radlwimmer
May 8 '16 at 17:46




Good thought. I'll include that in the answer for future reference.
– Manfred Radlwimmer
May 8 '16 at 17:46


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f37102450%2fget-stacktrace-inside-c-sharp-method%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini