当前位置: 首页 > 科技观察

使用strace命令了解Linux系统调用

时间:2023-03-18 14:22:56 科技观察

桌面上运行的每个进程都使用系统调用与操作系统通信。使用strace,您可以轻松地跟踪此类系统调用。当运行在Linux上的程序想要使用操作系统管理的资源(读取文件、创建进程等)时,它们会向操作系统发出系统调用。系统调用在内核级别工作并执行必要的操作,将控制权交还给调用程序。strace工具提供了在Linux上跟踪这些系统调用的能力。strace命令的典型用法要监控应用程序的系统调用,只需使用以下格式使用strace调用命令:┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$stracels/tmp但是,通常一些进程启动较早,并在后台继续工作。由于任何问题,您可能希望收集与此类流程相关的其他信息。您可以通过将进程的进程ID提供给-p参数,将strace附加到任何正在运行的应用程序:┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$strace-p5007output:Tracing应用程序的线程和分支使用strace,您可以使用-f标志来检查作为应用程序分支的所有线程和其他子进程。┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$strace-f-p5007output:Usestracetoinspectcertainsystemcalls默认的strace输出有时会非常拥挤。如果只想跟踪某些系统调用,可以使用-e参数执行此操作:strace-f-etrace=open,write,close,connect,select-p26757要仅跟踪与文件操作相关的系统调用,请使用-etrace=file:strace-etrace=file-p26757要仅过滤与网络相关的系统调用,请在命令中指定-etrace=network:strace-etrace=network-p26757以微秒为单位获取精确的时间信息输出系统时调用时,可以使用-t参数获取以秒为单位的精确时间信息。大多数时候,精度不足以满足您的需求。在这种情况下,您可以使用-tt参数获取微秒精度的时间信息:┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$strace-ttls/tmp收集系统信息calls系统调用统计使用-c参数,可以根据需要统计系统调用:┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$strace-f-c-p26757将日志保存到文件如果长时间运行strace并希望稍后更详细地检查结果日志,则需要保存日志。使用-o参数,您可以指定strace应保存其日志的文件:┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$strace-f-o/tmp/strace.log-etrace=filels/tmp跟踪阻塞进程使用prctl系统调用,Linux下的任何应用程序都可以防止自己被非root用户使用ptrace控制。如果应用程序通过prctl为自己清除了PR_SET_DUMPABLE标志,则除root以外的用户将无法使用ptrace控制此应用程序,即使他们有权向应用程序发出信号。在OpenSSH身份验证代理软件中可以看到此功能最典型的用途之一。因此,可以防止另一个应用程序在用户通过身份验证时使用ptrace控制该应用程序。跟踪和安全得益于传统Linux进程模型中的ptrace工具集,您在系统上与用户一起运行的任何软件都有权向其中插入恶意代码。从最简单的xterm工具到高级Web浏览器应用程序,这种类型的恶意软件可以控制所有其他正在运行的应用程序(感谢ptrace系统调用)并在您不知情的情况下复制重要信息。为了应对这种情况,很多用户都不知道,Linux内核中使用名为Yama的安全模块开发了一种保护机制。您可以通过/proc/sys/kernel/yama/ptrace_scope文件控制对ptrace系统调用的响应。默认情况下,写入此文件的值为0。可以接受以下值:值含义0一般行为:可以检查所有具有跟踪权限的应用程序。1受限跟踪:只有应用程序的直接父级允许的调试应用程序或具有PR_SET_PTRACER选项的应用程序才具有控制权。因此gdbprogram_name和straceprogram_name的使用将继续有效,但之后您将无法附加到正在运行的应用程序。2tracingtosysadmins:只能控制定义了CAP_SYS_PTRACE属性的应用程序或使用prctl定义PTRACE_TRACEME选项的子进程。3完全禁用:在任何情况下都不允许跟踪。如果此属性定义一次,则无法在运行时再次更改。许多开发人员不知道应用程序可以通过prctl禁用ptrace,root用户除外。尽管OpenSSH代理等与安全相关的软件可以执行这些操作,但期望系统上运行的所有软件都具有相同的行为是错误的。最近,一些Linux发行版开始将上述ptrace_scope文件的默认值设置为1。因此,整个系统提供了一个更安全的工作环境,限制了ptrace操作。使用名称ministrace.c注册下面的示例应用程序。然后你可以用下面命令编译译:┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$gcc-oministraceministrace.c┌──(linuxmi?linuxmi)-[~/www.linuxmi.com]└─$./ministrace日期代码:#include#include#include#include#include#include#include#include#includeintwait_for_syscall(pid_tchild){intstatus;while(1){ptrace(PTRACE_SYSCALL,child,0,0);waitpid(child,&status,0);if(WIFSTOPPED(status)&&WSTOPSIG(status)&0x80)return0;if(WIFEXITED(status))return1;}}intdo_child(intargc,char**argv){char*args[argc+1];memcpy(args,argv,argc*sizeof(char*));args[argc]=NULL;ptrace(PTRACE_TRACEME);kill(getpid(),SIGSTOP);returnexecvp(args[0],args);}intdo_trace(pid_tchild){intstatus,syscall,retval;waitpid(child,&stat我们,0);ptrace(PTRACE_SETOPTIONS,child,0,PTRACE_O_TRACESYSGOOD);while(1){if(wait_for_syscall(child)!=0)break;syscall=ptrace(PTRACE_PEEKUSER,child,sizeof(long)*ORIG_RAX);fprintf(stderr,"syscall(%d)=",syscall);if(wait_for_syscall(child)!=0)break;retval=ptrace(PTRACE_PEEKUSER,child,sizeof(long)*RAX);fprintf(stderr,"%d\n",retval);}return0;}intmain(intargc,char**argv){if(argc<2){fprintf(stderr,"Usage:%sprogargs\n",argv[0]);exit(1);}pid_tchild=fork();if(child==0){returndo_child(argc-1,argv+1);}else{returndo_trace(child);}}编译应用后,您可以使用ministrace运行任何命令并检查输出:您可以将strace用于多种用途。Strace可以帮助查找不必要地使用系统资源的程序中的错误。同样,程序在使用操作系统资源时会表现出特征。可以通过strace显示。因为strace直接监听系统调用,所以无论运行程序的代码是打开还是关闭,它都可以揭示运行时动态。您可以看到为什么程序在使用strace启动时会抛出错误。同样,strace可以帮助您了解程序意外终止的原因。因此,熟悉strace在Linux内核开发和系统管理中非常重要。