簡體   English   中英

fork / exec:stderr / stdout丟失

[英]fork/exec: stderr/stdout lost

我寫這將啟動一個新的進程組,然后派生一個PROGRAMM。

#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;
}

如果我用

./pgroup echo Test

它按預期工作。

如果我用

./pgroup bash -c "echo Test"

沒有輸出寫入我的終端。 這是為什么?

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](您不在這里,只說而已)。 而且-這是關鍵-您必須將其他args strcpy()放入堆空間,而不僅僅是傳遞現有的指針。 您沒有分配該argv,因此不要期望它在啟動例程再次運行時“纏住”等等。最后,您需要將NULL復制到參數列表的和。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

不要這樣混合標題。 sys /標頭放在首位。

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 <argc,這是不可思議的,這是由i的另一個怪異(不是從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聯機幫助頁中的相關宏。 殼支撐的值從0到255這樣的回報32512它是由256整除,因此最終被0。

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM