Как запустить «gdbserver» в фоне?

[119101]Вы можете, но это константа, так что это должно работать также хорошо:

Это представляет некоторые трудности, когда вы начинаете работать с большими числами - например, более 20 цифр - но для многих вещей это приемлемо.

Это автоматически ограничит и округлит ваш результат до двух десятичных разрядов - которые, в конце концов, не являются десятичными разрядами после того, как мы умножаемся. Затем мы просто обрабатываем результат как строку - сначала удаляем последние два символа из результата и вставляем десятичный разряд, а затем снова добавляем их.

Это должно быть POSIX портативным. [119108]

1
23.05.2017, 15:39
3 ответа

Кажется, это сработало для ОП.

gdbserver :2345 ls > /dev/null 2>&1 &

Я думаю, что причина в том, что когда программа даемонизируется, она закрывает все STDIO 0,1 и 2. Следующим открываемым входом IO будет 0. Если программа попытается использовать 0,1 или 2 с такими вещами, как printf или scanf, она будет действовать на неправильном входе IO или на закрытом входе IO. Например, если он даемонизирован, то сокет, открытый на 0, был STDIN и если будет вызван printf, то он будет записывать в незакрытый FD, что приведет к аварийному завершению работы программы.

4
27.01.2020, 23:15

Я никогда не нашел способа по-настоящему развязную раковину, есть слишком много причин, почему что-то останется на связи. Я написал очень маленькую программу C для полной вилки от любых команд, которые вы выполняете после нее.

----- Daemonize.C

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int i;
    // int reterr;
    pid_t pid, sid;

    //Fork the Parent Process
    pid = fork();

    if (pid < 0) { exit(EXIT_FAILURE); }

    //We got a good pid, Close the Parent Process
    if (pid > 0) { exit(EXIT_SUCCESS); }

    //Change File Mask
    umask(0);

    //Create a new Signature Id for our child
    sid = setsid();
    if (sid < 0) { exit(EXIT_FAILURE); }

    //Change Directory
    //If we cant find the directory we exit with failure.
    if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

    //Close Standard File Descriptors
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    //----------------
    //Main Process
    //----------------
    for(i=0; i < argc - 1; i++) {
        argv[i]=argv[i+1];
    }
    argv[argc-1] = '\0';
    execv(argv[0], argv);
    //reterr = execv(argv[0], argv);
    //printf("execv failed with '%s'\n", strerror(errno));

    //Close the log
    closelog ();
}

--- Makefile

CXX = gcc

# Implicit rules needed to build .o files and Metaobject stuff (_m.o)
.SUFFIXES: .c .o .h

.c.o:
    $(CXX) -c $(XTRA_INCL)   $< -o $@

OBJECTS = daemonize.o 
daemonize: $(OBJECTS)
    $(CXX) -o $@ -pipe -O2 $(OBJECTS) $(RPATH_XT)
    strip --strip-unneeded $@

clean:
    @rm -f core *.o *_m.* *.bak *.elf
2
27.01.2020, 23:15

Мой наставник, Роу Петерсон, всегда закрывал IO дублированием null, чтобы предотвратить повторное -присоединение чего-либо к FD. Я считаю, что таким образом демоны более стабильны.

daemonize()
{
        int fd1,fd2,fd3;

        signal(SIGCLD,SIG_IGN);

        if(fork()) {
                setpgid(getpid(),getpid());
                exit(0);
        }
        setpgid(0,0);

        fd1 = open("/dev/null",O_RDWR);
        fd2 = open("/dev/null",O_RDWR);
        fd3 = open("/dev/null",O_RDWR);


        close(0); dup(fd3);
        close(1); dup(fd3);
        close(2); dup(fd3);
        close(fd3);
        close(fd2);
        close(fd1);
}
0
27.01.2020, 23:15

Теги

Похожие вопросы