TL;DR
LD_PRELOADでprintfを後から差し替える - Qiita
上記の記事で LD_PRELOAD で先行ロードしたライブラリに新しい依存があったときに、ちゃんとリンクしてくれるのか疑問に思ったので検証した。
結論、新しい依存性も解決してくれることが確認できた。
検証
以下に検証をまとめる。printfの差し替えしたときの実装に liblua.so
への依存を追加した。
print.c
# include <stdio.h>
int main(int argc, char const* argv[])
{
printf("printf no args\n");
printf("printf %d\n", 1);
fprintf(stdout, "fprintf no args\n");
fprintf(stdout, "fprintf %d\n", 1);
return 0;
}
override.c(luaの依存を追加)
# include <stdio.h>
# include <stdarg.h>
# include <string.h>
# include <lua.h>
# include <lualib.h>
# include <lauxlib.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
const char *c = "override fwrite\n";
write(1, c, strlen(c)); // stdout
return 0;
}
int fprintf (FILE *__restrict __stream, const char *__restrict __format, ...) {
const char *c = "override fprintf\n";
write(1, c, strlen(c)); // stdout
return 0;
}
int puts(const char *s) {
const char *c = "override puts\n";
write(1, c, strlen(c)); // stdout
return 0;
}
int printf (const char *__restrict __format, ...) {
const char *c = "override printf\n";
write(1, c, strlen(c)); // stdout
{
const char *fn = "hello.lua";
// Lua の言語エンジンを初期化
lua_State *lua = luaL_newstate();
// Lua のライブラリを使えるようにする
luaL_openlibs(lua);
// Lua のスクリプトを読み込む
luaL_dofile(lua, fn);
}
return 0;
}
hello.lua
print("hello lua")
ビルドと実行結果は以下のようになる。
ビルドと実行結果
$ gcc print.c
$ ./a.out
printf no args
printf 1
fprintf no args
fprintf 1
$ gcc -shared -fPIC override.c -llua5.1 -o liboverride.so
$ LD_PRELOAD=./liboverride.so ./a.out
override puts
override printf
hello lua
override fwrite
override fprintf
LD_PRELOADで追加したライブラリの依存性も問題なく解決されていることがわかる。
ライブラリの依存性の確認
$ ldd ./a.out
linux-vdso.so.1 => (0x00007ffea74ca000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8569757000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8569b3a000)
$ LD_PRELOAD=./liboverride.so ldd ./a.out
linux-vdso.so.1 => (0x00007ffd939fb000)
./liboverride.so (0x00007f9c7c35c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9c7bf7b000)
liblua5.1.so.0 => /usr/lib/x86_64-linux-gnu/liblua5.1.so.0 (0x00007f9c7bd4d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9c7c560000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9c7ba47000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9c7b843000)
参考
第 5 回: Lua を組み込み用の言語として利用する方法 (関数編) — WTOPIA v1.0 documentation