views:

203

answers:

2

There is a constructor on StackTrace that takes an exeption as an argument. All fine and well, but I noticed that all the other constructors say that it will get the StackTrace from the current thread, but the constructor taking the exception does not say anything about that other than

The resulting stack trace describes the stack at the time of the exception.

I just want to be sure that I will get the correct StackTrace of an exception even if I create the StackTrace on a different thread that the exception was created in when I create the StackTrace from an exception in another thread.

Can someone please confirm?

+1  A: 

It will create the StackTrace for the thread it's called on (internally, it calls 'CaptureStackTrace' with for the parameter 'targetThread', which indicates the current thread is requested). The only ctor which creates for another thread is the one which takes a Thread instance.

codekaizen
This contradicts Mattias' and my tests. I just looked at it in Reflector and null is passed as targetThread to 'CaptureStackTrace'. It then calls 'GetStackFramesInternal' passing in the exception. I can't see the source for 'GetStackFramesInternal' though.
Hermann
Yea, that is odd. In Win32, NULL means "current thread", but here it appears to mean something else. GetStackFramesInternal is implemented in the MSCOREE.dll... I looked in the SSCLI source, and found the implementation in the file \clr\src\vm\debugdebugger.cpp: if (pException == NULL) { // Thread is NULL if it's the current thread. data.TargetThread = pStackFrameHelper->TargetThread; GetStackFrames(NULL, (void*)-1, } else { GetStackFramesFromException( }
codekaizen
+2  A: 

Seems easy enough to try, unless I'm missing something. This prints the right stack trace for me.

static Exception threadEx;

static void Main()
{
    Thread worker = new Thread(DoWork);
    worker.Start();
    worker.Join();

    if (threadEx != null) {
     StackTrace trace = new StackTrace(threadEx);
     Console.WriteLine(trace);
    }
}

static void DoWork()
{
    try {
     throw new Exception("Boom!");
    }
    catch (Exception ex) {
     threadEx = ex;
    }
}
Mattias S
Thanks Mattias, I did finally test this for myself too and you're right, it does print the right stack trace.
Hermann