デバイスでgdbserverを実行するとき(良いgdbserver :2345 myapp
)、gdbserver は端末を完全にブロックします。アンパサンドを追加または押すと、バックグラウンドで実行されません&
。^z私も確認しました:Kubuntuでも再現可能です。
シェルコマンドを使用する理由は次のとおりです。gdbserverでこれを実行する方法がわかりません。私は走った後に麻痺した感じを受けました。
答え1
これはOPで動作するようです。
gdbserver :2345 ls > /dev/null 2>&1 &
その理由は、プログラムがデーモン化されるとSTDIO 0、1、2がすべて閉じられるためだと思います。次に開くIOは0になります。プログラムがprintfやscanfなどのエントリに0、1、または2を使用しようとすると、無効なIOまたは閉じたIOに対して機能します。たとえば、デーモン化されている場合、ソケットは0(STDIN)で開き、printfが呼び出されると開かれていないFDに書き込まれるため、プログラムは中断されます。
答え2
私は実際にシェルをフォークする方法を見つけることができませんでした。接続を維持する理由が多すぎます。私は後で実行するすべてのコマンドを完全に分岐する非常に小さな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 ();
}
--- ファイル生成
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
答え3
私のメンターの一人であるRoe Petersonは、すべてのアイテムがFDに再接続するのを防ぐために、常にnullを繰り返してIOを閉じます。私はデーモンがこのようにしてより安定していることがわかりました。
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);
}