2015-01-25 2 views
2

Как проверить, является ли функция частью ядра или пользовательского пространства? (или могут быть оба) Есть ли обзор всех файлов/функций ядра?Как узнать, является ли функция частью режима ядро ​​/ пользователь?

Работа с C в среде Unix.

например. rand() - это свободное пространство пользователя, malloc() - это пространство пользователя и ядра и т. Д.

Страницы руководства не содержат никакой информации.

+1

Почему вы должны знать? –

+0

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

+0

Все функции, вызываемые из пользовательского пространства, являются функциями «пользовательского режима». Они * могут * однако вызвать ядро. Чтобы обойти это: вы не можете напрямую использовать функциональность ядра из пользовательского пространства. – alk

ответ

1

This статья должна предоставить вам некоторую информацию о системных вызовах (в пространстве ядра). Теперь вы можете использовать эту грубую (и не очень точную) рекомендацию:

  1. Все страницы руководства из раздела 2 являются системными вызовами.

  2. Если человек страница из раздела 3, смотрите в также часть в нижней части, чтобы увидеть, если он использует какие-либо команды из раздела 2. (Может также необходимо прочитать сам человек стр.)

Опять же, это не очень точная информация, но при чтении исходного кода она должна дать вам представление.

+0

[That] (http://linux.die.net/man/) помог мне! Не знал, что вызов функции делится на группы. – Leviathan

+0

Хех, я думал добавить это позже, но не обошел его :) Спасибо, что принял мой ответ. –

0

В течение всего времени выполнения процесс вычисляет множество системных вызовов, начиная даже до его фактического запуска.

У вас есть несколько вариантов для отладки тех:

  • пересобрать glibc с отладочной информацией
  • strace
  • gdb

Третий вариант, вероятно, является лучшим вариантом, особенно если вас интересует только одна функция, а не набор функций (где strace было бы лучше). Действительно, gdb позволяет поймать системные вызовы, сделанные присоединенным процессом или некоторыми конкретными; вы можете получить это с catch syscallномер или catch syscall, чтобы поймать их всех.

Возможно, вы также захотите избежать вызовов, выполняемых динамическим компоновщиком во время выполнения, скомпилировав код с помощью -static.

0

Зависит от того, что вы называете «режимом ядра». Если бы я понял вас правильно, вы имеете в виду, что некоторые функции C просят что-то сделать, например malloc() вызывает brk(), поэтому ядро ​​увеличит размер кучи процесса.

Итак, все, что вам нужно, это определить, какие функции задают что-то из ядра, которое обычно выполняется, вызывая Системный вызов, такой как brk().

Теперь пришло время определить, какие функции вызывают, какие системные вызовы. Есть два способа сделать это:

  • Статический код Analys.Просто создайте callgraph glibc, а затем постройте графики, в которых root - это syscall. Единственная проблема - сложность glibc, поэтому было бы сложно построить весь callgraph.
  • Анализ динамического кода. Прикрепите отладчик/трассировщик к вашему процессу, а когда процесс вызовет системный вызов, распечатайте его стек. Этот подход не охватывает все функции и случаи, но их легко реализовать.

I.e. Использование GDB:

[email protected]:~> gdb /bin/cat 
... 
(gdb) b brk 
Function "brk" not defined. 
Make breakpoint pending on future shared library load? (y or [n]) y 
(gdb) commands 1 
> bt 
> cont 
> end 
(gdb) r 
Starting program: /bin/cat 

... 

Breakpoint 1, __brk (addr=0x62d000) at ../sysdeps/unix/sysv/linux/x86_64/brk.c:28 
28  in ../sysdeps/unix/sysv/linux/x86_64/brk.c 
#0 __brk (addr=0x62d000) at ../sysdeps/unix/sysv/linux/x86_64/brk.c:28 
#1 0x00007ffff7b0eea5 in __GI___sbrk (increment=135168) at sbrk.c:53 
#2 0x00007ffff7aaeda9 in __GI___default_morecore (increment=<optimized out>) at morecore.c:48 
#3 0x00007ffff7aaaa37 in sysmalloc (av=0x7ffff7dd5640 <main_arena>, nb=32) at malloc.c:2454 
#4 _int_malloc (av=0x7ffff7dd5640 <main_arena>, bytes=5) at malloc.c:3718 
#5 0x00007ffff7aac263 in __GI___libc_malloc (bytes=5) at malloc.c:2859 
... 
#10 0x0000000000401d8a in main (argc=1, argv=0x7fffffffdd08) at cat.c:563 

Или какой-нибудь динамичный двигатель трассировка, такие как Systemtap (Linux):

# stap -e ' 
     probe syscall.brk { 
      if(pid() == target()) 
       print_ubacktrace(); 
     } ' -c /bin/cat -d /lib/x86_64-linux-gnu/libc.so.6 
... 
0x7f5edb427ffa : brk+0xa/0x70 [/lib/x86_64-linux-gnu/libc-2.13.so] 
0x7f5edb4280ad : sbrk+0x4d/0xb0 [/lib/x86_64-linux-gnu/libc-2.13.so] 
0x7f5edb3d0ae9 : __default_morecore+0x9/0xb0 [/lib/x86_64-linux-gnu/libc-2.13.so] 
0x7f5edb3cd1e6 : malloc_trim+0x15e6/0x23c0 [/lib/x86_64-linux-gnu/libc-2.13.so] 
0x7f5edb3cec00 : malloc+0x70/0x340 [/lib/x86_64-linux-gnu/libc-2.13.so] 
... 
0x401bea [/bin/cat+0x1bea/0xc000] 

Или DTrace:

[email protected]:~# dtrace -n ' 
      syscall::brk:entry 
      /pid == $target/ { 
       ustack() 
      }' -c '/bin/cat' 
CPU  ID     FUNCTION:NAME 
0  58      brk:entry 
      libc.so.1`_brk_unlocked+0x15 
      libc.so.1`sbrk+0x38 
      ... 
      libc.so.1`malloc+0x38 
      libc.so.1`strdup+0x29 
      libc.so.1`expand_locale_name+0x333 
      libc.so.1`setlocale+0x89c 
      cat`main+0x23 
      cat`_start+0x7d 
Смежные вопросы