Ale*_*lex 6 linux process fork
在 Linux 系统上,一个 C 进程在启动时启动,这会创建一个自己的分支。这不是一个内核过程或其他东西。在大多数情况下,aps -ef
将两个进程都显示为预期,但有时看起来如下所示:
1258 root 0:00 myproc
1259 root 0:00 [myproc]
Run Code Online (Sandbox Code Playgroud)
即括号包围的进程之一。根据ps
:
If the arguments cannot be located (usually because it has not been set,
as is the case of system processes and/or kernel threads) the command name
is printed within square brackets.
Run Code Online (Sandbox Code Playgroud)
我不明白“无法找到参数”是什么意思。该过程始终以完全相同的方式启动,并且分支始终以完全相同的方式创建。怎么会发生有时“无法找到论点”而有时却能找到的情况?
此外,该过程始终在没有任何参数的情况下启动......
我的问题:
/proc/{pid}/cmdline
为空时运行?附加信息:
myproc
。/proc/x/cmdline
)。/proc/child-pid/cmdline
正确运行的子进程是myproc
。/proc/child-pid/cmdline
不正确的运行的子进程是空的!ps -f
通常显示传递给execve()
进程或其任何祖先执行的最后一个系统调用的参数列表。
当您xxx arg1 arg2
在 shell 提示符下运行命令时,您的 shell 通常会派生一个进程,按xxx
名称搜索命令并将其执行为:
execve("/path/to/that/xxx", ["xxx", "arg1", "arg2"], @exported_variables)
Run Code Online (Sandbox Code Playgroud)
应该注意的是,第一个参数在xxx
那里。
执行后,进程的整个内存被擦除,这些参数(和环境)在进程堆栈的底部找到。
您将获得这些参数的前 4096 个字节,这/proc/<the-pid>/cmdline
就是ps
它的来源。
在分叉或克隆时,子级继承其父级的整个内存,包括该 arg 列表。
你得到[xxx]
when/proc/<the-pid>/cmdline
是空的。在这种情况下,不是显示 arg 列表,而是显示它在其中找到ps
的进程名称/proc/<the-pid>/stat
(对于已执行的命令,这是传递给最后一个的可执行文件的基本名称的前 16 个字节execve()
)。这可能有以下三个原因(我能想到的):
该进程或其任何祖先从未执行过任何操作。这就是内核线程的情况(并且只能是内核线程的情况,因为所有其他进程都是init
(被执行)的后代)。
$ ps -fp2
UID PID PPID C STIME TTY TIME CMD
root 2 0 0 Jan13 ? 00:00:00 [kthreadd]
Run Code Online (Sandbox Code Playgroud)该进程执行了一个带有空参数列表的命令。这通常永远不会发生,因为程序通常总是至少传递一个参数,即命令名称,但您可以强制使用例如:
int main(int argc, char *argv[]) {
if (argc) execve("/proc/self/exe",0,0);
else system("ps -fp $PPID");
}
Run Code Online (Sandbox Code Playgroud)
编译并运行后:
$ test1
UID PID PPID C STIME TTY TIME CMD
stephane 31932 29296 0 15:16 pts/5 00:00:00 [exe]
Run Code Online (Sandbox Code Playgroud)该进程argv[]
在其堆栈上覆盖它。
参数是内存中以 NUL 结尾的字符串。例如,如果您将 arg 列表的最后一个字符设为非空envp[0][-1]=1
(envp[]
值跟在argv[]
堆栈中的后面),则内核假定您已经修改了它,并且只返回/proc/xxx/cmdline
第一个参数直到第一个 NUL 字符。所以
int main(int argc, char* argv[], char *envp[]) {
envp[0][-1]=1;
argv[0][0]=0;
system("ps -fp $PPID");
}
Run Code Online (Sandbox Code Playgroud)
也会显示[xxx]
。
鉴于arglist(和environ)位于堆栈的底部,如果您的代码中有一个错误,使您在堆栈上写入超出了要编写的内容的末尾,则可能会发生这种情况,例如例如,如果使用strcpy
代替strncpy
. 调试这类问题,valgrind
非常有用。
归档时间: |
|
查看次数: |
3065 次 |
最近记录: |