什么是应用程序可以自行终止的最猛烈的方式(linux)

我想仿效暴力系统关机,即尽可能接近应用程序级别的停电。 我们正在谈论Linux上的c / c ++应用程序。 我需要应用程序自行终止。

目前我看到几个选项:

  1. 调用exit()
  2. 调用_exit()
  3. 调用abort()
  4. 通过零除或NULL解除引用。
  5. 其他选项?

什么是最好的select?

部分重复的这个问题

在应用程序级别,您可以得到的最暴力是_exit()。 除零,segfaults等是所有的信号,可以被困住 – 如果未处理,它们基本上与_exit()相同,但可能会留下一个coredump取决于信号。

如果你真的想要关机,最好的办法就是以最猛烈的方式切断电源。 调用/ sbin / poweroff -fn尽可能地接近,尽管它可能会在硬件级别上进行一些清理。

但是,如果你真的想要强调一些事情,那么最好的办法就是切实地切断电源 – 在电源线上安装某种软件控制的继电器,然后把软件切断。 不受控制的权力的丧失将会变成各种奇怪的东西。 例如,由于在DMA控制器或硬盘之前RAM断电 ,磁盘上的数据可能被损坏。 除了实际切割能力之外,在生产硬件配置中,还不能通过多次试验来测试。

恕我直言,最让人震惊的是在虚拟机中运行应用程序,而不关闭虚拟机。 在应用程序终止时操作系统仍在运行的所有其他情况下,操作系统将执行一些在实际停电时不会发生的清理。

 kill -9 

它杀死一个进程,不允许任何信号处理程序运行。

为什么不停止呢? 还是叫恐慌?

尝试

 raise(SIGKILL) 

在这个过程中,或从命令行:

 kill -9 pid 

其中pid是你的进程的PID(这两个方法是等价的,不应该执行任何清理)

你不清楚你的要求是什么。 如果您正在测试如何从电源故障中恢复,则需要真正导致电源故障。 即使是像内核恐慌一样的东西,也会允许硬盘上的写缓冲区刷新,因为它们独立于CPU。

如果您真的需要测试完整的故障情况,远程电源板可能是一个解决方案。

你可以尝试使用虚拟机。 冻结,拧紧,看看会发生什么。

否则kill -9将是最好的解决方案。

如果您需要应用程序自行终止,以下内容似乎是适当的:

 kill(getpid(), SIGKILL); // same as kill -9 

如果这不够暴力(也可能不是),那么我喜欢终止运行应用程序的虚拟机的想法。 你应该能够安装一些应用程序可以发送一个命令到主机(通过ssh或其他)来终止它自己的虚拟机的东西。

我已经进行了回归测试,我们用它来执行将电源开关拨到OFF的位置。 在做磁盘IO时。

以后不能恢复的就是失败。

你可以像这样购买可靠性:一般你需要一个“最终用户证书”。

您可以通过与您的UPS交谈(脏)来使用软件。 APC UPSes肯定会在软件控制下关闭电源!

谁说系统不能自行循环?

无限递归,应该用尽堆栈空间(如果不是,OOM​​杀手将完成作业):

 void a() { a(); } 

叉炸弹(如果应用程序没有任何叉限制,那么OOM杀手应该在某个时候杀死应用程序):

  while(1) fork(); 

内存不足:

  while(1) malloc(1); 

在一个正在运行的进程中, kill(getpid(),SIGKILL)是最极端的,因为不可能进行清理。

否则,如果您正在进行自动化测试,请尝试使用虚拟机,或将测试机器放在电源板上并关闭电源。

任何以编程方式终止进程的解决方案都不会以任何方式模拟异步终止。 每次都会在代码中的同一点终止,这是完全确定性的。

你的建议

  • exit()定义为“正常终止,执行终止进程的常规清理 – 几乎没有暴力

  • _exit()执行exit()操作的一些子集,但对应用程序,操作系统及其资源仍然“很好”。

  • abort()创建一个SIGABRT,操作系统可能会选择清理一些资源。

  • / 0可能与abort()有类似的行为

最好不要让应用程序自行终止,而是让一些外部进程异步终止,以便终止可能发生在执行的任何时刻。 使用随机定时器上的其他进程或脚本的kill,发送不能被捕获的SIGKILL信号,不执行清理。 如果你必须让这个进程自己终止,那么从某个异步线程开始,在非确定的时间后唤醒,并终止这个进程,但即使这样,你也知道哪个线程正在运行。 即使使用这些方法,过程也不能像真正的电源关闭那样在cpu-cycle中断,并且在进程终止之后,任何缓存或缓存的数据待处理输出仍可能出现或被写入。

正如所指出的那样,尽量消耗尽可能多的资源,直到内核杀死你为止:

 while(1) { malloc(1); fork(); } 

另一种方法是尝试写入只读页面,只要保持写入内存,直到出现总线错误。

如果你能到达内核,杀死它的一个好方法就是简单地写一个内核使用的数据结构,如果你发现一个只读的页面,并将其标记为可写,然后将其覆盖,那么奖励点就可以了。 BTW大多数Linux内核允许写入syscall_table或中断表,如果你写在那里你的系统肯定会崩溃。

在最近的系统中,具有超级用户权限的进程可能需要实时CPU / IO优先级,锁定所有可寻址内存,同时在/proc/dev/sys ,LAN / WiFi,固件ioctl和闪存中进行垃圾处理。 CPU / GPU / RAM,并有一个很好的机会通过引起附近的东西Halt and Catch Fire退出。

如果这个过程只需要做隐喻性暴力,那么可以在/proc/sysrq-trigger/proc/sysrq-trigger