我正在使用x86_64机器。我的linux内核也是64位内核。由于有不同的方法来实现系统调用(int 80,syscall,sysenter),我想知道我的机器正在使用什么类型的系统调用。我是linux的新手。我写了一个演示程序。
#include <stdio.h>
int main()
{
getpid();
return 0;
}
getpid()进行一次系统调用。任何人都可以给我一个方法来查找我的机器将为此程序使用哪种类型的系统调用..谢谢....
答案 0 :(得分:7)
victory:~ # gcc getpid.c -o getpid -g
victory:~ # gdb getpid
<snip>
(gdb) break main
Breakpoint 1 at 0x400540: file getpid.c, line 4.
(gdb) run
Starting program: /root/getpid
Breakpoint 1, main () at getpid.c:4
4 getpid();
(gdb) disassemble
Dump of assembler code for function main:
0x000000000040053c <main+0>: push %rbp
0x000000000040053d <main+1>: mov %rsp,%rbp
0x0000000000400540 <main+4>: mov $0x0,%eax
0x0000000000400545 <main+9>: callq 0x400440 <getpid@plt>
0x000000000040054a <main+14>: mov $0x0,%eax
0x000000000040054f <main+19>: leaveq
0x0000000000400550 <main+20>: retq
End of assembler dump.
看起来我们对getpid()的调用实际上是一个库调用。让我们在那里设置断点并继续。
(gdb) break getpid
Breakpoint 2 at 0x7ffff7b29c00
(gdb) cont
Continuing.
Breakpoint 2, 0x00007ffff7b29c00 in getpid () from /lib64/libc.so.6
(gdb) disassemble
Dump of assembler code for function getpid:
0x00007ffff7b29c00 <getpid+0>: mov %fs:0x94,%edx
0x00007ffff7b29c08 <getpid+8>: cmp $0x0,%edx
0x00007ffff7b29c0b <getpid+11>: mov %edx,%eax
0x00007ffff7b29c0d <getpid+13>: jle 0x7ffff7b29c11 <getpid+17>
0x00007ffff7b29c0f <getpid+15>: repz retq
0x00007ffff7b29c11 <getpid+17>: jne 0x7ffff7b29c1f <getpid+31>
0x00007ffff7b29c13 <getpid+19>: mov %fs:0x90,%eax
0x00007ffff7b29c1b <getpid+27>: test %eax,%eax
0x00007ffff7b29c1d <getpid+29>: jne 0x7ffff7b29c0f <getpid+15>
0x00007ffff7b29c1f <getpid+31>: mov $0x27,%eax
0x00007ffff7b29c24 <getpid+36>: syscall
0x00007ffff7b29c26 <getpid+38>: test %edx,%edx
0x00007ffff7b29c28 <getpid+40>: mov %rax,%rsi
0x00007ffff7b29c2b <getpid+43>: jne 0x7ffff7b29c0f <getpid+15>
0x00007ffff7b29c2d <getpid+45>: mov %esi,%fs:0x90
0x00007ffff7b29c35 <getpid+53>: mov %esi,%eax
0x00007ffff7b29c37 <getpid+55>: retq
End of assembler dump.
埋在getpid()库中的是syscall汇编程序指令。这是一条AMD64指令,支持快速上下文切换到ring0以进行系统调用。
答案 1 :(得分:1)
在linux下,您可以使用strace记录特定进程进行的系统调用。
答案 2 :(得分:0)
一种方法是使用gdb逐步执行机器代码(使用stepi
),直到找到启动系统调用的指令。因为不同的机器将指令放在不同的地方(有时在系统调用包装器本身,有时在系统调用包装器调用的函数中),我无法预测指令的确切位置。
例如,在一台旧计算机上,getpid
本身执行了int 0x80
,而在较新的计算机上,getpid
执行call *gs:0x10
会将__kernel_vsyscall
带到sysenter
} {{1}}
答案 3 :(得分:0)
我为此基于strace创建了一个简单的工具。 它完全符合您的要求:
public static String getCurrentDateTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = new Date();
String datetime = sdf.format(d);
return datetime;
}