1. 程式人生 > 實用技巧 >gdb多程序 clone系統呼叫

gdb多程序 clone系統呼叫

#define _GNU_SOURCE
#include<sched.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>

static char child_stack[2048];

int x = 10;

static int child_fn() {
    printf("Pid: %ld\n", (long) getpid());
    return 0;
}

int main() {
    printf("before= %d\n", x);
    errno = 0;
    pid_t child_pid = clone(&child_fn, (void *) child_stack+1024, CLONE_NEWPID | SIGCHLD, NULL);
    if(child_pid == -1) {
        printf("%s\n", strerror(errno));
        return 0;
    } else {
        printf("clone()= %ld\n", (long) child_pid);
        printf("after= %d\n", x);

        while(waitpid(-1, NULL, 0) < 0 && errno == EINTR) {
            printf("waiting\n");
            continue;
        }

        return 0;
    }
}



我得到的輸出是:

before= 10
clone()= 16
after= 10



這意味著child_fn確實分配了一個Pid,即child_pid。但是printf中的child_fn是不是沒有執行,或者可能是在其他stdout範圍內列印?無論哪種方式,這可能是什麼原因,以及如何對其進行除錯。我只是從名稱空間開始,所以對它們瞭解不多。

如果我使用gdb執行原始程式碼,則會發現它失敗並顯示SIGSEGV

$ gcc -o clone clone.c
$ sudo gdb ./clone
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/lars/tmp/clone 
before= 10
[New process 10768]
clone()= 10768
after= 10

Thread 2.1 "clone" received signal SIGSEGV, Segmentation fault.
[Switching to process 10768]
0x00007ffff7a5e9de in vfprintf () from /lib64/libc.so.6



我懷疑您的child_stack太小。您分配了2048個位元組,但只使用了一半。如果我將clone呼叫修改為如下所示:

pid_t child_pid = clone(&child_fn, (void *) child_stack+2048, CLONE_NEWPID | SIGCHLD, NULL);



然後在我的系統上似乎可以正常執行:

$ sudo gdb ./clone
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/lars/tmp/clone 
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.24-9.fc25.x86_64
before= 10
[New process 10807]
clone()= 10807
after= 10
Pid: 1
[Inferior 2 (process 10807) exited normally]

root@cloud:/nsexec# gcc simple.c  -o simple
root@cloud:/nsexec# ./simple 
clone() = 58961
root@cloud:/nsexec# gdb ./clone
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./clone...(no debugging symbols found)...done.
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /nsexec/clone 
[New process 58985]
clone() = 58985

Thread 2.1 "clone" received signal SIGBUS, Bus error.
[Switching to process 58985]
0x0000aaaaaaaaa8d8 in child_func ()
(gdb)