Большое спасибо @fche за то, что указал мне правильное направление. По его словам, функция symdata()
systemtap
может использоваться для получения информации о символе по заданному адресу, включая размер. Таким образом, мы можем написать нашу собственную функцию sizeof()
, которая анализирует ее для извлечения размера следующим образом:
function sizeof(address:long) {
tokenize(symdata(address), "/");
return strtol(tokenize("",""),16);
}
Если мы посмотрим на определение этой функции symdata()
, то увидим, что она сама является функцией systemtap
, использующей функцию _stp_snprint_addr()
C, которая сама вызывает _stp_kallsyms_lookup()
для извлечения данных. Это означает, что мы также можем определить собственный sizeof()
, используя stp_kallsyms_lookup()
напрямую:
function sizeof:long (addr:long) %{ /* pure */ /* pragma:symbols */
STAP_RETVALUE = -1;
_stp_kallsyms_lookup(STAP_ARG_addr, (unsigned long*)&(STAP_RETVALUE), NULL, NULL, NULL);
%}
(обратите внимание, что здесь нам нужен -g
(guru), так как мы используем встроенный C).
Теперь, чтобы получить размер массива, нам нужны размеры элементов массивов. Один из подходов может заключаться в использовании смещения адреса между двумя элементами массива. Таким образом, мы могли бы определить нашу функцию array_size()
как:
function array_size(first:long, second:long) {
return sizeof(first) / (second - first);
}
(где sizeof()
— это одна или другая из функций, определенных выше).
И назовите это как:
probe begin {
printf("%d\n", array_size(
&@var("unix_socket_table@net/unix/af_unix.c")[0],
&@var("unix_socket_table@net/unix/af_unix.c")[1]));
exit();
}
Что дает нам 512
, как и ожидалось.
Для sizeof()
другим подходом может быть использование оператора C sizeof()
:
$ sudo stap -ge '
%{ #include <net/af_unix.h> %}
probe begin {
printf("%d\n", %{ sizeof(unix_socket_table)/sizeof(unix_socket_table[0]) %} );
exit();
}'
512
(также требуется -g
), но тогда информация извлекается из исходного кода ядра (заголовочные файлы), а не из отладочной информации, поэтому, хотя это будет работать для массивов ядра, определенных в заголовочных файлах, этот подход не обязательно будет работать для всех массивов. .
person
Stephane Chazelas
schedule
13.03.2015