Быстрый мысленный эксперимент, прежде чем перейти к вопросу.Представьте, что кто-то реализует std :: malloc (скажем, один из людей JEMalloc или TCMalloc).Одной из самых основных вещей, которые им понадобятся, является способность знать, что программа не будет вызывать обратно в malloc после того, как выполнение вступит в реализацию std :: malloc.
Например,
void* malloc(...) {
auto lck = std::unique_lock{malloc_mutex};
// .. memory allocation business logic
}
Теперь, если есть сигнал между блокировкой и бизнес-логикой для распределения, мы можем заблокировать, если обработчик сигнала вызывает обратно в std :: malloc,Он не предназначен для повторного входа, стандарт C ++ требует, чтобы обработчик сигнала, зарегистрированный с помощью std :: signal, не вызывал обратно в оператор new (который, возможно, может вызывать обратно в malloc, поэтому требуется, чтобы определяемый пользователем сигналобработчик не перезванивает в malloc, если он считается переносимым во всех реализациях языка).
§ [support.signal]p3
в самой последней версии стандарта излагается это требование
Оценка безопасна для сигнала, если она не включает одно из следующего:
вызов любой стандартной библиотечной функции, за исключением простых атомарных операций без блокировки и функций, явно определенных как безопасные для сигнала,[Примечание: Это неявно исключает использование выражений new и delete, использующих распределитель памяти, предоставляемый библиотекой. - примечание к концу]
Однако стандарт C ++, по-видимому, ничего не говорит о том, как должны быть реализованы стеки функций для потоков выполнения (см. Этот вопрос: Диапазон адресов стека потоков C ++ ), это означает, что функция диспетчеризируется в пределах std :: mallocреализация может вызвать operator new
, если программа скомпилирована с сегментированными стеками.
Как можно реализовать такую функцию, как std::malloc
в этом случае?Если действительно, стандарт C ++ не дает таких гарантий, то что же?Как мы можем знать, что реализация обычной функции проходит через процесс выделения обычного стека (приращение указателя стека)?Какой стандарт (например, ABI, компилятор, POSIX) покрывает это?