问题
I'm working on a cloud platform for rendering visual effects and animation. We accept various formats of scene descriptions render them, and return the image outputs to the user. The processing backend is Linux. Sometimes we receive scene descriptions generated on Windows so we get paths that look like 'C:\path\to\file.mb'. I've written a Linux shared library to intercept various filesystem calls and alter the paths to something Linux can understand '/C/path/to/file'. I use the LD_PRELOAD mechanism to insert my functions before the "real" ones and it works great... except when it doesn't.
For example this command:
LD_PRELOAD=/home/robert/path_fix.so Render -s 1 -e 1 C:\path\to\test_scene_03_vray.ma
Will not locate test_scene_03_vray.ma. This also doesn't work:
LD_PRELOAD=/home/robert/path_fix.so echo test > C:\path\to\test.txt
I've been using ltrace to figure out which functions are called with references to path names, but these examples don't show up in my traces:
ltrace -f -C -S -o ltrace.out Render C:\path\to\test_scene_03_vray.ma
Is there a tool other than ltrace that will let me see which function calls are invoked?
Here's the list of what I already have overrides for:
- fopen
- freopen
- opendir
- open
- creat
- openat
- stat
- lstat
- fstatat
- __lxstat
- __xstat
- mkdir
- mkdirat
- unlink
- unlinkat
- access
- faccessat
- rename
- renameat
- renameat2
- chmod
- fchmodat
- chown
- lchown
- fchownat
- link
- linkat
- name_to_handle_at
- readlink
- readlinkat
- symlink
- symlinkat
- rmdir
- chdir
Are there more functions that I'm missing here? I tried to implement everything that takes
const char *filepath
as an argument.
Side question: This seems like it might already be a solved problem... Is there a library or other approach that converts Windows paths to unix friendly paths? Keep in mind that the rendering applications are 3rd party proprietary binaries so I can't modify them.
Thanks for any suggestions!
回答1:
Yes, there are other functions, such as the 64-bit functions open64()
. There are also functions such as __open()
.
On a 64-bit Centos 7 server, for just open
I get:
nm -D /lib64/libc.so.6 | grep open
0000000000033d70 T catopen
00000000003c0b80 B _dl_open_hook
000000000006b140 T fdopen
00000000000ba4c0 W fdopendir
00000000000755d0 T fmemopen
000000000006ba00 T fopen
000000000006ba00 W fopen64
000000000006bb60 T fopencookie
0000000000073700 T freopen
0000000000074b60 T freopen64
00000000000eb7a0 T fts_open
0000000000022220 T iconv_open
000000000006b140 T _IO_fdopen
0000000000077230 T _IO_file_fopen
0000000000077180 T _IO_file_open
000000000006ba00 T _IO_fopen
000000000006d1d0 T _IO_popen
000000000006cee0 T _IO_proc_open
0000000000131580 T __libc_dlopen_mode
00000000000e82a0 W open
00000000000e82a0 W __open
00000000000ed0f0 T __open_2
00000000000e82a0 W open64
00000000000e82a0 W __open64
00000000000ed110 T __open64_2
00000000000e8330 W openat
00000000000e8410 T __openat_2
00000000000e8330 W openat64
00000000000e8410 W __openat64_2
00000000000f7860 T open_by_handle_at
00000000000340b0 T __open_catalog
00000000000b9f70 W opendir
00000000000f12b0 T openlog
0000000000073ea0 T open_memstream
00000000000731c0 T open_wmemstream
000000000006d1d0 T popen
0000000000130630 W posix_openpt
00000000000e6ec0 T posix_spawn_file_actions_addopen
For example, on Linux this C code is quite likely to work just fine:
int fd = __open( path, O_RDONLY );
You're also not going to catch statically-linked processes, or those that issue a system call such as open
directly.
回答2:
You can technically use kprobes to intercept the calls but if thr numbrr of files arent too many or dynamicaly generated, i suggest creating symlinks. It is much safer and simpler.
来源:https://stackoverflow.com/questions/40161522/intercepting-file-operations-on-linux