6.7. What to do when a file or library isn't being found (better living through strace)
Sometimes you'll see error messages that indicate a file wasn't found. The file could be a library:
% ./exult
./exult: error while loading shared library: libSDL-1.2.so.0: cannot load shared object
file: No such file or directory
or it could be some kind of data file, like a wad or map file:
% qf-client-sdl
IP address 192.168.0.2:27001 UDP Initialize Error: W_LoadWadFile: couldn't load gfx.wad
Suppose gfx.wad is already on my system, but couldn't be found because it isn't in the right directory. Then where IS the right directory? Wouldn't it be helpful to know where these programs looked for the missing files?
This is where strace shines. strace tells you what system calls are being made, with what arguments, and what their return values are. In my 'Kernel Module Programming Guide' (due to be released to LDP soon), I outline everything you may want to know about strace. But here's a brief outline using the canonical example of what strace looks like. Give the command:
strace -o ./LS_LOG /bin/ls
The -o option sends strace's output to a file; here, LS_LOG. The last argument to strace is the program we're inspecting, here, "ls". Look at the contents of LS_LOG. Pretty impressive, eh? Here is a typical line:
open(".", O_RDONLY|O_NONBLOCK|0x18000) = 4
We used the open() system call to open "." with various arguments, and the return value of the call is 4 . What does this have to do with files not being found?
Suppose I want to watch the StateOfMind demo because I can't ever seem to get enough of it. One day I try to run it and something bad happens:
% ./mind.i86_linux.glibc2.1
Loading & massaging...
Error:Can't open data file 'mind.dat'.
Let's use strace to find out where the program was looking for the data file.
strace ./mind.i86_linux.glibc2.1 2> ./StateOfMind_LOG
Pulling out vim and searching for all occurrences of mind.dat , I find the following lines:
open("/usr/share/mind.dat",O_RDONLY) = -1 ENOENT (No such file)
write(2, "Error:", 6Error:) = 6
write(2, "Can\'t open data file \'mind.dat\'."..., ) = 33
It was looking for mind.dat in only one directory. Clearly, mind.dat isn't in /usr/share . Now we can try to locate mind.dat and move it into /usr/share , or better, create a symbolic link.
This method works for libraries too. Suppose the library libmp3.so.2 is in /usr/local/include but your new game "Kill-Metallica" can't find it. You can use strace to determine where Kill-Metallica was looking for the library and make a symlink from /usr/local/include/libmp3.so.2 to wherever Kill-Metallica was looking for the library file.
strace is a very powerful utility. When diagnosing why things aren't being found, it's your best ally, and is even faster than looking at source code. As a last note, you can't look up information in source code of commercial games from Lokisoft or Tribsoft. But you can still use strace with them!
* License

