TLDR
x86_64での話。他のアーキテクチャでは未確認。
ltraceコマンドを使うと、共有ライブラリ内の関数に対する呼び出しをトレースできる。しかし単に ltrace a.out
としただけでは、-lhoge
のようにビルド時に指定したライブラリ内の関数呼び出しはトレースされるものの、dlopen()したライブラリ内の関数の呼び出しはトレースされない。そのためには ltrace -x hoge a.out
のように関数名を指定する必要がある。
例
hoge.c
// gcc -W -Wall -fPIC -shared hoge.c -o libhoge.so
int hoge(int a, int b)
{
return 10 + a * b;
}
main.c
// gcc -W -Wall -ldl main.c -o a.out
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main()
{
void* lib = dlopen("./libhoge.so", RTLD_LAZY);
if (lib == NULL) {
printf("%s\n", dlerror());
exit(1);
}
int (*f)(int, int);
f = (int (*)(int, int))dlsym(lib, "hoge");
int x = f(5, 9);
printf("x = %d\n", x);
dlclose(lib);
return 0;
}
ltrace a.outを実行
hoge()の呼び出しが表示されていない。
$ ltrace ./a.out
dlopen("./libhoge.so", 1) = 0x55cd42d67280
dlsym(0x55cd42d67280, "hoge") = 0x7f0bc72cc5aa
printf("x = %d\n", 55x = 55
) = 7
dlclose(0x55cd42d67280) = 0
+++ exited (status 0) +++
ltrace -x hoge a.outを実行
hoge@libhoge.so(5, 9, 1, 0)
という行が表示されている。
$ ltrace -x hoge ./a.out
dlopen("./libhoge.so", 1) = 0x564a38c5d280
dlsym(0x564a38c5d280, "hoge") = 0x7f8ffa51b5aa
hoge@libhoge.so(5, 9, 1, 0) = 55
printf("x = %d\n", 55x = 55
) = 7
dlclose(0x564a38c5d280) = 0
+++ exited (status 0) +++
解説
ltraceのdlopen()対応は2009年頃に実装されたらしい。
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=537781
元となったパッチとその解説がこちらのページにある。
http://timetobleed.com/extending-ltrace-to-make-your-rubypythonperlphp-apps-faster/