代码之家  ›  专栏  ›  技术社区  ›  Drakosha

应用程序终止自身最暴力的方式是什么(Linux)

  •  11
  • Drakosha  · 技术社区  · 15 年前

    我想模拟剧烈的系统关闭,即尽可能接近应用程序级别的断电。我们正在讨论Linux上的C/C++应用程序。 我需要申请自行终止。

    目前我看到几个选项:

    1. 呼叫 exit()
    2. 呼叫 _exit()
    3. 呼叫 abort()
    4. 除数为零或取消引用为空。
    5. 其他选择?

    最好的选择是什么?

    部分复制的 this question

    14 回复  |  直到 15 年前
        1
  •  14
  •   bdonlan    15 年前

    在应用程序级别,最暴力的是Exit()。除以零、segfaults等都是可以捕获的信号-如果不捕获,它们基本上与_exit()相同,但可能会根据信号留下一个coredump。

    如果你真的想要一个硬关机,最好的办法是以最暴力的方式切断电源。调用/sbin/poweroff-fn是尽可能接近的,尽管它可能在硬件级别做一些清理。

    不过,如果你真的想强调一些事情,你最好的办法就是真正切断电源——在电源线上安装某种软件控制的继电器,让软件切断电源。不受控制的能量损失会产生各种奇怪的东西。例如,磁盘上的数据可能由于 RAM losing power before the DMA controller or hard disk . 在生产硬件配置中,通过多次测试,除了切断电源之外,您无法通过其他任何方式测试这一点。

        2
  •  26
  •   lothar    15 年前

    imho最接近于对电源的愤怒是在虚拟机中运行应用程序,并且在不关闭的情况下运行虚拟机的电源。在所有其他情况下,当应用程序终止操作系统时,操作系统仍在运行 一些 在实际停电时不会发生的清理。

        3
  •  11
  •   Bill Lynch    15 年前
    kill -9
    

    它会终止进程,不允许运行任何信号处理程序。

        4
  •  7
  •   Charlie Martin    15 年前

    为什么不停下来?还是叫恐慌?

        5
  •  7
  •   Stack Exchange Supports Israel    15 年前

    尝试

    raise(SIGKILL)
    

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

    kill -9 pid
    

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

        6
  •  5
  •   Don Neufeld    15 年前

    你不清楚你的要求是什么。如果您正在测试如何从电源故障中恢复,则需要实际导致电源故障。即使做内核死机之类的事情,也会允许硬盘上的写缓冲区刷新,因为它们独立于CPU。

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

        7
  •  2
  •   AndreasT    15 年前

    您可以尝试使用虚拟机。 别动,用力拧,看看会发生什么。

    否则杀死-9是最好的解决方案。

        8
  •  2
  •   Greg Hewgill    15 年前

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

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

    如果这不够暴力(可能不够暴力),那么我喜欢终止一个运行应用程序的虚拟机的想法。您应该能够在应用程序可以(通过ssh或其他方式)向主机发送命令以终止其自己的虚拟机的地方装配一些东西。

        9
  •  1
  •   Tim Williscroft    15 年前

    我曾经做过回归测试,我们把电源开关拨到关的地方。 在执行磁盘IO时。

    后来恢复失败是,嗯:失败。

    您可以这样购买可靠性:一般来说,您需要一个“最终用户证书”。

    你可以通过跟你的UPS说脏话(脏话)进入软件。 apc upses绝对会在软件控制下关闭电源!

    谁说系统不能自行重启?

        10
  •  1
  •   anon    15 年前

    无限递归,应该耗尽堆栈空间(如果没有,OOM杀手将完成该任务):

    void a() { a(); }
    

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

      while(1)
        fork();
    

    内存不足:

      while(1)
        malloc(1);
    
        11
  •  1
  •   bob    15 年前

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

    否则,如果您正在进行自动测试,请尝试虚拟机,或者将测试机置于电源板上并关闭电源。

        12
  •  1
  •   Clifford    13 年前

    进程以编程方式自行终止的任何解决方案都不会以任何方式模拟异步终止。从某种意义上说,它是完全确定性的,每次都将在代码中的同一点终止。

    你的建议

    • exit()定义为 “正常终止,对终止进程执行定期清理。 “几乎不 暴力的 !

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

    • abort()创建一个sigabrt,操作系统可以选择执行一些资源清理。

    • /0的行为可能与abort()相似。

    最好不要让应用程序自行终止,而是让一些外部进程异步终止应用程序,以便在执行过程中的任何时候终止应用程序。在随机计时器上使用来自另一个进程或脚本的kill来发送 SIGKILL 无法捕获的信号,不执行清理。如果您必须让进程自行终止,请从某个异步线程执行该操作,该线程在某个不确定的时间后唤醒,并终止该进程,但即使这样,您也会知道当它终止时正在运行哪个线程。即使使用这些方法,也无法像真正断电那样在CPU周期中间终止进程,并且在进程终止后仍可能出现或写入任何缓存或缓冲的数据挂起输出。

        13
  •  0
  •   A M daniel    13 年前

    正如所指出的,在内核杀死您之前,尽量消耗更多的资源:

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

    另一种方法是尝试写入只读页,只需继续写入内存,直到出现总线错误。

    如果您可以访问内核,一个杀死它的好方法就是简单地写一个内核使用的数据结构,如果您发现一个页面是只读的,并且标记为可写的,然后覆盖它,那么您将得到额外的奖励。btw大多数Linux内核都允许写入syscall_表或中断表,如果在那里写入,系统肯定会崩溃。

        14
  •  0
  •   user130144    10 年前

    在最近的系统上,具有超级用户权限的进程可以获得实时CPU/IO优先级、锁定所有可寻址内存、在 /proc , /dev , /sys ,LAN/WiFi,固件IOCTL和闪存同时,超频/过电压CPU/GPU/RAM,并有很好的机会通过引起附近的东西退出 Halt and Catch Fire .

    如果这个过程只需要 隐喻的 暴力,可能会在 /proc/sysrq-trigger .