Существует ли кроссплатформенный способ захвата стека вызовов?
Быстрый ответ: к сожалению, это невозможно.Различные компиляторы и платформы будут организовывать стек по-разному, и без «помощи» компилятора вы не сможете точно проследить обратно через стек ... самое большее, что вы могли бы сделать на платформах, использующих стек.базовый указатель кадра будет перемещаться вверх по стеку, используя значения либо EBP
, либо RBP
, и даже это зависит от того, используете ли вы 32-разрядный исполняемый файл x86 или x86_64.Кроме того, правила, управляющие двоичным интерфейсом приложений (ABI) UNIX и Windows ABI, совершенно разные.В общем, в конечном итоге вам придется поддерживать как минимум четыре различных варианта:
- Unix 32-битный ABI
- Unix 64-битный ABI
- Windows 32-битный ABI
- Windows 64-битный ABI
Имейте в виду, что 64-битный ABI UNIX позволяет компиляторам выбирать, будут ли они поддерживать стек или нет- указатель базы кадра ... поэтому использование указателя базы не гарантируется;компилятор может просто выбрать ссылку на все переменные стека против самого указателя стека без использования отдельного базового указателя.Это все равно будет считаться совместимым с UNIX 64-битным ABI.
Так что, как вы видите, со всеми этими возможными вариантами вам будет очень непросто создать надежный кроссплатформенный стек.трейсера.Лучше всего использовать инструменты, доступные вам для целевой платформы.Если вам нужно поддерживать несколько платформ, то, к сожалению, будет некоторый уровень дублирования кода, поскольку вы будете использовать специальные инструменты для платформ, которые помогут вам надежно выполнять трассировку стека.