Классы для получения backtrace

yndx-antoshkka
yndx-antoshkka

На данный момент в С++ нет изкоробочного метода для получения стека вызовов и работы с ним. Предлагаю придумать такие методы и классы, написать прототип и сделать егостандартом языка.

На данный момент есть черновой прототип, который активно мной дописывается stacktrace:

std::stacktrace s;
std::cout << s;     // выведет стектрейс

std::cout << s[0];  // выведет текущую функцию, например:
// foo(int)    ../example/getting_started.cpp:29

Пожалуста, расскажите чего вам не хватает в прототипе и что вам кажется в нём неправильным.

23
рейтинг
12 комментариев
ilnur.khuziev
давайте сразу под флаг компилятора: попытка напечатать трейс в stderr при terminate/abort и т.д.
ilnur.khuziev
yndx-antoshkka
ilnur.khuziev, скорее всего так и получится в конечном итоге. В стандарте нельзя прописывать флаги компилятора, но разработчики компилятора, как мне кажется, проявят инициативу.
yndx-antoshkka
konyuchenko.nikita
Вообще говря, в стандарте нет понятия стека как такового и не оговорено, что он вообще может и должен существовать. Есть понятие stack unwinding, которое относится скорее к процессу вызова деструкторов.
Еще вопрос - какой ожидаемый вывод при оптимизациях? Такой же как, например, libunwind, получаемый проходом по стеку и попыткой определить что определенный адрес мог быть адресом возврата, или же подразумевается дополнительная работа компилятора по подготовке метаданных? С оптимизацией хвостовых рекурсий что делать?
konyuchenko.nikita
yndx-antoshkka
konyuchenko.nikita, в стандарте придётся сурово пожонглировать словами, чтобы описать stacktrace. Сложно, но можно.

Компилятор метаданные подготавливать не должен, все данные есть в дебажной секции бинарника и в таблицах экспортов. Стектрейс будет показываться и для оптимизированного кода. В случае с оптимизацией хвостовой рекурсии, часть вызовов может убраться из стектрейса, но строчка, где конструировался стектрейс будет показываться верно... Другими словами - 1 в 1 поведение gdb bt
yndx-antoshkka
Сергей Прейс
konyuchenko.nikita, Полностью согласен. Кроме того, никак не стандартизовано как стек связан с именами функций, так что не ясно как специфицировать что именно должен печатать этот класс.
Сергей Прейс
Сергей Прейс
yndx-antoshkka, понятия дебажной таблицы нет в C++ стандарте равно как и таблицы экспортов. Это всё регулируется ABI конкретной платформы и может принципиально отсутствовать.
Сергей Прейс
Ilia
Похоже стоит различать символизацию и получение stacktrace, как это делает POSIX и WinAPI.
Символизировать стек гораздо дольше, чем получить набор указателей на фреймы/функции.
Ilia
yndx-antoshkka
udalovilia, в прототипе эти понятия разнесены и выполняются независимо друг от друга.
yndx-antoshkka
Anatoly Scheglov
Нет и не нужно. Вывод стектрейса - это не то, что каждый разработчик пишет каждый день.
Для случаев когда это надо, есть готовые библиотеки (в т.ч. системные).
Anatoly Scheglov
yndx-antoshkka
Anatoly Scheglov, покажите мне пожалуйста эти библиотеки
yndx-antoshkka
iloskutov
Уже есть, например, Boost.Stacktrace, поддерживающий несколько бэкендов. Если с его функциональностью что-то не так — окей, можно засабмитить им Issue, но стандарт-то тут при чём?

Как уже заметили, стандарт не определяет ни понятия стека, ни стектрейса, а компиляторы охотно инлайнят функции и оптимизируют хвостовую рекурсию, так что гарантий про такой стектрейс нельзя дать практически никаких. Чтобы это могло стать частью стандарта, надо переписать значительную его часть в терминах стека и дать в нём ряд гарантий, ограничивающих оптимизатор (и, как следствие, его эффективность).
iloskutov
yndx-antoshkka
iloskutov, Boost.Stacktrace я писал в качестве прототипа для принятия в стандарт C++. И на главной страницу Boost во втором параграфе прям написано - "Задача Boost - создавать reference implementations для принятия в стандарт С++"

Пользуясь вашей логикой, из стандарта надо убрать std::thread, std::shared_ptr, std::unique_ptr, std::atomic, std::string_view, std::variant. Ведь они же уже реализованы в сторонних библиотеках, а до 2011 года стандарт вообще не говорил про многопоточность :)

И да, если Boost.Stacktrace не накладывает ограничений на оптимизатор, то чего ради должен накладывать ограничения stacktrace из стандартной библиотеки?
yndx-antoshkka
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).