This project has moved and is read-only. For the latest updates, please go here.

Possible bug

Aug 13, 2015 at 10:36 AM
Dear Jochen,

Firstly I would like to thank for this great and useful project.

I have used it to report the callstack in case of crash. It works fine if I run 64-bit application on 64-bit OS. But seems there is a bug when running 32-bit application on 64-bit OS. In this case the stack it reports is useless.

To solve this issue I tried to use WOW64_CONTEXT instead of CONTEXT structure, when _M_IX86 is defined and the proccess is running under WOW64 (https://msdn.microsoft.com/en-us/library/windows/desktop/aa384249(v=vs.85).aspx).

Could you please look into it and/or suggest a solution ?

Kind regards,
Ani
Aug 16, 2015 at 9:16 PM
Hi Ani, can you explain your scenario a little bit more? Do you take a context of a different 32-bit process/thread from a 64-bit process? Or a local context from a the same process?

Greetings
Jochen
Aug 16, 2015 at 9:35 PM
Hi Jochen,

I am using StackWalker to report crashes in my application. So I register signal handlers in which I call sw.ShowCallstack(); and it takes a context of the current thread.

Kind regards,
Ani
Oct 25, 2015 at 2:49 PM
Are you using the CONTEXT from an other process or from within the same process? If this is the case, then you are right... for more info see: http://www.howzatt.demon.co.uk/articles/DebuggingInWin64.html
Dec 3, 2015 at 1:24 PM
Edited Dec 3, 2015 at 1:38 PM
I have a similar problem. I'm running a 32-bit Qt application compiled with MSVC. To get the backtrace on a crash, I set up a signal handler (using the signal function) and call StackWalker::ShowCallstack inside the handler. Whenever the application crashes, I only get the backtrace of the signal handler, not the one of the context where the application crashed.

To solve the problem, I tried doing this:
  BOOL isWow64 = false;
  IsWow64Process(GetCurrentProcess(), &isWow64);

  StackWalker sw;
  if (isWow64)
    {
      WOW64_CONTEXT ctx;
      ctx.ContextFlags = CONTEXT_FULL;
      HANDLE curThread = GetCurrentThread();
      Wow64GetThreadContext(curThread, &ctx);
      sw.ShowCallstack(curThread, reinterpret_cast<CONTEXT *>(&ctx));
    }
  else
    sw.ShowCallstack();
But it doesn't seem to work -- it shows me this:
[...]
ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 773D0C32)
773D0C32 (ntdll): (filename not available): ZwGetContextThread
ERROR: SymGetSymFromAddr64, GetLastError: 126 (Address: 003CC138)
ERROR: SymGetLineFromAddr64, GetLastError: 126 (Address: 003CC138)
ERROR: SymGetModuleInfo64, GetLastError: 1114 (Address: 003CC138)
003CC138 ((module-name not available)): (filename not available): (function-name not available)
ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 655F6DC6)
Any ideas?
Dec 3, 2015 at 1:30 PM
The callstack can only be displayed if you have a valid context. I think that you do not have a valid "CONTEXT" in your signal handler, do you? If you do not have the context of your exception, you can´t display it ;)
To get the context for the exception you must use the UnhandledExeptionFilter (http://blog.kalmbach-software.de/2013/05/23/improvedpreventsetunhandledexceptionfilter/) see also examples in the code.

by the way: I recommend to write a minidump in order to find bugs in your code!
Dec 3, 2015 at 2:33 PM
So, basically, this article is wrong?: http://oroboro.com/stack-trace-on-crash/

It's a tutorial on how to make a dump of the backtrace on a crash in a cross-platform manner. For Windows, it says I can use the StackWalker project inside the signal handler.
Dec 3, 2015 at 2:36 PM
This only works, if the current thread context is inside the trapped signal handler... if this is the case, then it should work. If it does not work, can you provide me a simple example with a signal-handler?
Dec 3, 2015 at 7:47 PM
Then it must be because a Qt program has several threads. Any idea of how I can get the context of the thread in which the crash happened?

Here's a simple Qt application using StackWalker, to give you an idea: https://www.dropbox.com/s/8l43kcoa5p24b9u/signal-stackwalker-test.zip?dl=0

Here's part of the output:
[...]
c:\viewer\depends\stackwalker\stackwalker\stackwalker.cpp (920): StackWalker::ShowCallstack
c:\viewer\depends\stackwalker\stackwalker\signal-stackwalker-test\main.cpp (20): handler
[...]
Dec 11, 2015 at 3:34 AM
To anyone who might be interested: I solved my problem by calling the StackWalker from an exception filter. Since an UnhandledExceptionFilter has an EXCEPTION_POINTERS as a parameter, you can get the context of the thread the exception was thrown from the EXCEPTION_POINTERS::ContextRecord member. Works for me.

Thanks for the help.