Get started with strace and debug faster
Open
As you might expect, open tries to open the specified file. If that file exists, the return value is a positive number. This file descriptor is the "handle" that the system will use to refer to this file for subsequent system calls. In the second article of this two-part series, I'll look at the fstat and mmap lines. After these lines, the file is closed again.
If you look at the open calls farther down the output, you'll see that some of the files are read from, as well. So what does this section mean? These are all files that are being loaded before the program can run, and they all have to do with the dynamic libraries used on a Linux system, which I'll discuss in more detail my next article. For now, it's enough to know that many of these files and libraries are loaded (or at least looked for) pretty much any time any file or program is executed on a Linux system. Also, you'll see a Perl library being loaded, which is obviously specific to Perl scripts.
Depending on your system and some memory-related and thread-related calls, you'll see some getuid and getgid calls after all the calls to libraries. These fetch the user and group ID that the process is running as (which should be your user ID), and the geteuid and geteguid calls fetch the effective user and group ID (i.e., this records who actually kicked the process off and whether they're running it as another user – which you might do, for example, if you used sudo).
Another couple of open calls are made to system directories, and then a series of stat calls, checking for the whereabouts of various Perl libraries or versions. Most of these will probably send back -1, which is the return you get if an error occurs. Perl libraries can be kept in a lot of places, and they all get looked through.
The Program!
Finally, I get to the actual program (Listing 4)! The first line of Listing 4 searches for the executable. The /proc/self/exe is a symbolic link to the executable path; this data (in this case, the path /usr/bin/perl) is put in the buffer in the second argument. The return value is the number of bytes put into the buffer. In other words, I'm loading up the path to the executable.
Listing 4
Running the Program
Then I get the process ID; on my system, it's 3252, but it will be something different on your system. Then, with the read line, the Perl script itself is read into memory. That second value is another example of strace doing some work for you. The second value in a read call is, again, a pointer to a buffer where the data that is read from the file descriptor is to be put.
The strace program dereferences the pointer and gets the data out of the buffer for you. In this case, the content of the buffer is your whole script (only the first few bytes are shown by default). The return value is the number of bytes read into the buffer. The next set of lines are all looking for the strict Perl module, and you'll see the output run through a set of possible locations (Listing 5).
Listing 5
Looking for a Perl Module
After it finally gets a successful return for stat (i.e., a return value of 0 rather than -1), the module file is opened and read, as shown in Listing 6. Again, the return value of that open line – here, it's 4 – identifies the file for later calls.
Now look at the next few lines – the first argument for all of them is 4, which means they're looking at the /usr/share/perl/5.8/strict.pm file. The next few lines deal with seeking through the file, reading it, and then closing it again.
Finally, look at the last little section of the output (Listing 7). As before, that 3 is a file descriptor. If you look back through the output, you'll see that when the helloworld.pl file was opened, its return value (its descriptor) was 3.
Listing 7
Last Part of Perl Output
Again, I am reading the Perl file, but this time, the return value (remember, this is the number of bytes read into the buffer) is 0, and the second value (the data read in) is an empty string. In other words, this checks that everything really has been read out of the file before it's closed. Now the single actual command in the program is run in the write line, and the process is detached.
Right! That was fairly complicated, but I hope you have an idea of what's going on. Now I'll show you what happens and what differs when I do the same thing with a C file.
Strace on C
Listing 8 shows a "Hello World" program in C. To compile it, type cc -o helloworld helloworld.c and then check it by typing ./helloworld. Assuming all went well, you should run strace -o strace_c.out ./helloworld. The strace output is shown in Listing 9.
Listing 8
helloworld.c
Listing 9
Complete strace for Hello in C
The first couple of lines look similar to the Perl example: an execve call containing the program name and a uname call. Also, a couple of access calls to the same files as before failed (ld.so.nohwcap and ld.so.preload). In addition, ld.so.cache is opened, read, and closed, as well. (ld.so.cache contains a list of possible libraries that have previously been found, which cuts down on the amount of time spent searching for libraries in the library path.)
Also present are the mmap, mprotect, and arch_prctl calls, as well as munmap. Because the program itself is the executable, and thus the permissions on it have already been checked, you won't see a check of the user or group ID. (With Perl, the executable is /usr/bin/perl – or wherever Perl lives on your system – so it is necessary to check to see whether the user has access to that executable file.)
Because C cleans up its memory after itself, munmap calls are also in the C strace output.
In this case, there's no readlink call because this is interpreted – not compiled – code, so you don't need to identify an executable with which to execute it. The difference between compiled and interpreted code is also responsible for the lack of read calls here compared with the Perl script output. The C code doesn't have to be read into memory and then fed into an interpreter; instead, it's run directly.
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Linux Servers Targeted by Akira Ransomware
A group of bad actors who have already extorted $42 million have their sights set on the Linux platform.
-
TUXEDO Computers Unveils Linux Laptop Featuring AMD Ryzen CPU
This latest release is the first laptop to include the new CPU from Ryzen and Linux preinstalled.
-
XZ Gets the All-Clear
The back door xz vulnerability has been officially reverted for Fedora 40 and versions 38 and 39 were never affected.
-
Canonical Collaborates with Qualcomm on New Venture
This new joint effort is geared toward bringing Ubuntu and Ubuntu Core to Qualcomm-powered devices.
-
Kodi 21.0 Open-Source Entertainment Hub Released
After a year of development, the award-winning Kodi cross-platform, media center software is now available with many new additions and improvements.
-
Linux Usage Increases in Two Key Areas
If market share is your thing, you'll be happy to know that Linux is on the rise in two areas that, if they keep climbing, could have serious meaning for Linux's future.
-
Vulnerability Discovered in xz Libraries
An urgent alert for Fedora 40 has been posted and users should pay attention.
-
Canonical Bumps LTS Support to 12 years
If you're worried that your Ubuntu LTS release won't be supported long enough to last, Canonical has a surprise for you in the form of 12 years of security coverage.
-
Fedora 40 Beta Released Soon
With the official release of Fedora 40 coming in April, it's almost time to download the beta and see what's new.
-
New Pentesting Distribution to Compete with Kali Linux
SnoopGod is now available for your testing needs