https://bugs.winehq.org/show_bug.cgi?id=57628
Bug ID: 57628 Summary: Simple StackWalk64 code example doesn't produce output as expected Product: Wine Version: 10.0-rc3 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: dbghelp Assignee: wine-bugs@winehq.org Reporter: tuxifan@posteo.de Distribution: ---
Created attachment 77753 --> https://bugs.winehq.org/attachment.cgi?id=77753 StackWalk64 code example
Running the attached StackWalk64 code example produces a stack trace on Windows. In Wine, it doesn't. No log messages are generated.
https://bugs.winehq.org/show_bug.cgi?id=57628
tuxifan@posteo.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Distribution|--- |Debian
https://bugs.winehq.org/show_bug.cgi?id=57628
--- Comment #1 from tuxifan@posteo.de --- There are 2 issues in this code sample: `STACKFRAME64` isn't zero-initialized, and `SymInitialize` isn't called. Not sure how this is treated, I mean it is literally wrong API usage, but it *is* behaving differently on Windows. I will attach the executable.
https://bugs.winehq.org/show_bug.cgi?id=57628
--- Comment #2 from tuxifan@posteo.de --- Created attachment 77754 --> https://bugs.winehq.org/attachment.cgi?id=77754 Executable generated from attached code sample
https://bugs.winehq.org/show_bug.cgi?id=57628
Fabian Maurer dark.shadow4@web.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |testcase Status|UNCONFIRMED |NEW CC| |dark.shadow4@web.de Ever confirmed|0 |1
--- Comment #3 from Fabian Maurer dark.shadow4@web.de --- Confirming, although not 100% sure how supported that is...
https://bugs.winehq.org/show_bug.cgi?id=57628
Eric Pouech eric.pouech@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |eric.pouech@gmail.com
--- Comment #4 from Eric Pouech eric.pouech@gmail.com --- I'm not sure it's wrong API usage :-( MSDN documentation for StackWalk64 doesn't explicitly requests that the process has been initialized (whereas it's explicitly stated for most of the others dbghelp's APIs)
this likely requires something like what's done in minidump writing (eg creating a dbghelp context with SymInitialize if none exists) (*)
what's harder is the STACKFRAME64 part...
MSDN states that only the 3 addresses need to be initialized... let's see
when using
memset(&s, 0xA5, sizeof(s));
before the the init of the STACKFRAME64, I get a nice exception thrown from within StackWalk64... it seems to be triggered when the KDHELP64 RetpolineStubFunctionTableSize field is set to 0xA5A5A5A5A5A5A5A5 So not initializing the STACKFRAME can lead so severe impacts!
I see also usage of STACKFRAME64.Reserved fields - after first call, Reserved[0] is set to 0, - after second call, Reserved[2] can be touched - afterwards no Reserved fields are changed
the Far & Virtual fields are only changed when their value is 0 or 1 depending if Far&Virtual are among 0,1 or not, modification on Reserved[2] is different (set to 1 vs decreased by one)
but in any case, native seems to do more work to try to identify if the structure has been initialized or not...
note: builtin dbghelp also requires to distinguish, first call, second call and any other calls on x86_64 (situation is way more complex on i386)
note also that non initialized content on stack can vary between Wine & Windows
is this snipnet derived from a real application? If so, can you share which one? (the observations above are only for x64, and are likely to be different for another machine. current dbghelp code makes the assumption that the Reserved fields are zero:ed upon first call; I'm not sure we can simply detect the uninitialized state without making any assumption on the Reserved fields content)
(*) would require some testing as likely the process handle shall be a live (real) process handle, and whether the context is kept somehow (otherwise would require rewalking the module list at each call, which could be time expansive at the end)
https://bugs.winehq.org/show_bug.cgi?id=57628
--- Comment #5 from tuxifan@posteo.de --- (In reply to Eric Pouech from comment #4)
is this snipnet derived from a real application? If so, can you share which one?
Yes, however I unfortunately can't easily share that application or give further information about it :-( I wrote that code snipped to isolate the issue that occurs within that application, also so that I can simply share it here.
https://bugs.winehq.org/show_bug.cgi?id=57628
--- Comment #6 from Eric Pouech eric.pouech@gmail.com --- investigated a bit more the case of missing SymInitialize call
I can't even let Wine stack walk tests on Windows pass: it turns out that (in this case) native calls the FunctionTableAccess64 function, which fails because process is not initialized the net result is that we can't unwind to the calling frame
and on amd64, calling into FunctionTableAccess64 is absolutely required for proper unwinding
does your app pass FunctionTableAccess64 to StackWalk or is it a simplification from your snippnet?
but with providing a decent implementation of these two functions for StackWalk64, I can pass the test on native, and builtin as well
so there's nothing to "fix" here