Как я могу обнаружить доступ к файлу в Linux? -- c++ поле с участием linux поле с участием resources пол Связанный проблема

How can I detect file accesses in Linux?


10
vote

проблема

русский

У меня есть куча потоков и приложений для обработки данных, которые я иногда нужно шпионить, то есть мне нужно знать, какие файлы они читают. Это в основном, чтобы помочь в упаковке TestCases, но также может быть полезен при отладке.

Есть ли способ запустить исполняемые файлы таким образом, который производит такой список?

У меня есть две мысли на этом:

  1. есть команда, которую я могу вызвать, и эта команда вызывает мои приложения. Что-то вдоль линий GDB. Я называю GDB, дайте ему путь к исполнящению, а некоторые аргументы и GDB вызывают это для меня. Возможно, есть что-то подобное, чтобы сказать мне, как используются системные ресурсы.
  2. Может быть, более интересный (но ненужный боковой путь) решение.
    1. создать библиотеку под названием libc.co, которая реализует Fopen (и некоторые другие)
    2. Изменить ld_library_path, чтобы указать на новой библиотеке
    3. сделать копию настоящего libc.so и переименовать fopen (наверное nepof, возможно) в редакторе
    4. Моя библиотека загружает копию и вызывает переименованную функцию по мере необходимости для обеспечения функциональности Fopen.
    5. Позвоните в приложение, которое затем называет мой прокси Fopen.

Альтернатива № 1, безусловно, будет предпочтительным, но комментарием о том, как сделать # 2 проще приветствовать тоже.

Английский оригинал

I have a bunch of flows and data processing applications that I occasionally need to spy on, meaning I need to know what files they read. This is mostly to aid in packaging testcases, but can also be useful when debugging.

Is there a way to run the executables in such a way that produces such a list?

I have two thoughts on this:

  1. There is a command that I can invoke and that command invokes my apps. Something along the lines of GDB. I call GDB, give it a path to the executable and some arguments and GDB calls it for me. Perhaps there's something similar to telling me how system resources are used.
  2. Maybe the more interesting (but unnecessary side path) solution.
    1. create library called libc.so which implements fopen (and some others)
    2. change LD_LIBRARY_PATH to point at the new library
    3. make a copy of the real libc.so and rename fopen (nepof, perhaps) in an editor
    4. my library loads the copy and calls the renamed function as necessary to provide fopen functionality.
    5. call the app which then calls my proxy fopen.

Alternative #1 would certainly be the preferable one but comments on how to do #2 more easily are welcome too.

</div
        
 
 

Список ответов

13
 
vote
vote
Лучший ответ
 

Один вариант - использовать stroace:

 <код> strace -o logfile -eopen yourapp   

Это будет регистрировать все события открытых файлов, но он будет наложить штраф производительности, который может быть значительным. Это имеет преимущество в том, что он прост в использовании, однако.

Другой вариант - использовать ld_preload. Это соответствует вашему варианту № 2. Основная идея состоит в том, чтобы сделать что-то подобное:

 <код> #define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h>  int open(const char *fn, int flags) {     static int (*real_open)(const char *fn, int flags);      if (!real_open) {         real_open = dlsym(RTLD_NEXT, "open");     }      fprintf(stderr, "opened file '%s' ", fn);     return real_open(fn, flags); }   

Затем постройте с:

 <код> gcc -fPIC -shared -ldl -o preload-example.so preload-example.c   

и запустите вашу программу, например:

 <код> $ LD_PRELOAD=$PWD/preload-example.so cat /dev/null opened file '/dev/null'   

Это имеет гораздо меньше над головой.

Примечание, однако, что есть и другие точки входа для открытия файлов - например, Fopen (), OpenAT () или один из множества устаревших точек входа:

 <код> 00000000000747d0 g    DF .text      000000000000071c  GLIBC_2.2.5 _IO_file_fopen 0000000000068850 g    DF .text      000000000000000a  GLIBC_2.2.5 fopen 000000000006fe60 g    DF .text      00000000000000e2  GLIBC_2.4   open_wmemstream 00000000001209c0  w   DF .text      00000000000000ec  GLIBC_2.2.5 posix_openpt 0000000000069e50 g    DF .text      00000000000003fb  GLIBC_2.2.5 _IO_proc_open 00000000000dcf70 g    DF .text      0000000000000021  GLIBC_2.7   __open64_2 0000000000068a10 g    DF .text      00000000000000f5  GLIBC_2.2.5 fopencookie 000000000006a250 g    DF .text      000000000000009b  GLIBC_2.2.5 popen 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 __open64 0000000000068850 g    DF .text      000000000000000a  GLIBC_2.2.5 _IO_fopen 00000000000d7e70  w   DF .text      0000000000000020  GLIBC_2.7   __openat64_2 00000000000e1ef0 g    DF .text      000000000000005b  GLIBC_2.2.5 openlog 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 open64 0000000000370c10 g    DO .bss       0000000000000008  GLIBC_PRIVATE _dl_open_hook 0000000000031680 g    DF .text      0000000000000240  GLIBC_2.2.5 catopen 000000000006a250 g    DF .text      000000000000009b  GLIBC_2.2.5 _IO_popen 0000000000071af0 g    DF .text      000000000000026a  GLIBC_2.2.5 freopen64 00000000000723a0 g    DF .text      0000000000000183  GLIBC_2.2.5 fmemopen 00000000000a44f0  w   DF .text      0000000000000088  GLIBC_2.4   fdopendir 00000000000d7e70 g    DF .text      0000000000000020  GLIBC_2.7   __openat_2 00000000000a3d00  w   DF .text      0000000000000095  GLIBC_2.2.5 opendir 00000000000dcf40 g    DF .text      0000000000000021  GLIBC_2.7   __open_2 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 __open 0000000000074370 g    DF .text      00000000000000d7  GLIBC_2.2.5 _IO_file_open 0000000000070b40 g    DF .text      00000000000000d2  GLIBC_2.2.5 open_memstream 0000000000070450 g    DF .text      0000000000000272  GLIBC_2.2.5 freopen 00000000000318c0 g    DF .text      00000000000008c4  GLIBC_PRIVATE __open_catalog 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 open 0000000000067e80 g    DF .text      0000000000000332  GLIBC_2.2.5 fdopen 000000000001e9b0 g    DF .text      00000000000003f5  GLIBC_2.2.5 iconv_open 00000000000daca0 g    DF .text      000000000000067b  GLIBC_2.2.5 fts_open 00000000000d7d60  w   DF .text      0000000000000109  GLIBC_2.4   openat 0000000000068850  w   DF .text      000000000000000a  GLIBC_2.2.5 fopen64 00000000000d7d60  w   DF .text      0000000000000109  GLIBC_2.4   openat64 00000000000d6490 g    DF .text      00000000000000b6  GLIBC_2.2.5 posix_spawn_file_actions_addopen 0000000000121b80 g    DF .text      000000000000008a  GLIBC_PRIVATE __libc_dlopen_mode 0000000000067e80 g    DF .text      0000000000000332  GLIBC_2.2.5 _IO_fdopen   

Вам может потребоваться зацепить все это для полноты - по крайней мере, те, которые не префиксированы с _, должны быть подключены. В частности, обязательно связать FOPEN отдельно , поскольку внутренний вызов libc - от fopen (), чтобы открыть () не подключен к библиотеке ld_preload.

Подобное предостережение применяется к stroace - имеется Syscall 'SwionCall, а также в зависимости от вашей архитектуры, также могут быть и другие устаревшие синхронизации. Но не так много, как с крюками LD_PRELOAD, поэтому, если вы не возражаете против того, чтобы ударить производительность, это может быть более простым вариантом.

 

One option is to use strace:

strace -o logfile -eopen yourapp 

This will log all file-open events, but it will impose a performance penalty that may be significant. It has the advantage of being easy to use however.

Another option is to use LD_PRELOAD. This corresponds to your option #2. The basic idea is to do something like this:

#define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h>  int open(const char *fn, int flags) {     static int (*real_open)(const char *fn, int flags);      if (!real_open) {         real_open = dlsym(RTLD_NEXT, "open");     }      fprintf(stderr, "opened file '%s' ", fn);     return real_open(fn, flags); } 

Then build with:

gcc -fPIC -shared -ldl -o preload-example.so preload-example.c 

And run your program with eg:

$ LD_PRELOAD=$PWD/preload-example.so cat /dev/null opened file '/dev/null' 

This has much less overhead.

Note, however, that there are other entry points for opening files - eg, fopen(), openat(), or one of the many legacy compatibility entry points:

00000000000747d0 g    DF .text      000000000000071c  GLIBC_2.2.5 _IO_file_fopen 0000000000068850 g    DF .text      000000000000000a  GLIBC_2.2.5 fopen 000000000006fe60 g    DF .text      00000000000000e2  GLIBC_2.4   open_wmemstream 00000000001209c0  w   DF .text      00000000000000ec  GLIBC_2.2.5 posix_openpt 0000000000069e50 g    DF .text      00000000000003fb  GLIBC_2.2.5 _IO_proc_open 00000000000dcf70 g    DF .text      0000000000000021  GLIBC_2.7   __open64_2 0000000000068a10 g    DF .text      00000000000000f5  GLIBC_2.2.5 fopencookie 000000000006a250 g    DF .text      000000000000009b  GLIBC_2.2.5 popen 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 __open64 0000000000068850 g    DF .text      000000000000000a  GLIBC_2.2.5 _IO_fopen 00000000000d7e70  w   DF .text      0000000000000020  GLIBC_2.7   __openat64_2 00000000000e1ef0 g    DF .text      000000000000005b  GLIBC_2.2.5 openlog 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 open64 0000000000370c10 g    DO .bss       0000000000000008  GLIBC_PRIVATE _dl_open_hook 0000000000031680 g    DF .text      0000000000000240  GLIBC_2.2.5 catopen 000000000006a250 g    DF .text      000000000000009b  GLIBC_2.2.5 _IO_popen 0000000000071af0 g    DF .text      000000000000026a  GLIBC_2.2.5 freopen64 00000000000723a0 g    DF .text      0000000000000183  GLIBC_2.2.5 fmemopen 00000000000a44f0  w   DF .text      0000000000000088  GLIBC_2.4   fdopendir 00000000000d7e70 g    DF .text      0000000000000020  GLIBC_2.7   __openat_2 00000000000a3d00  w   DF .text      0000000000000095  GLIBC_2.2.5 opendir 00000000000dcf40 g    DF .text      0000000000000021  GLIBC_2.7   __open_2 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 __open 0000000000074370 g    DF .text      00000000000000d7  GLIBC_2.2.5 _IO_file_open 0000000000070b40 g    DF .text      00000000000000d2  GLIBC_2.2.5 open_memstream 0000000000070450 g    DF .text      0000000000000272  GLIBC_2.2.5 freopen 00000000000318c0 g    DF .text      00000000000008c4  GLIBC_PRIVATE __open_catalog 00000000000d7b10  w   DF .text      0000000000000080  GLIBC_2.2.5 open 0000000000067e80 g    DF .text      0000000000000332  GLIBC_2.2.5 fdopen 000000000001e9b0 g    DF .text      00000000000003f5  GLIBC_2.2.5 iconv_open 00000000000daca0 g    DF .text      000000000000067b  GLIBC_2.2.5 fts_open 00000000000d7d60  w   DF .text      0000000000000109  GLIBC_2.4   openat 0000000000068850  w   DF .text      000000000000000a  GLIBC_2.2.5 fopen64 00000000000d7d60  w   DF .text      0000000000000109  GLIBC_2.4   openat64 00000000000d6490 g    DF .text      00000000000000b6  GLIBC_2.2.5 posix_spawn_file_actions_addopen 0000000000121b80 g    DF .text      000000000000008a  GLIBC_PRIVATE __libc_dlopen_mode 0000000000067e80 g    DF .text      0000000000000332  GLIBC_2.2.5 _IO_fdopen 

You may need to hook all of these for completeness - at the very least, the ones not prefixed with _ should be hooked. In particular, be sure to hook fopen seperately, as the libc-internal call from fopen() to open() is not hooked by a LD_PRELOAD library.

A similar caveat applies to strace - there is the 'openat' syscall as well, and depending on your architecture there may be other legacy syscalls as well. But not as many as with LD_PRELOAD hooks, so if you don't mind the performance hit, it may be an easier option.

</div
 
 
4
 
vote
 <код> man strace    

Пример (предположить 2343 - это идентификатор процесса):

 <код> # logging part strace -p 2343 -ff -o strace_log.txt   # displaying part grep ^open strace_log.txt   
 
man strace  

example (assume 2343 is the process id):

# logging part strace -p 2343 -ff -o strace_log.txt   # displaying part grep ^open strace_log.txt 
</div
 
 
2
 
vote

Что я использую, это что-то вроде:

 <код> strace -o file.txt ./command   

Вы можете тогда

 <код> cat file.txt | grep open   

Чтобы получить список всех файлов, которые открыта программа.

 

What I use is something like:

strace -o file.txt ./command 

You can then

cat file.txt | grep open 

to get a list of all the files that the program opened.

</div
 
 

Связанный проблема

-1  Qt показывает изображение на 1/4 секунды  ( Qt show an image for 1 4 of a second ) 
Эй, я пробовал несколько раз, чтобы завершить это, используя Uslep или Qt Sleep, когда показывает изображение, но иногда (почти каждый раз) он появляется белы...

29  C ++ Указатель на объекты  ( C pointer to objects ) 
в C ++ У вас всегда инициализировать указатель на объект с new ключевое слово? или вы просто имеете это тоже: <код> MyClass *myclass; myclass->DoSometh...

-1  C ++ с использованием класса от заголовка в классе  ( C using a class from a header within a class ) 
У меня есть немного проблемы с классами, используемыми в классах, из файлов заголовка. У меня есть время занятий во времени. Как: <код> #ifndef TIME_H #de...

1  Проблема с использованием TextureView с NDK  ( Issue using textureview with ndk ) 
Я работаю над небольшим кусочком кода, используя текстуру, чтобы отобразить результат среды MediaPlayer. Я сталкиваюсь с проблемой, пытающимся смешивать упр...

4  Строка :: Новая: что это?  ( Stringnew what is it ) 
Я из фона Java и изучает C ++. Я столкнулся с следующим C ++: <код> String source = String::New("'Hello' + ', World'"); Как то, что я так понимаю, это ...

0  Использование Pybind11 на MacBook Pro  ( Using pybind11 on macbook pro ) 
Я пытаюсь использовать Pybind11 на MacBook, и я пытаюсь сделать так, как было написано в https://pybind11.readtheDocs.io/en/stable/basics.html я установил C...

1  Как работают Char и INT в C ++  ( How do char and int work in c ) 
Может быть, я собираюсь задать глупый вопрос, но я хочу подтвердить, как работает Char? Позвольте мне объяснить с примерами того, что я хочу спросить. Пусть п...

42  Как я могу легко увидеть график C / C ++ #include? [закрыто]  ( How can i see the c c include graph easily ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> закрыт. Этот вопрос не соответствует Рекомендациям переполнения ...

1  Наличие проблемных проектов C ++ в Eclipse CDT в ОС X для глупой причины  ( Having trouble building c project in eclipse cdt in os x for a silly reason ) 
Я пытаюсь построить очень простую программу C ++ в Eclipse, и я получаю очень глупую ошибку: <код> **** Internal Builder is used for build **...

-2  Конструкторы ведут себя странным с кодом обработки исключений  ( Constructors behaving strange with exception handling code ) 
Скриншот # 1: Образец (образец & amp;) {...) // Нет ошибки без использования "const" Скриншот № 2: Destructor называется дважды, когда Copy-Constructor не вк...

7  Как очистить удаленные объекты в C ++  ( How do clean up deleted objects in c ) 
Возможно ли использовать память об удаленных объектах в C ++? Я хочу сделать это, чтобы воспроизвести Coredump в модульном тесте: <код> //Some member variab...

145  Как определить, является ли строка номер с C ++?  ( How to determine if a string is a number with c ) 
У меня было довольно неприятностей, пытаясь написать функцию, которая проверяет, является ли строка номер. Для игры, которую я пишу, мне просто нужно проверит...

29  Добавление! Оператор и SQRT (), POW () и т. Д. Для пример примерка калькулятора  ( Adding the operator and sqrt pow etc to a calculator example applicatio ) 
Я делаю упражнения в новой книге Strustrup "Принципы программирования и практики с использованием C ++" и было интересно, если кто-нибудь на переполнении ст...

7  Используйте простой класс C ++ в Android NDK  ( Use a simple c class in android ndk ) 
Я пытаюсь узнать основные основы Android NDK, но я застрял, когда я должен использовать его с классом C ++. Я понимаю, как использовать его с помощью просто...

3  Преобразование IPlimage в вектор в 1D в OpenCV  ( Converting iplimage into 1d vector in opencv ) 
Я хочу преобразовать MXN IPLIMAGE в вектору A (M * N) x 1 1. Может ли это сделать с любой функцией в OpenCV? Любая помощь значительно ценится. ...