当ltrace
用于跟踪系统调用时,我可以看到 fork() 使用 sys_clone() 而不是 sys_fork()。但是我找不到定义它的 linux 源代码。
我的程序是:
#include<stdio.h>
main()
{
int pid,i=0,j=0;
pid=fork();
if(pid==0)
printf("\nI am child\n");
else
printf("\nI am parent\n");
}
Run Code Online (Sandbox Code Playgroud)
而ltrace
输出是:
SYS_brk(NULL) = 0x019d0000
SYS_access("/etc/ld.so.nohwcap", 00) = -2
SYS_mmap(0, 8192, 3, 34, 0xffffffff) = 0x7fe3cf84f000
SYS_access("/etc/ld.so.preload", 04) = -2
SYS_open("/etc/ld.so.cache", 0, 01) = 3
SYS_fstat(3, 0x7fff47007890) = 0
SYS_mmap(0, 103967, 1, 2, 3) = 0x7fe3cf835000
SYS_close(3) = 0
SYS_access("/etc/ld.so.nohwcap", 00) = -2
SYS_open("/lib/x86_64-linux-gnu/libc.so.6", 0, 00) = 3
SYS_read(3, "\177ELF\002\001\001", 832) = 832 …
Run Code Online (Sandbox Code Playgroud) 我知道 strace 和 ltrace,但这只能分别告诉我进程正在执行哪些系统调用和库调用。我想确切地知道进程正在执行哪些指令。如果可能的话,要么是汇编,要么是 C 和汇编之间的某种中间立场。假设二进制文件没有用调试符号编译,所以更有可能倾向于第一个选项。
用例:进程似乎挂起,strace 或 ltrace 没有输出。确定进程是否正在做“某事”。我意识到这可能很难确定,因为我认为这类似于解决停机问题。但是,有可能收集有用的数据。
第二个用例:好奇心。将整个汇编指令列表转储到文本列表会很有趣。
我的猜测是我可以使用 gdb 来做到这一点,但不确定如何,因为这不是关于调试我编写的程序,而是关于使用 gdb 检查正在运行的进程的健康状况。
操作系统是 CentOS 6。
我想跟踪对特定库的函数调用,将其称为 libfoo。不幸的是,我在上面找到的文档很少,所以我有很多问题。
在 libfoo 的文档中,它将调用 foo_a、foo_b、foo_c .. 列为 api 调用。在 Windows DLL 中,生成这样的调用列表很容易,每个外部调用都必须如此声明(dllexport(DLL) 或类似的东西),一个简单的脚本将提取所有导出的符号。我将如何为 linux 共享对象生成这样的列表。
一旦我生成了这样一个列表,我如何将它与 ltrace 一起使用以生成使用特定程序的调用跟踪。另外我如何在这些调用中扩展 ( C ) 字符串参数?
我猜想Linux 上的 SQL Server 正在检查/proc/self/status
,TracerPID
如果不是,则停止运行0
。我想测试一下。玩玩,这是 strace,
... lots of stuff
openat(AT_FDCWD, "/proc/self/status", O_RDONLY) = 5
fstat(5, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(5, "Name:\tsqlservr\nUmask:\t0022\nState"..., 1024) = 1024
close(5) = 0
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
getpid() = 28046
gettid() = 28046
tgkill(28046, 28046, SIGABRT) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=28046, si_uid=999} ---
gettid() = 28046
write(2, "Dump collecting thread …
Run Code Online (Sandbox Code Playgroud) 在运行ltrace -S
由gcc
(版本 5.4.0)编译的两个程序后,一个调用vfork()
,一个调用fork()
,我发现vfork()
调用SYS_vfork
whilefork()
调用SYS_clone
。我找不到任何有关这个特定的行为在任何地方的任何信息(有消息说各的fork()
,vfork()
并且clone()
由相应的命名来实现sys_
通话,而其他消息来源说,所有的三个电话使用实施sys_clone
)。
源代码:
#include<stdio.h>
main()
{
int pid;
pid=vfork();
}
Run Code Online (Sandbox Code Playgroud)
输出ltrace -S
:
...
__libc_start_main([some stuff here] <unfinished ...>
vfork([more stuff] <unfinished ...>
SYS_vfork([more stuff])
--- SIGCHLD (Child exited) ---
Run Code Online (Sandbox Code Playgroud)
libc 使用SYS_vfork
forvfork()
但不使用SYS_fork
for是否有原因fork()
?我读过托马斯·尼曼的回答到
哪个文件在内核指定fork()的一样,vfork()...在使用sys_clone()系统调用,它说:
vfork()
反过来是通过一个单独的CLONE_VFORK
标志实现的,这将导致父进程休眠,直到子进程通过信号唤醒它。子进程将是父进程命名空间中唯一的执行线程,直到它调用exec()
或退出。不允许孩子写入内存。相应的clone()
调用可能如下: …