<div dir="ltr"><div>This is what Ken Johnson replied:<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Aug 16, 2020 at 4:09 PM Skywing <<a href="mailto:Skywing@valhallalegends.com">Skywing@valhallalegends.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US">
<div class="gmail-m_5354491578500379953WordSection1">
<p class="MsoNormal">I just briefly skimmed the discussion, so hopefully I didn't misunderstand what you are trying to do ... but if your objective is to capture a stack trace under NT, the OS exports several services for this purpose, depending on what you
need out of such a stack trace :</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal">1) There is a "pre-cooked" stack trace facility that will perform the entire stack trace for you (optionally skipping some frames at the top), returning an array of program counter values for each return address on the stack: <a href="https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/bb204633(v=vs.85)?redirectedfrom=MSDN" target="_blank">https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/bb204633(v=vs.85)?redirectedfrom=MSDN</a>
(CaptureStackBackTrace) and its kernel/NTDLL equivalent <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlcapturestackbacktrace" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlcapturestackbacktrace</a> (RtlCaptureStackBackTrace)</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal">2) Alternatively, if more customization for the operation than what CaptureStackBackTrace/RtlCaptureStackBackTrace affords is required, then you could walk the stack manually by successively invoking <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlvirtualunwind" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlvirtualunwind</a>
(RtlVirtualUnwind) for each frame, starting with a live register context (e.g. as captured by <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlcapturecontext" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlcapturecontext</a> (RtlCaptureContext)). This would give you the opportunity to examine, for instance,
the nonvolatile register context for each frame, albeit at the cost of having to write platform dependent code for each build target (e.g. AMD64, 32-bit ARMNT, ARM64, etc.). RtlCaptureStackBackTrace is essentially implemented in this way for non-32-bit-x86
targets (x86 doesn't have what most architectures would consider an "unwinder" in the sense of restoring registers; there is simply a linked list of frames that participate in SEH and that desire to be called for a dynamic unwind operation, so RtlCaptureStackBackTrace
assumes that EBP-based frames are in use and walks an EBP-based frame chain on x86 - not all x86 code is written with EBP-based frames so while even though we generally build the OS that way, you might always run the risk of encountering external code that
uses EBP as a general purpose register for which such an unwind attempt for a stack trace would fail). On non-x86 architectures, the various NT platform ABIs typically strive to provide for precise unwinding at all frames and at every instruction boundary
where interrupts are enabled (at least assuming that all code in the process is well-formed and follows the ABI properly etc. - interrupts are always enabled in user mode code). For C/C++ code, VC, ICC, and (I believe) LLVM/clang should support the platform
exception/unwind ABIs; GCC may or may not these days.</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal">The OS's exception and unwind dispatcher, for non-x86 build targets, uses the virtual unwind facility to accomplish unwinding for purposes of exception handling related exception dispatching & unwinding.</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"> </p>
<p class="MsoNormal">On the non-x86 targets, debuggers and related tools would typically use the platform ABI's exception and unwind handling structures for their unwinding as well. Debuggers on x86 might either assume EBP-based frames, or use compiler-specific
debug information from debug symbols (typically not embedded in the compiled binary for most NT-targeted code but rather kept in a standalone .pdb/.dbg file etc.).</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"> </p>
<p class="MsoNormal">Note that the platform exception and unwind APIs and associated structures embedded in executable images don't, on their own, provide a way to map a PC value to a meaningful symbolic function name, line number, etc.. If you want to resolve
PC values to function names, then you'll typically need debug symbols for each module present on the call stack. For that, provided that you have debug symbols available for all such frames (OS binaries have these published on the Microsoft public symbol
server; some major third parties like web browsers publish their symbols on their own symbol servers as well but many other third party binaries may not make such affordances available). There are a set of APIs (<a href="https://docs.microsoft.com/en-us/windows/win32/debug/symbol-handling" target="_blank">https://docs.microsoft.com/en-us/windows/win32/debug/symbol-handling</a>)
to load debug symbols for a module, and resolve a module + RVA (i.e. module + offset into the module) to a symbol name and offset into the symbol. When debug symbols aren't available, these facilities will typically pick the nearest exported symbol (if any),
which may or may not be at all meaningful (most symbols aren't exported in most executables targeting NT). Note that loading and processing debug symbols is typically a considerably more "heavyweight" operation than invoking the platform unwind APIs.</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal">- S</p></div></div></blockquote><div><br></div><div>Ian,</div><div>how close are these capabilities to what you planned for libbacktrace?</div><div><br></div><div>Than,<br></div><div>please explain which scenarios did you assume, for libbacktrace, while integrating Ian's project with <a href="https://go.googlesource.com/gollvm/">https://go.googlesource.com/gollvm/</a>.</div><div>Please check Ken's considerations and tell which of those would be the native way to support unwinding capabilities.</div><div>I think there is some undocumented context, for that, related to gollvm.</div><div>Consider this related to github issues, targeting support of Windows 10 (x86_64; i386). And btw - specifically ARM64 oriented Windows 10 haven't been suggested yet, by ARM's engineers, which contributed into brief support of ARM64 oriented Linux.<br></div><div><br></div><div>Ivan<br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Aug 16, 2020 at 11:17 PM Ivan Serdyuk <<a href="mailto:local.tourist.kiev@gmail.com">local.tourist.kiev@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Martin,</div><div>good to hear from you.</div><div>Thanks for the effort - I will test on 32bit and 64bit Windows 10.</div><div>I will report ASAP.</div><div><br></div><div>Ivan<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Aug 16, 2020 at 8:42 PM Martin Storsjö <<a href="mailto:martin@martin.st" target="_blank">martin@martin.st</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sat, 15 Aug 2020, Ivan Serdyuk wrote:<br>
<br>
> <br>
> <br>
> On Sat, Aug 15, 2020 at 8:39 PM Martin Storsjö <<a href="mailto:martin@martin.st" target="_blank">martin@martin.st</a>> wrote:<br>
> Hi,<br>
> <br>
><br>
> On Sat, 15 Aug 2020, Ivan Serdyuk wrote:<br>
><br>
> > Just as Shoaib said, libunwind only is useful in<br>
> environments<br>
> > that use<br>
> > the Itanium C++ ABI - there's really no use for it in an<br>
> MSVC<br>
> > context<br>
> > (either using MSVC or clang-cl to compile it).<br>
> ><br>
> > The particular linker error comes from the fact that<br>
> there's<br>
> > functions<br>
> > implemented in assembly, that expect the function name<br>
> to be<br>
> > mangled the<br>
> > itanium way, while the object files built by the<br>
> compiler expect<br>
> > the<br>
> > symbols to use the MSVC C++ name mangling, so there's an<br>
> > undefined<br>
> > reference.<br>
> ><br>
> ><br>
> > I see, thanks.<br>
> ><br>
> > Which options exist for MSVC, in sense an alternative to<br>
> libunwind and<br>
> > libbacktrace ?<br>
><br>
> Well for libunwind, there's really no use for it in an MSVC<br>
> setting. All<br>
> the unwinding functionality is already built into the operating<br>
> system,<br>
> available via the Rtl*Unwind* functions.<br>
> <br>
> <br>
> Martin,<br>
> you mean these functions<br>
> <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlunwind" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlunwind</a><br>
> <br>
> <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlunwind" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlunwind</a><br>
> 2<br>
> <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlunwind" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlunwind</a><br>
> ex<br>
> <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlvirtua" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlvirtua</a><br>
> lunwind<br>
> ?<br>
<br>
Yes, those are the functions used for unwinding on windows.<br>
<br>
> For libbacktrace, I guess the _Unwind_Backtrace function in<br>
> libunwind<br>
> might work and be useful, even if the rest of libunwind doesn't<br>
> make sense<br>
> in such a context.<br>
<br>
Just FWIW, I made a RFC patch that fixes building libunwind in MSVC mode <br>
(still requiring clang-cl though), at <a href="https://reviews.llvm.org/D86041" rel="noreferrer" target="_blank">https://reviews.llvm.org/D86041</a> - <br>
mostly just to show what it takes - not convinced that it necessarily is <br>
something that should be done.<br>
<br>
It does seem like _Unwind_Backtrace in libunwind doesn't work properly on <br>
x86_64 windows at the moment though, but on aarch64 it seems to do what <br>
one would expect.<br>
<br>
// Martin<br>
</blockquote></div>
</blockquote></div>