呼んだのは誰?
Posted feedbacks - C
GNU拡張を使用しています。 $ gcc -finstrument-functions -rdynamic caller.c -ldl のような形でコンパイルしてください。 参考 : http://alohakun.blog7.fc2.com/blog-entry-760.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
char *caller_func_name;
__attribute__((no_instrument_function))
void __cyg_profile_func_enter(void *func_address, void *call_site)
{
Dl_info func_info;
Dl_info call_info;
if (dladdr(func_address, &func_info) == 0) {
return;
}
if (strcmp(func_info.dli_sname, "foo") != 0) {
return;
}
if (dladdr(call_site, &call_info) == 0) {
return;
}
caller_func_name = (char *)call_info.dli_sname;
}
char *foo()
{
return caller_func_name;
}
char *bar()
{
return foo();
}
char *baz()
{
return foo();
}
int main()
{
printf("%s\n", bar());
printf("%s\n", baz());
return 0;
}
|
__builtin_return_address() と libbfd の bfd_find_nearest_line() を使ってみました。
% gcc -g caller.c -lbfd
でコンパイルできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <stdio.h>
#include <stdlib.h>
#include <bfd.h>
static bfd *abfd;
static int size;
static asymbol **symbols;
static asection *section;
const char *foo()
{
int ret;
void *addr;
const char *file;
const char *func;
unsigned int line;
addr = __builtin_return_address(0);
ret = bfd_find_nearest_line(abfd, section, symbols, (long)addr,
&file, &func, &line);
return func;
}
const char *bar()
{
return foo();
}
const char *baz()
{
return foo();
}
int main()
{
abfd = bfd_openr("/proc/self/exe", NULL);
bfd_check_format(abfd, bfd_object);
size = bfd_get_symtab_upper_bound(abfd);
symbols = (asymbol**)malloc(size);
section = bfd_get_section_by_name(abfd, ".debug_info");
printf("%s\n", bar());
printf("%s\n", baz());
free(symbols);
return 0;
}
|



にしお
#3384()
Rating1/1=1.00
Ruby で表現すると、 以下のような「fooという関数を呼び出す関数」#bar、#bazがあるとき
このbar, bazの返り値が以下のようになるような関数fooを定義してください。このお題は匿名の「Smalltalk からの挑戦状」を元に作成しました。 確かにこの手のリフレクションの機能が言語によってどう違うのかは興味深いところです。 リフレクションを使う問題をいくつか考えてみたいと思います。 ご投稿ありがとうございました。
[ reply ]