неортодоксальное ядро ​​Linux и Valgrind - PullRequest
3 голосов
/ 23 февраля 2012

Прежде всего, позвольте мне извиниться, если я пишу это не в том месте. Кажется, я не могу найти форум пользователей valgrind, на котором можно публиковать подобные материалы, и, поскольку это место кажется довольно всеобъемлющим, я решил попробовать его.

У меня несколько необычное ядро ​​Linux, которое мне нужно использовать при запуске моего кода. Я не знаю слишком много о ядре, особенностях, так как я не писал его. По какой-то причине мое ядро ​​выглядит так, будто оно расширяет таблицу системных вызовов ядра Linux по умолчанию. По-видимому, происходит следующее: при insmod файла .ko текущая стандартная таблица системных вызовов расширяется, начиная с значения, равного 333, и заканчивая 341, с сохранением исходной таблицы системных вызовов и восстановлением, когда файл .ko Это модмодирование. Эти дополнительные системные вызовы, кажется, выполняют своего рода уникальную связь IPC с проприетарное программное обеспечение, которое я использую.

Конечно, это похоже на ад в Вальгринде.

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

==26045== Thread 2:
==26045== Syscall param preadv(vector) points to unaddressable byte(s)
==26045==    at 0x4000982: ??? (in /lib/ld-2.9.so)
==26045==    by 0x426C756: syscall (in /lib/libc-2.9.so)
==26045==    by 0x4037430: com_lock (coms.c:114)


--23932-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--23932-- si_code=1;  Faulting address: 0x165;  sp: 0x63a6dde4

valgrind: the 'impossible' happened:
   Killed by fatal signal
==23932==    at 0x3809D5E0: vgSysWrap_linux_sys_preadv_before (syswrap-linux.c:3413)
==23932==    by 0x380785CB: vgPlain_client_syscall (syswrap-main.c:1382)
==23932==    by 0x38076330: vgPlain_scheduler (scheduler.c:929)
==23932==    by 0x380A13E8: run_a_thread_NORETURN (syswrap-linux.c:98)
==23932==    by 0x380A1732: vgModuleLocal_start_thread_NORETURN (syswrap-linux.c:268)
==23932==    by 0x380A8AC8: ??? (in /usr/local/lib/valgrind/memcheck-x86-linux)

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

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

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

Я использую valgrind 3.7, с g ++ 4.1.1 и специальным ядром, собранным из 2.6.29 gentoo (для всех намерений и целей, это 2.6.29 gentoo, пока мой собственный модуль ядра не будет загружен)

Edit:

Я обнаружил еще несколько вещей, связанных с этим, с тех пор как я впервые написал. Похоже, что в valgrind есть файл include / vki / vki-scnums-x86-linux.h. В соответствии с комментариями в нем (здесь запомнился valgrind 3.7.0), это более или менее фрагмент asm-i386 / unistd.h из ядра 2.6.9. При перечислении инструкций 333 определяется __NR_preadv. Для меня valgrind умирает, когда он выполняет системный вызов для чего-то, называемого my_ipc, который является уникальным для моего ядра системным вызовом, перечисленным не иначе как 333. Похоже, что существует ошибка отображения системного вызова между тем, против чего был скомпилирован valgrind, и тем, что на самом деле происходит в ядре. Таким образом, оболочка syscall valgrind пытается вызвать, когда видит, что syscall 333 не может обработать syscall 333, поскольку подпись вызова функции, вероятно, не совпадает.

Я думаю, что preadv выглядит как ...

preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);

и из того, что я могу сказать, мой вызов ipc выглядит как

asmlinkage long my_ipc (uint, long, long, long, long, long);

1 Ответ

3 голосов
/ 23 февраля 2012

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

Файл README_MISSING_SYSCALL_OR_IOCTL в корне дерева исходных текстов valgrind - лучшее место для начала, чтобы узнать, как добавить упаковщик системных вызовов в valgrind.

Чтобы ответить на ваш вопрос о форумах Valgrind, есть списки рассылки или IRC-канал #valgrind на freenode.

...