What kind of stack unwinding libraries do exist and what's the difference? [closed]
Asked Answered
R

1

8

Trying to build my own non-GNU cross-platform C++ environment, I have faced the fact that I don't really understand the basics of the stack unwinding. The environment I build is as follows:

libc++libc++abilibunwind (or some other unwinder).

I've found that libc++abi already contains some kind of libunwind, but doesn't use it on Linux. From the comments I understood, that it's special libunwind: LLVM Stack Unwinder that supports only Darwin and ARM but not x86_64 - and it's confusing. How does it come that the CPU architecture affects the stack unwinding process?

Also I know about following stack unwinders:

  1. glibc built-in.
  2. libc++abi LLVM libunwind.
  3. GNU libunwind (from savanna).

Questions:

  1. How does the platform or CPU architecture affects the stack unwinding process?
  2. Why to have many stack unwinders - and not just a single one?
  3. What kind of unwinders do exist and what is a difference between them?

Expectations from an answer:

I expect to get the answer that covers this topic as whole, not just separate points on each question.

Rizzi answered 18/8, 2014 at 5:11 Comment(6)
#3-type questions are considered off-topic on StackOverflow.Outcast
@DonReba Can you point me to the corresponding meta-post, please? - I have asked such questions and saw them here and there before.Rizzi
stackoverflow.com/help/on-topic #4Outcast
@DonReba Do you mean this part?: Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource - then I don't see how this applies to my question. By the way, #3-type questions - do you mean questions with 3 another subquestions or something else?Rizzi
I mean questions that ask to recommend an unwinder library, which is subquestion #3.Outcast
@DonReba I see what you mean - the question is not about recommendations. I reformulated it with hope, that it won't confuse anyone anymore.Rizzi
G
3

Fundamentally, the stack layout is up to the compiler. It can lay out the stack in almost whatever way it thinks is best. The language standard says nothing about how the stack is laid out.

In practice, different compilers lay the stack out differently and the same compiler can also lay it out differently when run with different options. The stack layout will depend on the size of types on the target platform (especially the size of pointer types), compiler options such as GCC's -fomit-frame-pointer, ABI requirements of the platform (eg x64 has a defined ABI where x86 does not). How to interpret the stack will also depend on how the compiler stores the relevant information. This in turn partly depends on the executable format (probably either ELF or COFF these days, but actually, as long as the OS can load the executable and find the entry point, everything else is pretty much up for grabs) and partly on the debug information format - which is again specific to the compiler/debugger combination in use. In the end, it is perfectly possible to write inline assembler that manipulates the stack and program flow in a way that no unwinder will be able to follow. Some compilers also allow you to customise the function prologue and epilogue, giving you another opportunity to confuse any unwinding algorithm.

The net effect of all this is that it is not possible to write a single stack-unwinding algorithm that will work everywhere. The unwinding algorithm has to match the compiler, OS and, for more than the most basic information, the debugger. The best you can do is to write a simple stack-unwinding interface and implement it differently for each compiler/OS/debugger combination you support.

Glaucous answered 18/8, 2014 at 6:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.