执行int 3中断会在Linux上停止整个进程还是只停止当前线程?

Mci*_*anM 8 c c++ linux multithreading interrupt-handling

假设架构是x86.操作系统是基于Linux的.给定一个多线程进程,其中单个线程执行一条int 3指令,中断处理程序是否停止执行整个进程或只是执行int 3指令的线程?

Mic*_*kis 11

由于问题是针对Linux的,让我们深入研究内核源代码!我们知道int 3会生成一个SIGTRAP,我们可以看到do_int3.SIGTRAP默认行为是终止进程和转储核心.

do_int3调用do_trap它,很多间接的后,来电complete_signal,大多数的奇迹发生.在评论之后,很清楚地看到发生了什么而不需要解释:

  • 发现一个线程传递信号.主线程首先给出了破解,但任何线程都可以获得它,除非明确说明它不想要.
  • SIGTRAP是致命的(我们假设我们想要确定默认行为是什么)并且必须转储核心,因此对整个组来说是致命的
  • 第1003行的循环唤醒所有线程并传递信号.

编辑:回答评论:

当流程处于ptraced时,手册页中会详细记录该行为(请参阅"信号传递停止").基本上,在内核选择处理信号的任意线程后,如果跟踪选定的线程,它进入信号传递停止 - 这意味着信号尚未传递给进程,并且可以通过跟踪器进程抑制.调试器就是这种情况:在调试时,死进程对我们没有用(这不完全正确,但让我们考虑实时调试方案,这是唯一在这种情况下有意义的方案),所以默认情况下我们阻止SIGTRAP,除非用户另有指定.在这种情况下,跟踪进程如何处理SIGTRAP(SIG_IGN或SIG_DFL或自定义处理程序)是无关紧要的,因为它永远不会知道它发生了.

请注意,对于SIGTRAP,跟踪器进程必须考虑除停止进程之外的各种方案,这也在每个ptrace操作下的手册页中详细说明.


use*_*841 8

很容易测试:

#include <thread>
#include <vector>

void f(int v) {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    if (v == 2) asm("int $3");
    std::this_thread::sleep_for(std::chrono::seconds(1));
    printf("%d\n", v); // no sync here to keep it simple
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 4; i++) threads.emplace_back(f, i);
    for (auto& thread : threads) thread.join();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果只有线程被停止,它仍然应该从2以外的线程打印消息,但事实并非如此,整个过程在打印任何内容之前停止(或在调试时触发断点).在Ubuntu上,你得到的信息是:

跟踪/断点陷阱(核心转储)