График функции (вход и выход с отметкой времени) для пользователя, библиотеки и пространства ядра в Linux?

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

Я хотел бы проанализировать, что происходит с функцией из ALSA, скажем, snd_pcm_readi; для этого, скажем, я подготовил небольшой testprogram.c где у меня это:

void doCapture() {
  ret = snd_pcm_readi(handle, buffer, period_size);
}

Проблема с этой функцией заключается в том, что она в конечном итоге (должна) подключиться к snd_pcm_readi в общей системной библиотеке /usr/lib/libasound.so; оттуда я верю через ioctl было бы как-то общаться с snd_pcm_read в модуле ядра /lib/modules/$(uname -r)/kernel/sound/core/snd-pcm.ko - и это должно в конечном итоге говорить с чем угодно .ko модуль ядра, который является драйвером для конкретной звуковой карты.

Теперь, с организацией, как указано выше, я могу сделать что-то вроде:

valgrind --tool=callgrind --toggle-collect=doCapture ./testprogram

... а потом kcachegrind callgrind.out.12406 действительно показывает связь между snd_pcm_readi, libasound.so и ioctl (Я не могу получить ту же информацию, чтобы показать с callgrind_annotate) - так, что несколько охватывает пользовательское пространство; но это так далеко, как это идет. Кроме того, он генерирует граф вызовов, то есть общие отношения вызывающего / вызываемого абонентов между функциями (возможно, путем подсчета выборок / тиков, которые каждая функция потратила на работу по графику).

Тем не менее, то, что я хотел бы получить вместо этого, это что-то вроде вывода Linux ftrace трассировщик называется function_graph, который обеспечивает временную отметку входа и выхода отслеживаемых функций ядра... пример из ftrace: добавить документацию для функции graph tracer [LWN.net]:

$ cat /sys/kernel/debug/tracing/trace
# tracer: function_graph
#
#      TIME       CPU  DURATION                  FUNCTION CALLS
#       |         |     |   |                     |   |   |   |
 2105.963678 |   0)               |      mutex_unlock() {
 2105.963682 |   0)   5.715 us    |        __mutex_unlock_slowpath();
 2105.963693 |   0) + 14.700 us   |      }
 2105.963698 |   0)               |      dnotify_parent() {

(NB: новее ftrace сначала документация не показывает временную метку для function\_graph, только продолжительность - но я думаю, что это все еще можно изменить)

С ftrace можно фильтровать, чтобы можно было только отслеживать функции в данном модуле ядра - так что в моем случае я мог бы добавить функции snd-pcm.ko и все .ko Модуль - это драйвер звуковой карты, и я хотел бы, чтобы все, что я нахожу интересным, охватывало пространство ядра. Но затем я теряю ссылку на программу пользовательского пространства (если я явно не printf в /sys/kernel/debug/tracing/trace_marker или сделать trace_printk из пространства пользователя .c файлы)

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


Как PS: кажется, я действительно нашел то, что соответствует описанию, которое является fulltrace Приложение / скрипт:

fulltrace [andreoli @ Github]

fulltrace отслеживает выполнение программы ELF, предоставляя в качестве вывода полную трассировку вызовов ее пользовательского пространства, библиотеки и функций ядра....
(предварительные условия) следующие включенные параметры конфигурации ядра и их зависимости должны быть включены (=y): FTRACE, TRACING_SUPPORT, UPROBES, UPROBE_EVENT, FUNCTION_GRAPH_TRACER.

Звучит идеально - но проблема в том, что я на Ubuntu 11.04, и пока это 2.6.38 Ядро, к счастью, имеет CONFIG_FTRACE=y включен - его /boot/config-`uname -r` даже не упоминает UPROBES: / Так как я хотел бы избежать взлома ядра, к сожалению, я не могу использовать этот скрипт...

(Между прочим, если бы UPROBES были доступны, (насколько я понимаю) каждый устанавливает зонд трассировки на адрес символа (как получено из, скажем, objdump -d ), и вывод снова идет в /sys/kernel/debug/tracing/trace - так что некоторые нестандартные решения были бы возможны с использованием UPROBES, даже без fulltrace сценарий)

Итак, чтобы немного сузить мой вопрос - есть ли решение, которое позволило бы одновременно выполнять трассировку "графа функций" в пространстве пользователя (включая разделяемые библиотеки) и в пространстве ядра, но где UPROBES не доступны в ядре?

0 ответов

Другие вопросы по тегам