Замена системных вызовов (syscalls) в Linux 2.6+

Я собираюсь написать пользовательскую библиотеку потоков, так как, похоже, в этой области нет активной работы, и я верю, что C++0x обещает и фьючерсы могут придать этой модели некоторую силу. К сожалению, для того, чтобы эта модель работала, необходимо обеспечить переключение контекста при блокировке вызовов. Таким образом, я хотел бы перехватывать каждый системный вызов, чтобы заменить его асинхронной версией. Есть некоторые предостережения:

  • Я знаю, что почти для каждого обычного системного вызова существуют асинхронные системные вызовы, но по соображениям обратной совместимости это не является жизнеспособным решением.
  • Я знаю, что в Linux 2.4 или более ранних версиях можно было напрямую изменить sys_call_table, но это исчезло.
  • Поскольку я хотел бы, чтобы моя библиотека была при желании статически связана, трюк LD_PRELOAD нежизнеспособен.
  • Точно так же модули ядра не подходят, поскольку предполагается, что это пользовательская библиотека.
  • Наконец, ptrace() также не подходит по тем же причинам. Я не могу, чтобы моя библиотека разветвляла новый процесс только для того, чтобы ее можно было использовать.

Это возможно?


person tgoodhart    schedule 18.06.2011    source источник
comment
Мне кажется, что вопрос связан не столько с системными вызовами, сколько с механизмом связывания. Поскольку обычно никто не вызывает системные вызовы в коде сборки, вы просто хотите заменить некоторые общие функции своими собственными во время компоновки.   -  person Radim Vansa    schedule 07.07.2011
comment
Вы знаете, интересно, возможно ли, чтобы процесс ptrace сам сделал это возможным? Даже если это не так, вы можете изучить, как strace перехватывает системные вызовы.   -  person Omnifarious    schedule 08.11.2011


Ответы (1)


Я пытаюсь написать библиотеку потоковой обработки пользовательской среды, поскольку в этой области, похоже, нет активной работы.

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

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

person Kevin    schedule 23.09.2011
comment
На самом деле я смотрел на Марселя, но, к сожалению, его лицензия несовместима с тем, чем я занимаюсь. Более того, то, что вы опубликовали, предполагает, что они используют трюк LD_PRELOAD и/или используют общие библиотеки. Тем не менее, Марсель выглядит довольно мило, так что, надеюсь, у кого-то еще будут менее строгие требования, чем у меня. - person tgoodhart; 23.09.2011