[llvm-dev] Supporting libunwind on Windows 10 (32bit; 64bit) for MSVC and Clang
Than McIntosh via llvm-dev
llvm-dev at lists.llvm.org
Mon Aug 17 05:37:47 PDT 2020
>please explain which scenarios did you assume, for libbacktrace, while
integrating Ian's project with https://go.googlesource.com/gollvm/.
Not really sure I understand your question. By "scenarios" are you talking
about strategies for doing stack unwinding?
Gollvm targets libgo (the version of the Go runtime used by gccgo); the
libgo runtime uses libbacktrace, but Gollvm is not doing anything special
as relates to setting up or configuring libbacktrace.
On Sun, Aug 16, 2020 at 7:30 PM Ivan Serdyuk <local.tourist.kiev at gmail.com>
> This is what Ken Johnson replied:
> On Sun, Aug 16, 2020 at 4:09 PM Skywing <Skywing at valhallalegends.com>
>> 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 :
>> 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
>> (CaptureStackBackTrace) and its kernel/NTDLL equivalent
>> 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
>> (RtlVirtualUnwind) for each frame, starting with a live register context
>> (e.g. as captured by
>> (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.
>> 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.
>> 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.).
>> 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 (
>> https://docs.microsoft.com/en-us/windows/win32/debug/symbol-handling) 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.
>> - S
> how close are these capabilities to what you planned for libbacktrace?
> please explain which scenarios did you assume, for libbacktrace, while
> integrating Ian's project with https://go.googlesource.com/gollvm/.
> Please check Ken's considerations and tell which of those would be the
> native way to support unwinding capabilities.
> I think there is some undocumented context, for that, related to gollvm.
> 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.
> On Sun, Aug 16, 2020 at 11:17 PM Ivan Serdyuk <
> local.tourist.kiev at gmail.com> wrote:
>> good to hear from you.
>> Thanks for the effort - I will test on 32bit and 64bit Windows 10.
>> I will report ASAP.
>> On Sun, Aug 16, 2020 at 8:42 PM Martin Storsjö <martin at martin.st> wrote:
>>> On Sat, 15 Aug 2020, Ivan Serdyuk wrote:
>>> > On Sat, Aug 15, 2020 at 8:39 PM Martin Storsjö <martin at martin.st>
>>> > Hi,
>>> > On Sat, 15 Aug 2020, Ivan Serdyuk wrote:
>>> > > Just as Shoaib said, libunwind only is useful in
>>> > environments
>>> > > that use
>>> > > the Itanium C++ ABI - there's really no use for it in an
>>> > MSVC
>>> > > context
>>> > > (either using MSVC or clang-cl to compile it).
>>> > >
>>> > > The particular linker error comes from the fact that
>>> > there's
>>> > > functions
>>> > > implemented in assembly, that expect the function name
>>> > to be
>>> > > mangled the
>>> > > itanium way, while the object files built by the
>>> > compiler expect
>>> > > the
>>> > > symbols to use the MSVC C++ name mangling, so there's an
>>> > > undefined
>>> > > reference.
>>> > >
>>> > >
>>> > > I see, thanks.
>>> > >
>>> > > Which options exist for MSVC, in sense an alternative to
>>> > libunwind and
>>> > > libbacktrace ?
>>> > Well for libunwind, there's really no use for it in an MSVC
>>> > setting. All
>>> > the unwinding functionality is already built into the operating
>>> > system,
>>> > available via the Rtl*Unwind* functions.
>>> > Martin,
>>> > you mean these functions
>>> > 2
>>> > ex
>>> > lunwind
>>> > ?
>>> Yes, those are the functions used for unwinding on windows.
>>> > For libbacktrace, I guess the _Unwind_Backtrace function in
>>> > libunwind
>>> > might work and be useful, even if the rest of libunwind doesn't
>>> > make sense
>>> > in such a context.
>>> Just FWIW, I made a RFC patch that fixes building libunwind in MSVC mode
>>> (still requiring clang-cl though), at https://reviews.llvm.org/D86041 -
>>> mostly just to show what it takes - not convinced that it necessarily is
>>> something that should be done.
>>> It does seem like _Unwind_Backtrace in libunwind doesn't work properly
>>> x86_64 windows at the moment though, but on aarch64 it seems to do what
>>> one would expect.
>>> // Martin
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev