我写了一个程序,它启动一个新的进程组,然后分叉。
body {
display: flex;
flex-direction: column;
height: 100vh;
}
footer {
position: fixed;
top: 180px;
bottom: 0;
width: 100%;
}
footer img[usemap] {
height: auto;
max-width: 100%;
width: 100%;
}
如果我用
打电话<svg height="250" width="500" style="position:relative;z-index:500;pointer-events:none;">
<polygon points="220,10 300,210 170,250 123,234" fill="#CECECE" opacity="0.9" stroke="#000000" stroke-width="2" />
Sorry, your browser does not support inline SVG.
</svg>
</div>
<footer class="footer">
<img src="http://www.wired.com/wp-content/uploads/2014/12/9-credit-1.jpg" alt="" usemap="#Map" name="#Map" id="map" style='z-index: -1'/>
<map name="Map" id="Map">
</map>
</footer>
它按预期工作。
如果我用
打电话#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char** argv) {
if(0 != setpgid(0,0)) {
fprintf(stderr, "Process group creation failed.");
}
pid_t pid = fork();
if(-1 == pid) {
// ups, error
fprintf(stderr, "Fork failed!\n");
return 1;
} else if(0==pid) {
// this is the child process
char **partial = malloc((argc-1)*sizeof(char*));
for(int i=1;i<argc;i++) {
partial[i-1] = argv[i];
}
execvp(partial[0], partial);
exit(127);
}
// this is the parent process
int status;
waitpid(pid, &status, 0);
return status;
}
没有输出写入终端。那是为什么?
答案 0 :(得分:0)
execve调用导致了段错误:
==22934== Command: ./testt bash -c echo\ Test
==22934==
==22935== Syscall param execve(argv) points to unaddressable byte(s)
==22935== at 0x4EF9537: execve (in /usr/lib64/libc-2.20.so)
==22935== by 0x4EF9D35: execvpe (in /usr/lib64/libc-2.20.so)
==22935== by 0x400822: main (testt.c:23)
==22935== Address 0x51f2058 is 0 bytes after a block of size 24 alloc'd
==22935== at 0x4C29BCF: malloc (in /usr/lib64/valgrind /vgpreload_memcheck-amd64-linux.so)
==22935== by 0x4007C5: main (testt.c:18)
==22935==
特别是,不要乱用argv [0](你不在这里,但只是说)。并且 - 这是关键 - 你必须strcpy()其他args到堆空间,而不仅仅是传递现有的指针。你没有分配那个argv,所以当启动例程再次运行时,不要指望它“坚持”等等......最后,你需要将NULL复制到参数列表的和。
答案 1 :(得分:-1)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
不要混合这样的标题。 sys / headers先行。
int main(int argc, char** argv) {
if(0 != setpgid(0,0)) {
fprintf(stderr, "Process group creation failed.");
}
pid_t pid = fork();
if(-1 == pid) {
// ups, error
fprintf(stderr, "Fork failed!\n");
return 1;
} else if(0==pid) {
// this is the child process
char **partial = malloc((argc-1)*sizeof(char*));
for(int i=1;i<argc;i++) {
partial[i-1] = argv[i];
}
这项练习有什么意义?如何使用argv ++,然后可以直接在execvp中使用它。你的循环是残暴和不必要的。你malloc argc - 1,但循环条件是i&lt; argc是不存在的,由另一种奇怪的东西弥补,我不是从0开始。错误诱导风格。
你也没有验证任何参数。
execvp(partial[0], partial);
如果您检查错误,您会看到失败。最简单的“第一次接触”工具是strace,它会告诉你究竟是什么,见:
[pid 15735] execve(“/ usr / bin / bash”,[“bash”,“ - c”,“echo test”, 0x20fe1],[/ * 58 vars * /])= -1 EFAULT(错误地址)
从这一点可以看出,arg数组没有正确终止,并且内核试图复制垃圾。
所以,你的“回声测试”示例在纯粹意外时起作用,因为发生在那里有零。
如果你在malloc中启用了调试,那么它也会失败。
exit(127);
这不是你如何退出没有执行的孩子。见_Exit。
}
// this is the parent process
int status;
waitpid(pid, &status, 0);
return status;
此值不适合重新标注。请参阅waitpid联机帮助页中的相关宏。 shell支持从0到255的值。这将返回32512,可以被256整除,因此最终为0。
}