当我在设备上运行 gdbserver 时(喜欢gdbserver :2345 myapp
),gdbserver 完全阻塞终端。添加 & 符号&
或按下都不会^z使其在后台运行。我还检查过:它在 Kubuntu 上也可以重现。
我真的需要使用 shell 命令,因为我不知道如何通过 gdbserver 执行这些,运行后我感觉自己瘫痪了。
答案1
这似乎对OP有用。
gdbserver :2345 ls > /dev/null 2>&1 &
我认为这样做的原因是因为当程序被守护时,它会关闭所有 STDIO 0,1 和 2。下一个要打开的 IO 将是 0。如果程序尝试将 0,1 或 2 与 printf 或 scanf 之类的东西一起使用它将作用于错误的 IO 或关闭的 IO。例如,如果它是守护进程化的,则套接字在 0 上打开(STDIN 是),如果调用 printf,它将写入非打开的 FD,这将导致程序崩溃。
答案2
我从来没有找到一种真正用 shell 进行分叉的方法,有太多原因导致某些东西保持连接。我编写了一个非常小的 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 总是通过重复 null 来关闭 IO,以防止任何内容重新附加到 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);
}