Skip to main content
6 of 11
added 6 characters in body
Rui F Ribeiro
  • 58k
  • 28
  • 156
  • 237

My favourite tool for monitoring which files an application opens is still sysdig.

For monitoring all the open files in open by a program:

sudo proc.name=exe_file sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

Monitoring all the files opened by the server:

sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

Creating a trace file that will only contain writing events in home directories (which we can inspect later with "sysdig -r writetrace.scap.gz"):

sudo sysdig -p "%user.name %proc.name %fd.name" "evt.type=write and fd.name contains /home/" -z -w writetrace.scap.gz

Seeing everything at syscall level a process does:

sudo sysdig proc.name=exe_file

Sysdig has many chisels, see:

Sysdig Examples

How to monitor and troubleshoot a Linux server using sysdig

You also have got dtrace that is not much used in Linux, but is still use a lot with *BSD operating systems:

# Files opened by process,
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'

Besides sysdig, strace and dtrace, you also have got ltrace, which records/intercepts signals/dynamic libraries/system calls which are called/received by a process:

ltrace is a program that simply runs the specified command until it exits. It intercepts and records the dynamic library calls which are called by the executed process and the signals which are received by that process. It can also intercept and print the system calls executed by the program.

$ltrace exe_file
_libc_start_main(0x400624, 1, 0x7ffcb7b6d7c8, 0x400710 <unfinished ...>  
time(0)                                                                              = 1508018406  
srand(0x59e288e6, 0x7ffcb7b6d7c8, 0x7ffcb7b6d7d8, 0)                                 = 0  
sprintf("mkdir -p -- '/opt/sms/AU/mo'", "mkdir -p -- '%s'", "/opt/sms/AU/mo")        = 28  
system("mkdir -p -- '/opt/sms/AU/mo'" <no return ...>  
--- SIGCHLD (Child exited) ---  
<... system resumed> )                                                               = 0  
rand(2, 0x7ffcb7b6d480, 0, 0x7f9d6d4622b0)                                           = 0x2d8ddbe1  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 3  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 4  
+++ exited (status 0) +++  

If the program is small, you might also consider disassembly/decompiling it with objdump or Hopper:

For more details see: Understanding what a Linux binary is doing

As a first approach, I would do

strings exe_file

Some of the files names might just be present in ASCII mode in the binary file with luck.

see also related answer Why are true and false so large?

If binaries/files that come with the distribution you can also fetch the sources from the sources repositories of the distribution, or the official repositories of the actual utility.

As a last resource, you can always use tools like gdb or rr to debug the binary in real time.

Rui F Ribeiro
  • 58k
  • 28
  • 156
  • 237