Можно ли свободно использовать сегментированные стеки с другими библиотеками

Насколько я понимаю, сегментированные стеки создаются с поддержкой компилятора, поэтому всякий раз, когда функция, работающая в сегментированном стеке, вызывает другую функцию, if сначала проверяет, достаточно ли в стеке места для кадра стека для этой новой функции. И если это не так, к этой функции подключается другой сегментированный стек, и код переходит к этой функции.

Но работает ли это, если, например, у меня запущено волокно, и я вызываю другую функцию из другой общей (или скомпилированной в неразделяемый объектный файл) библиотеки, которая не была скомпилирована с параметром -fsplit-stack? Как функции в этой библиотеке узнают, что им нужно будет проверить, достаточно ли места в сегментированном стеке для продолжения работы?

Интересуют только реализации clang и gcc (и, в частности, с контекстом boost), спасибо!


person Curious    schedule 19.11.2017    source источник
comment
Мне кажется, что этот вопрос уже обсуждался несколько раз раньше. Я понимаю, что вам нужно дополнительное подтверждение, но, честно говоря, я не понимаю, почему вы ожидаете, что кто-то сможет предоставить его на этот раз, когда этого не произошло в прошлые разы.   -  person sehe    schedule 19.11.2017
comment
@sehe эти вопросы были другими. Какой конкретно вы имеете в виду?   -  person Curious    schedule 19.11.2017
comment
Я не сразу это замечаю, но я выделил разделы, которые, как я помню, отвечают на ваш текущий вопрос. Возможно, я неправильно помню некоторые вещи, которые я читал в частном порядке в ходе дискуссий, которые происходили в то время.   -  person sehe    schedule 19.11.2017


Ответы (1)


Я собираюсь вернуться к части документации, которую я помню, видел в более раннем вопросе по этой теме:

Обратная совместимость

Мы хотим иметь возможность использовать программы с разделенным стеком в системах с готовыми библиотеками, скомпилированными без разделенных стеков. Это означает, что нам нужно убедиться, что в стеке достаточно места, прежде чем вызывать любую такую ​​функцию.

Каждый объектный файл, скомпилированный в режиме разделенного стека, будет снабжен аннотацией, указывающей, что функции используют разделенные стеки. Это, вероятно, должно быть аннотировано примечанием, но в GNU as нет общей поддержки для создания произвольных заметок. Поэтому каждый объектный файл, скомпилированный в режиме разделенного стека, будет иметь пустой раздел со специальным именем: .note.GNU-split-stack. Если объектный файл, скомпилированный в режиме разделенного стека, включает некоторые функции с атрибутом no_split_stack, то объектный файл также будет иметь атрибут .note.GNU-no-split-stack section. Это сообщит компоновщику, что некоторые функции могут не иметь ожидаемого пролога с разделенным стеком.

[...]

Для вызовов кода с разделенным стеком на код без разделения стека компоновщик изменит начальные инструкции в функции разделения стека (вызывающей). Это означает, что компоновщик должен обладать специальными знаниями. инструкций, которые выдает компилятор. Результатом изменений будет увеличение требуемого размера кадра на число, достаточное для разумной работы с неразделенным стеком. Это будет число, зависящее от цели; по умолчанию будет что-то вроде 64 КБ. Обратите внимание, что этот большой стек будет освобожден, когда функция разделения стека вернется. Обратите внимание, что я не рассматриваю случай, когда код с разделенным стеком в общей библиотеке вызывает код без разделения стека в основном исполняемом файле; это кажется маловероятной проблемой.

Я специально помню список (выделенный курсивом) оговорка - я не помню, это я выделил его или кто-то другой. Ключевое слово в этом обсуждении было об обратных вызовах.

person sehe    schedule 19.11.2017
comment
Итак, вы думаете, что это плохо, когда функция сегментированного стека вызывает другую в другой разделяемой библиотеке? Поскольку это своего рода предполагает угадывание? - person Curious; 19.11.2017
comment
Это не предполагает угадывания. Компоновщик знает и генерирует достаточно кода, чтобы он не сломался. Однако это будет неоптимально (это может сильно повредить многократно вызываемым функциям). Часть, где это пойдет не так (опять же, НЕ предположение, просто детерминистически неверно), - это когда вы передаете внешней библиотеке с разделенным стеком обратный вызов в свою основную программу, которая не является разделенным стеком. Это НЕ будет обнаружено компоновщиком. - person sehe; 19.11.2017
comment
М-м-м. Я, вероятно, не должен говорить обратный вызов (поскольку это может подразумевать указатели функций, что является отдельной проблемой, упомянутой непосредственно ниже в документах). На самом деле они, вероятно, возвращаются к вашему коду без разделения стека через динамическую связь (экспортированные символы, импортированные из библиотеки с разделенным стеком через -rdynamic) - person sehe; 19.11.2017
comment
Когда вы передаете внешней библиотеке с разделенным стеком обратный вызов в свою основную программу, которая не является разделенным стеком, чем этот случай отличается от функции с разделенным стеком, вызывающей другую функцию без разделения стека? Это был тот случай, о котором я изначально хотел спросить. Не думаю, что я понимаю :( - person Curious; 19.11.2017
comment
Это обратная совместимость, а не прямая совместимость. Split-stack знает о разделенных стеках, поэтому может подстраиваться при вызове не-splitstack. Наоборот, это не так (код без разделения стека мог быть скомпилирован компилятором, который вообще не знает о коде с разделенным стеком) - person sehe; 19.11.2017
comment
О, понятно, но что, если функция, которую вы вызываете из кода разделенного стека, занимает в стеке более 64 КБ? - person Curious; 19.11.2017
comment
Затем вы получаете переполнение стека, как и везде (iirc размер стека pthreads по умолчанию составляет ~ 8 КБ) - person sehe; 19.11.2017