Действительно ли возможно перенести вызовы к статически связанной сторонней библиотеке?

Я хотел бы проследить вызовы до некоторой сторонней библиотеки, которые выполняются из другой сторонней библиотеки.

Пример: Я хочу проследить вызовы до библиотеки A. Мое приложение статически связывает библиотеку B, которая в свою очередь статически связана с библиотекой A. Так в основном то, что я имею, является libAB.a

В случае динамического подключения я мог записать библиотеку A2 с обертками для функций, которые я хочу к трассировке библиотеки A и использую LD_PRELOAD=A2.so. Затем мои обертки назовут вместо этого, и я буду видеть трассировку. В моем случае я не могу использовать динамическое подключение.

Действительно ли возможно достигнуть того же статического подключения использования?

В идеальном случае я хотел бы связать свое приложение с libAB.a и библиотекой трассировки libA2.a и получить трассировку.

Спасибо,
Robusta

1
задан robusta 16 June 2010 в 13:34
поделиться

3 ответа

Хорошо, я нашел :)

man ld

       --wrap symbol
       Use a wrapper function for symbol.  Any undefined reference to symbol will be resolved to "__wrap_symbol".  Any undefined ref‐
       erence to "__real_symbol" will be resolved to symbol.

       This  can  be  used to provide a wrapper for a system function.  The wrapper function should be called "__wrap_symbol".  If it
       wishes to call the system function, it should call "__real_symbol".

       Here is a trivial example:

               void *
               __wrap_malloc (size_t c)
               {
                 printf ("malloc called with %zu\n", c);
                 return __real_malloc (c);
               }

       If you link other code with this file using --wrap malloc, then all calls to "malloc" will call the  function  "__wrap_malloc"
       instead.  The call to "__real_malloc" in "__wrap_malloc" will call the real "malloc" function.
2
ответ дан 2 September 2019 в 23:44
поделиться

Ну, это похоже на тупик:)

Но я думаю, что вы можете решить эту проблему с помощью макросов. Хотя это решение может быть не чистым и работать не во всех ситуациях.

Вы можете попробовать следующее:

void functionFromLibA();
#define functionFromLibA() trace(); functionFromLibA()
int main()
{
    functionFromLibA();
}

Это будет расширено до:

void myfunc();
int main()
{
trace(); functionFromLibA();
}

РЕДАКТИРОВАТЬ: Но обратите внимание, что для этого решения все объявления прототипов функций должны выполняться до определения макросов. В противном случае прототипы также будут расширены при предварительной обработке.

0
ответ дан 2 September 2019 в 23:44
поделиться

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

Там а также такие вещи, как Oprofile http://oprofile.sourceforge.net/ , LTTng http://lttng.org/ и perf (поставляется с последними ядрами в исходном коде ядра, в tools / perf / вам нужно его скомпилировать, на Ubuntu я думаю, что он находится в пакете linux-tools)

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

0
ответ дан 2 September 2019 в 23:44
поделиться
Другие вопросы по тегам:

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