2.4. Effects and Issues of Using strace

2.4. Effects and Issues of Using strace

The strace tool is somewhat intrusive (although it isn’t too bad). It will slow down the traced process, and it may also wake up a sleeping process if the process is waiting in the pause() function. It is rare that strace actually causes any major problems, but it is good to be aware of the effects.

strace 工具有点侵入性 (虽然它不是太坏)。它会减慢跟踪过程, 如果进程在pause() 函数中等待, 它也可能唤醒休眠进程。strace 很少实际上导致了任何重大问题, 但了解的它影响,是很好的事情。

The strace tool prints its output to stderr, which makes it a bit easier to separate the output from the traced tool’s output (if tracing something off of the command line). For csh or tcsh, you can use something like ( strace /bin/ ls > /dev/null ) | & less to see the actual strace output without the output from the traced program (/bin/ls in this case). Other shells support separating stdout and stderr as well, although it is usually just easier to send the output to a file using the -o switch to strace. This also ensures that the strace output is completely clean and without any stderr output from the traced process.

strace 将输出打印到 stderr, 这将strace输出与被跟踪的工具的输出分开 (如果在命令行中跟踪某些内容) 会更容易一些。对于 csh 或 tcsh, 您可以使用类似的东西 (strace/bin/ls > /dev/null) |less 看到实际的 strace 输出, 没有被跟踪程序的输出 (在本例中/bin/ls)。其他 shell 也支持分离标准输出和 stderr, 尽管通常只需使用-o 开关将输出发送到 strace 文件就更容易了。这也确保了 strace 输出是完全干净的, 没有任何被跟踪的进程的输出。

When a setuid program is run off of the command line, the program is run as the user of the strace program, and the setuid does not take place. There are also security protections against tracing a running program that was setuid. Even if a running setuid-root program changes its effective user ID back to the real user ID, strace will not be able to attach to the process and trace it. This is for security reasons since the process may still have sensitive information in its memory from when it was running as root.

当 setuid 程序从命令行中运行时, 并且该程序作为 strace 程序的用户运行, 则setuid 不发生作用。对于跟踪正在运行的正在 setuid 的程序, 还有安全保护。即使运行的 setuid root用户程序将其有效的用户 id 更改回实际用户 id, strace 也无法附加到进程并跟踪它。这是出于安全原因, 因为进程在其内存中仍可能有敏感信息, 从它作为 root 运行时。

If a program is setuid to root, strace requires root privileges to properly trace it. There are two easy ways to trace a setuid-root program, both of which require root privileges. The first method is to strace the setuid program as root. This will ensure the setuid-root program is also straced as root, but the real user ID will be root and not a mortal user as would normally be the case. The other method is to trace the shell as root using the -f switch to follow the setuid-root program and its invocation. The latter method is better, although it is a bit less convenient.

如果某个程序 setuid到root, strace 需要根权限才能正确跟踪它。有两种简单的方法可以跟踪 setuid root程序, 这两者都需要root权限。第一种方法是将 setuid 程序 strace 为root。这将确保 setuid 的程序也 straced 为root, 但真正的用户 ID 将是root, 而不是普通用户, 通常情况下是这样。另一种方法是使用-f 开关跟踪 shell 作为根目录, 以遵循 setuid 程序及其调用。后一种方法是更好的, 虽然它是有点不方便。

2.4.1. strace and EINTR

If you are using strace on a program that does not handle interrupted system calls properly, the target program will very likely experience a problem. Consider the following source code snippet:

如果在未正确处理中断的系统调用的程序上使用 strace, 则目标程序很可能会遇到问题。请考虑以下源代码段:

result = accept(s, addr, &addrlen);

 

if (result < 0)

{

  perror( "accept" ) ;

  return (SOCKET) INVALID_SOCKET;

}

else

 return result;

 

This function does not handle interruptions to the accept() call properly and is not safe to strace. If you were to strace this process while it was waiting on accept(), the process would pop out of the accept call and return an error via perror(). The error code (errno) received when a system call is interrupted is EINTR. Because the process does not handle EINTR error codes, the process will not recover, and the process may even exit altogether.

此函数不正确处理accept () 调用的中断, 并且不安全 strace。如果在等待accept () 时 strace 此进程, 则进程将弹出接受调用, 并通过 perror () 返回错误。系统调用中断时收到的错误代码 (errno) 是 EINTR。由于进程不处理 EINTR 错误代码, 进程将无法恢复, 进程甚至可能完全退出。

A better (and more robust) way to write this code would be

编写此代码的更好 (更健壮) 的方法是

do

{

    result = accept(s, addr, &addrlen);

} while ( result < 0 && errno == EINTR )

 

if (result < 0)

{

  perror( "accept" ) ;

  return (SOCKET) INVALID_SOCKET;

}

else

 return result;

 

The new code will still pop out of accept() if strace attaches to it, although the while loop will call accept() again when it receives the EINTR error code. In other words, when strace attaches, the code loop will see the EINTR error code and restart the accept() system call. This code is robust with respect to interrupts (that are caused by signals).

如果 strace 附加到它, 则新代码仍将弹出accept(), 尽管 while 循环在接收到 EINTR 错误代码时会再次调用accept()。换言之, 当 strace 附加时, 代码循环将看到 EINTR 错误代码并重新启动accept() 系统调用。对于中断 (由信号引起), 此代码是健壮的。

发布了234 篇原创文章 · 获赞 12 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/mounter625/article/details/102691203