2012-02-08 10 views
4

Есть ли способ узнать, какие функции из стандартной библиотеки C выполняют системные вызовы? Некоторые из них, например, open, close и malloc очевидны, но есть ли какой-то список, на который можно посмотреть? Как, например, strcpy сделать системный вызов или любую из функций в time.h?C стандартная библиотека и системные вызовы

+2

Вероятно, это зависит от реализации. Существует ли какая-то конкретная система? – templatetypedef

+0

ugh ... это то, чего я боялся. :( – theshadow322

+0

malloc() не всегда выполняет системные вызовы. – tristan

ответ

7

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

Теперь, хотя это зависит от реализации (это зависит от реализации, независимо от того, существуют ли «системные вызовы»), хороший способ рассуждать и делать обоснованное предположение - рассматривать «системный вызов» как значение «пользовательский», to-kernel-to-user ", так как это действительно системный вызов.

Рассмотрите ваш пример strcpy. Он копирует строку из одного массива (в пространстве вашего процесса) в другой массив (также в вашем пространстве памяти). Ничто из того, что он делает, не содержит никаких данных, кроме этих строк, поэтому было бы довольно патологически вводить пространство ядра в рамках этой операции.

С другой стороны, рассмотрим функцию time от time.h. Он возвращает текущее системное время. Это общий системный ресурс, поэтому вы можете ожидать, что ему потребуется ввести пространство ядра, чтобы прочитать запись ядра о текущем времени. И традиционно, вы были бы правы. Однако современные версии Linux, по крайней мере, на некоторых арках, отображают страницу памяти ядра в каждый пользовательский процесс как доступную только для чтения - страницу, содержащую определенную информацию, которую может обновлять только ядро, например, системное время, но все процессы могут свободно читать из пользовательского пространства без утечки каких-либо секретных данных. Так что этот вопрос более двусмыслен.

Наконец, у вас есть такие операции, как open или unlink что должны обязательно включают переход пользователя к ядру-пользователю, потому что они имеют дело с разделяемыми ресурсами (в файловой системе), на котором должно быть насильственными разрешение.

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

+0

Даже 'open' не обязательно включает в себя переход ядра. В старых версиях Windows, если вы открыли дескриптор файла консоли (например, «CONIN $»), вы получите постоянный дескриптор (что означает «текущий поток текущей консоли»), возвращенный заглушкой пользовательского режима. Я не знаю, верно ли это. – arx

+0

Я принимал версию 'open', которая соответствует POSIX. Возвращение дескриптора файла, соответствующего уже открытому, нигде рядом не соответствует ... –

1

Системный вызов выполняется, когда вашей программе необходимо установить связь с ядром. Было бы крайне неэффективно для strcpy сделать системный вызов, так как для этого требуется interupt; ваш код перестает работать, есть переключатель контекста, режим выполнения CPU изменяется (чтобы иметь больше привилегий), обработчик interupt будет работать, и ваш код будет продолжен. Предполагается, что ОС не решит запустить другой процесс после того, как вы перепутаете или полностью сработаете свой код (например, при ожидании чтения).

Вы можете в значительной степени ответить на вопрос самостоятельно, спросив себя: могу ли я написать эту функцию? (Может как в: это физически возможно?) Вы можете написать свой собственный strcpy, но не открыть или прочитать. Вы можете написать свой собственный fopen, но он должен был бы назвать открытым.

В Википедии есть list of catagories for system calls. Это даст вам представление о том, когда требуется системный вызов.

This показывает, как вызвать interupt в сборке (это единственное место, где вы сможете достичь кода, который делает это).

+0

+1 Мне нравится «Могу ли я написать эту функцию?» подхода в качестве образовательного инструмента. Обратите внимание на угловой случай, когда он не полностью работает, пример «времени», который я дал. (Если вы знаете, что ядро ​​отображает необходимые данные в памяти пользовательского пространства и знает формат, вы «можете» писать «время», но он будет хрупким, поскольку детали ядра могут измениться. Таким образом, вам нужно использовать код, предоставленный ядром если вы хотите избежать syscall.) –

Смежные вопросы