ptrace 多线程应用程序

发布于 2024-09-15 07:17:08 字数 1170 浏览 6 评论 0原文

我有一个类似“调试器”的应用程序,名为hyper-ptrace。它启动 user_appl3,它是带有 NPTL 的多线程。

hyper-ptrace的主循环是:

wait3(&status, FLAGS, &u);
// find a pid of child, which has a signal
switch (signal = WSTOPSIG(status))
{
  case SIGTRAP:
    do_some_analysis_of_the_child(pid, &status) // up to several ms
    break;
}
ptrace(PTRACE_CONT, pid); // discard signal, user_appl3 doesn't know anything 
                          //about this SIGTRAP

硬件以某个周期间隔为每个线程为user_appl3生成SIGTRAP,并将其传递给某些线程。间隔可以是 100..1 毫秒甚至更小。 它是一种带有中断的每 CPU 时钟。每个线程仅在其 CPU 上运行(通过关联性绑定)。

因此存在问题1

如果线程1收到TRAP并且调试器进入do_some_analysis_of_the_child(因此调试器不会为第二个线程执行wait3),过了一会儿,thread2 也得到了 TRAP,Linux 内核会做什么?

在我看来:thread1 将被停止,因为它收到一个信号并且有一个等待的调试器。但线程 2 继续运行(是吗?)。当 thread2 收到信号时,不会有等待的调试器,因此 TRAP 可以传递给 thread2 本身,从而有效地杀死它。 我说得对吗?

还有第二个问题,问题2

对于这种情况,我应该如何重写 主循环 的 hyper-ptrace 来降低通过调试器将信号传递到用户线程的机会? 陷阱生成硬件和用户应用程序都无法更改。停止第二个线程也不是一个变体。

我需要对两个线程进行分析。有些部分只能在线程停止时才能完成。

提前致谢!

I have a "debugger"-like application, named hyper-ptrace. It starts user_appl3 which is multithreaded with NPTL.

Main loop of hyper-ptrace is:

wait3(&status, FLAGS, &u);
// find a pid of child, which has a signal
switch (signal = WSTOPSIG(status))
{
  case SIGTRAP:
    do_some_analysis_of_the_child(pid, &status) // up to several ms
    break;
}
ptrace(PTRACE_CONT, pid); // discard signal, user_appl3 doesn't know anything 
                          //about this SIGTRAP

The SIGTRAP is generated for user_appl3 by hardware at some periodic interval for each thread and it is delivered to some of thread. Interval can be 100..1 ms or even less.
It is a sort of per-CPU clocks with interrupts. Each threads runs on only its CPU (binded with affinity).

So there is the question1:

If thread1 got TRAP and debugger enters to do_some_analysis_of_the_child, (so debugger does not do a wait3 for second thread), and a bit time later thread2 gots TRAP too, what will be done by Linux kernel?

In my opinion: thread1 will be stopped because its get a signal and there is a waiting debugger. But thread2 continues to run (is it?). When thread2 gets a signal, there will be no a waiting debugger, so TRAP can be delivered to the thread2 itself, effectively killing it. Am I right?

And there is the second question, question2:

For this case, how should I rewrite the main loop of hyper-ptrace to lower the chances of delivering signal through to the user's thread, over the debugger?
Nor trap-generating hardware neither user application can't be changed. Stopping the second thread is not a variant too.

I need analysis of both threads. Some it parts can be done only when thread is stopped.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我入戏太深 2024-09-22 07:17:08

否,信号未传递至应用程序。当信号发生时,子应用程序将停止,并且您的 ptracing 进程将在下次调用 wait() 时收到通知。

你是对的 - 跟踪停止仅适用于主线程。

要获得您想要的行为,请在跟踪线程停止后立即挂起整个子进程(每个线程),方法是向进程 PID 发送 SIGSTOP,然后使用 SIGCONT 恢复它> 完成后:

wait3(&status, FLAGS, &u);

if (WIFSTOPPED(status))
    kill(pid, SIGSTOP);  /* Signal entire child process to stop */

switch (signal = WSTOPSIG(status))
{
  case SIGTRAP:
    do_some_analysis_of_the_child(pid, &status) // up to several ms
    break;
}

ptrace(PTRACE_CONT, pid, 0, 0); // discard signal, user_appl3 doesn't know anything about this SIGTRAP
kill(pid, SIGCONT);  /* Signal entire child process to resume */

No, the signal isn't delivered to the application. The child application will stop when the signal happens, and your ptracing process will be notified about it next time it calls wait().

You're right - the tracing stop only applies to the main thread.

To get the behaviour you want, suspend the entire child process (every thread) immediately after the traced thread stops by sending a SIGSTOP to the process PID, and resume it with a SIGCONT when you're done:

wait3(&status, FLAGS, &u);

if (WIFSTOPPED(status))
    kill(pid, SIGSTOP);  /* Signal entire child process to stop */

switch (signal = WSTOPSIG(status))
{
  case SIGTRAP:
    do_some_analysis_of_the_child(pid, &status) // up to several ms
    break;
}

ptrace(PTRACE_CONT, pid, 0, 0); // discard signal, user_appl3 doesn't know anything about this SIGTRAP
kill(pid, SIGCONT);  /* Signal entire child process to resume */
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文