What libraries for stack promotion exist and what is the difference?

Trying to create my own cross-platform C ++ environment other than GNU, I came across the fact that I really don't understand the basics of stack deployment. I create the following environment:

libc++ ← libc++abi ← libunwind (or some other unwinder).

I found that libc++abi already contains some kind of libunwind, but does not use it on Linux. From the comments, I realized that this is a special libunwind: LLVM Stack Unwinder, which only supports Darwin and ARM, but not x86_64 - and this is confusing. How is it that processor architecture affects the stack reversal process?

In addition, I know of the following discharges:

  • built-in glibc module.
  • libc ++ abi LLVM libunwind.
  • GNU libunwind (from the savannah).

Questions:

  • How does the platform or processor architecture affect the stack reversal process?
  • Why do you have many stack breaks, and not just one?
  • What are the unwinders and what is the difference between them?

Expectations from the answer:

I expect to receive an answer that covers the whole topic, and not just individual points on each question.

+6
source share
1 answer

Basically, the stack layout is compiler dependent. He can lay out the stack almost as it seems to him the best. The language standard says nothing about how the stack stacks.

In practice, different compilers put the stack in different ways, and the same compiler can also set it differently at startup with different parameters. The layout of the stack will depend on the size of the types on the target platform (especially the size of pointer types), compiler options such as GCC -fomit-frame-pointer , platform ABI requirements (for example, x64 has a specific ABI where x86 is 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 (maybe ELF or COFF at the moment, but in fact, as long as the OS can load the executable and find the entry point, everything else is pretty much suitable for captures) and partially debugging the information format, which again is specific to the used compiler / debugger combination. After all, it is entirely possible to write an inline assembler that manipulates the stack and program flow so that no unwinders can follow. Some compilers also allow you to customize the prolog and epilogue functions, giving you another opportunity to confuse any reversal algorithm.

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

+2
source

Source: https://habr.com/ru/post/973952/


All Articles