Как получить имя функции от указателя функции в ядре Linux?

Как получить имя функции от указателя функции в C?

Править: Реальный случай: я пишу модуль ядра Linux, и я вызываю функции ядра. Некоторые из этих функций являются указателями, и я хочу осмотреть код той функции в источнике ядра. Но я не знаю, на какую функцию это указывает. Я думал, что это могло быть сделано, потому что, когда система перестала работать (паника ядра) она распечатывает на экране текущий стек вызовов с именами функции. Но, я предполагаю, что был неправ... я?

56
задан pevik 10 September 2019 в 13:26
поделиться

7 ответов

Это не непосредственно возможно без дополнительной помощи.

Вы могли:

  1. поддерживают таблицу в Вашей программе, отображающей указатели функции на имена

  2. , исследуют таблицу символов исполняемого файла, если это имеет тот.

последний, однако, является твердым, и не является портативным. Метод будет зависеть от двоичного формата операционной системы (ELF, a.out, .exe, и т.д.), и также на любом перемещении, сделанном компоновщиком.

РЕДАКТИРОВАНИЕ: Так как Вы теперь объяснили, каков Ваш реальный вариант использования, ответ на самом деле не настолько трудно. Таблица символов ядра доступна в /proc/kallsyms, и существует API для доступа к ней:

#include <linux/kallsyms.h>

const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize,
                            unsigned long *ofset, char **modname, char *namebuf)

void print_symbol(const char *fmt, unsigned long addr)

В простых целях отладки последний, вероятно, сделает точно, в чем Вы нуждаетесь - это берет адрес, форматирует его и отправляет его в printk, или можно использовать printk с %pF спецификатор формата.

33
ответ дан Alnitak 26 November 2019 в 17:17
поделиться

Вы не можете diectly, но можно реализовать другой подход к этой проблеме, если Вы хотите. Можно сделать указатель структуры, вместо этого указывающий на функцию, а также описательную строку, которую можно установить на то, что Вы хотите. Я также добавил отладку posebilety, так как Вы problably не хотите, чтобы они Вар были printet навсегда.

// Define it like this
typedef struct
{
  char        *dec_text;
  #ifdef _DEBUG_FUNC
  void        (*action)(char);
  #endif
} func_Struct;

// Initialize it like this
func_Struct func[3]= {
#ifdef _DEBUG_FUNC
{"my_Set(char input)",&my_Set}};
{"my_Get(char input)",&my_Get}};
{"my_Clr(char input)",&my_Clr}};
#else
{&my_Set}};
{&my_Get}};
{&my_Clr}};
#endif 

// And finally you can use it like this
func[0].action( 0x45 );
#ifdef _DEBUG_FUNC
printf("%s",func.dec_text);
#endif
2
ответ дан eaanon01 26 November 2019 в 17:17
поделиться

Я удивлен, почему все говорят, что это не возможно. Это возможно на Linux для нестатических функций.

я знаю по крайней мере два способа достигнуть этого.

существуют функции GNU для печати следа: backtrace() и backtrace_symbols() (См. man). В Вашем случае Вам не нужно backtrace(), поскольку у Вас уже есть указатель функции, Вы просто передаете его backtrace_symbols().

Пример (работающий код):

#include <stdio.h>
#include <execinfo.h>

void foo(void) {
    printf("foo\n");
}

int main(int argc, char *argv[]) {
    void    *funptr = &foo;

    backtrace_symbols_fd(&funptr, 1, 1);

    return 0;
}

Компиляция с gcc test.c -rdynamic

Вывод: ./a.out(foo+0x0)[0x8048634]

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

Иначе должен использовать dladdr() (другое расширение), я предполагаю print_backtrace() использование dladdr(). dladdr() возвраты Dl_info структура, которая имеет имя функции в [1 113] поле. Я не обеспечиваю пример кода здесь, но это очевидно - см. man dladdr для деталей.

нбар! Оба подхода требуют, чтобы функция была нестатична!

ну, существует еще один путь - используют отладочную информацию с помощью [1 115], но это потребовало бы неразделенного двоичного файла и не очень легкое сделать так, я не рекомендую его.

63
ответ дан qrdl 26 November 2019 в 17:17
поделиться

Нет никакого пути, как сделать это в целом.

при компиляции соответствующего кода в Библиотеку DLL / Общую Библиотеку необходимо быть в состоянии включить в список все точки входа и соответствовать указателю, который Вы имеете. Еще не попробовали его, но у меня есть некоторый опыт с DLLs/Shared, Освобождает и ожидал бы, что он будет работать. Это могло даже быть реализовано для работы перекрестно-plarform.

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

1
ответ дан mh. 26 November 2019 в 17:17
поделиться

Выезд Визуальный Детектор Утечки , чтобы видеть, как они получают свою работу печати стека вызовов. Это предполагает использование Windows, все же.

0
ответ дан Jim Buck 26 November 2019 в 17:17
поделиться

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

-3
ответ дан sblundy 26 November 2019 в 17:17
поделиться

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

-4
ответ дан yogman 26 November 2019 в 17:17
поделиться
Другие вопросы по тегам:

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