почему strace не использует тестовые системные вызовы, чтобы узнать их индексы в таблице системных вызовов?

256
user322908

Я понимаю, что эта straceкоманда используется ptrace(PTRACE_PEEKUSER, child, __builtin_offsetof(struct user, regs.orig_eax))для поиска индекса системного вызова, в который попадает дочерний элемент трассировки. Затем, чтобы перевести индекс в имя функции syscall, он построил таблицы, сделанные на основе поиска заголовков исходного кода linux, присутствующих в установке.

Этот метод должен быть недокументированным и склонным к сбою, поскольку расположение и синтаксис объявлений исходного кода не документированы, должны быть найдены с помощью grepping и могут изменяться неизвестными способами. Я правильно сказал это?

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

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

Я уверен, что этот метод должен быть рассмотрен, так как он не является чем-то особенно гениальным. Так что должно быть что-то не так с этим. Что случилось??

1
Как бы они выполняли эти тестовые системные вызовы, кроме как с использованием констант из заголовков system / kernel? R.. 8 лет назад 0
Также «первый запуск после перезагрузки» - это концепция, которая вообще не имеет смысла. Как он вообще узнает такую ​​вещь? R.. 8 лет назад 0
@Р.. ?? `open (foobar.txt, O_RDONLY)` не требуется никаких документов user322908 8 лет назад 0
@R .. что касается "первого запуска", я просто не хотел рисковать ситуацией, когда кто-то меняет некоторые заголовки, перекомпилирует ядро ​​и перезагружается с новым ядром (что, кстати, может сломать текущую `strace '). `Я верю). Поэтому мне нужно убедиться, что я сохраню таблицу, потому что я не хочу вычислять ее каждый раз, когда вызывается `strace`, а затем стирается при перезагрузке. Конечно, в Linux должен быть способ определить, звонят ли мне в первый раз после перезагрузки. Наверняка должен быть какой-то файл, который был затронут / создан после перезагрузки, чтобы я мог сравнить свою метку времени с ней? user322908 8 лет назад 0
@R .. например, системный вызов `sysinfo` скажет мне, сколько времени прошло с тех пор, как я загрузился, а затем, сравнивая его с меткой времени файла, в котором я хранил таблицу, я знаю, нужно ли стереть файл и начать заново. user322908 8 лет назад 0
Откуда вы знаете, что `open (foobar.txt, O_RDONLY)` дает ровно один системный вызов, и это `SYS_open`? Он может использовать `SYS_openat`. Это может привести к тому, что другие системные вызовы будут выполняться как часть отложенного связывания в динамическом компоновщике, если это первый вызов `open`. Или это может быть связано с другими системными вызовами внутри для какой-то другой цели. Не существует тривиального взаимно-однозначного сопоставления между библиотечными и системными вызовами. R.. 8 лет назад 1
Если вы думаете, что определения номеров системных вызовов могут измениться после перезагрузки, у вас есть серьезные недоразумения, которые могут объяснить, почему вы задаете этот вопрос для начала. Они являются абсолютной постоянной частью публичного API / ABI ядра. Чтобы их не было, двоичные файлы, созданные для одного ядра, не могли быть использованы для другого. R.. 8 лет назад 0
@R ... Ладно, я понимаю, что вы хотите сказать, что между вызовами lib и вызовами sys нет однозначного соответствия. Отлично. Я не понимаю вторую часть, где вы говорите «абсолютная часть общедоступного API ядра». Если это так, то можете ли вы указать мне, где задокументирован этот API, где написано «на платформе то или иное, открытый системный вызов - это индекс 2» или что-то в этом роде. user322908 8 лет назад 0
@R .. конечно, у меня есть недопонимание. Если бы у меня было прекрасное понимание, я бы не задавал этот вопрос, а отвечал. Ваш комментарий неуместен. user322908 8 лет назад 0
@R .. На этой странице документации man7.org/linux/man-pages/man2/syscalls.2.html четко сказано, что я могу вызывать определенные библиотечные функции, и это приведет к соответствующему системному вызову (в конце). user322908 8 лет назад 0
Справочные страницы не являются нормативными. Они должны быть описательными, но иногда описания не совсем верны. Если вы считаете, что этот текст вводит в заблуждение, отправьте отчет об ошибке в проект man-страниц Linux. R.. 8 лет назад 0
Насчет фиксированных номеров системных вызовов - это просто политика стабильности Linux. В системах без такой политики у вас не будет обратной совместимости, и любые двоичные файлы, использующие числа системных вызовов (это означает, что любые статические двоичные файлы, а также динамические двоичные файлы, использующие функцию `syscall ()`) будут привязаны к конкретному ядру. версия, для которой они были построены. Вы можете найти политику стабильности Linux где-нибудь в документации ядра, но это даже не нужно указывать; это просто самый простой здравый смысл о совместимости. R.. 8 лет назад 0
@R .. Мало того, но исторически изменения в таблице системных вызовов включают только добавление и удаление новых системных вызовов. В таблице много пробелов, в которых устаревшие и окончательно удаленные системные вызовы просто больше не существуют (и вызывают `-ENOSYS`). Таблица никогда не была «сдвинута» так, что значение системного вызова изменяется. Фактически, когда системный вызов должен измениться, добавляется новая версия с аналогичным именем. forest 5 лет назад 0

1 ответ на вопрос

1
forest

Потому что не существует понятия имени системного вызова на том низком уровне. Нет никакого способа straceсказать «Эй, давай fcntl()позвоним и посмотрим, что это за номер!». Он может совершать звонки только на основе номеров системных вызовов. Это связано с тем, что системный вызов выполняется, когда номер системного вызова сохраняется в регистре eaxили rax, а процесс вызывает int 0x80или syscall.

Похожие вопросы