系统调用
什么是系统调用
所有操作系统在其内核都有一些内建的函数,这些函数可以用来完成一些系统级别的功能,这些函数被称为系统调用,这些函数代表了用户空间到内核空间的一种转换
例如用户空间调用open函数,在内核空间中则会调用sys_open。
系统的错误码
系统调用并不直接返回错误码,而是将错误码放入到一个名为errno的全局变量中。
errno的值只在函数发生错误时设置。如果函数不发生错误,errno的值就无定义,并不会被置为0.另外,在处理errno钱最好将它的变量存入另一个变量,因为在处理过程中,即使像printf()这样的函数出错时也会改变errno的值
strace初识
strace命令是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。当然strace与专业的调试工具比如说gdb之类的是没法相比的,因为它不是一个专业的调试器。
strace ./test
用strace来跟踪信号
首先strace ./test
然后打开另一个窗口,输入命令“killall test”
strace中的结果显示test进程“+++ killed by SIGTERM +++”事实上,命令killall test就是杀死所有名为test的进程
统计系统调用
strace -c test
[root@localhost five]# strace -c test
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 1 read
0.00 0.000000 0 3 open
0.00 0.000000 0 5 close
0.00 0.000000 0 3 fstat
0.00 0.000000 0 9 mmap
0.00 0.000000 0 3 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 3 brk
0.00 0.000000 0 1 1 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 31 1 total
会显示调用多少次read函数,多少次write函数等
其他常用选项
一 -o就是将strace的结果输入到文件中
strace -c -o test.txt ./test
或者
strace -c ./test 2>test2.txt
二、-T将每个系统调用时间所花费的时间打印出来
strace -T ./test
三、-p。strace不光能自己初始化一个进程strace,还能跟踪现有的进程
strace -p pid
strace实战
#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;
int main(){
char buffer[256];
ifstream in("input.txt");
if (! in.is_open()){
cout << "Error opening file"<<endl;
exit (1);
}
while (!in.eof()){
in.getline (buffer,100);
cout << buffer << endl;
}
return 0;
}
g++ -o test test.cpp
./test
输出
Error opening file
用strace进行调试,strace ./test
找到问题,没有input.txt