杀死进程并在Linux中强制其返回0?


16

在Linux环境中,如何在确保该进程返回的退出代码为0的同时向该进程发送终止信号?为此,我是否需要做一些精美的GDB魔术,还是我不知道有没有精美的杀伤信号?

测试用例:

cat; echo $?

killall cat

尝试各种终止信号只会提供不同的返回信号,例如129、137和143。我的目标是终止脚本运行的进程,但要使脚本认为它成功。

Answers:


20

您可以使用GDB和进程ID附加到进程,然后发出call带有exit(0)参数的命令。

call允许您在正在运行的程序中调用函数。调用exit(0)退出,返回码为0。

gdb -p <process name>
....
.... Gdb output clipped
(gdb) call exit(0)

Program exited normally.

作为单行工具:

gdb --batch --eval-command 'call exit(0)' --pid <process id>

如果程序不使用(g)libc,例如用Assembly:编写的程序,则此方法将无效No symbol table is loaded. Use the "file" command。尽管这极不可能。
Cristian Ciupitu 2014年

处理红宝石脚本:-D
Mikhail,

1
@CristianCiupitu有解决此问题的方法。在进入下一个系统调用时,只需修改相关的寄存器,以使目标程序_exit使用0作为参数来调用系统调用。这将适用于任何不仅仅循环和燃烧CPU周期的进程。如果该过程恰好没有陷入无限循环中,则可以在可执行文件中找到必要的指令并将指令指针指向该处时,仍然可以使用相同的方法。
kasperd 2015年

@Mikhail可以处理“ ruby​​脚本”,因为GDB已连接到ruby解释器进程,该进程的二进制文件与glibc链接。
丹尼尔(Daniel)

@kasperd,是的,虽然我是这样,但是更精确的说明会很好。
Cristian Ciupitu


3

我不确定,但是如果收到任何列出的信号,它将以0退出。您可以执行其他操作,包括调用函数等。

#!/bin/bash 
trap 'exit 0' SIGINT SIGQUIT SIGTERM

3

这种单线为我工作:

/bin/bash -c '/usr/bin/killall -q process_name; exit 0'

我认为您不理解这个问题。该命令无法实现所要求的功能。这是我使用您的命令了:$ cat; echo $? Terminated 143
卡巴斯德(Kasperd)

2
@Landon Thomas您在此处显示的代码行实际上返回0。但是被杀死的process_name不会返回0,这是OP想要的。
丹尼尔(Daniel)

2

有点古怪的方法,但是..

您可以为您的进程创建一个包装器,以覆盖SIGCHLD处理程序。例如:

#!/bin/bash
set -o monitor
trap 'exit(0)' CHLD
/some/dir/yourcommand

之后,可以通过将脚本放在$ PATH中并重命名为相同的名称,从而使脚本运行此包装而不是进程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.