【问题标题】:ptrace one thread from anotherptrace 一个线程
【发布时间】:2014-08-01 04:18:34
【问题描述】:

尝试使用ptrace() 系统调用,我正在尝试跟踪同一进程的另一个线程。根据手册页,跟踪器和跟踪器都是特定线程(不是进程),所以我看不出它不应该工作的原因。到目前为止,我已经尝试了以下方法:

  • 使用PTRACE_TRACEME来自clone()d子级:调用成功,但没有做我想做的事,可能是因为要跟踪的线程的父级不是调用clone()的线程
  • 使用父线程中的PTRACE_ATTACHPTRACE_SEIZE:这总是以EPERM 失败,即使进程以root 身份运行并使用prctl(PR_SET_DUMPABLE, 1)

在所有情况下,waitpid(-1, &status, __WALL) 都会失败并返回 ECHILD(显式传递子 pid 时也是如此)。

我应该怎么做才能让它工作?

如果根本不可能,是因为设计或内核中的错误(我使用的是 3.8.0 版本)。在前一种情况下,您能否指出文档的正确位置?

【问题讨论】:

标签: multithreading ptrace


【解决方案1】:

正如@mic_e 所指出的,这是关于内核的一个已知事实 - 不完全是错误,但也不完全正确。 See the kernel mailing list thread about it. 摘自 Linus Torvalds:

“新”(去年 11 月)支票不太可能消失。它解决了 所以很多问题(安全性和稳定性),并考虑到

(a) 一年中,只有两个人曾经注意到

(b) 有一个如上所述的解决方法,不是非常具有侵入性

我不得不说,为了真正回到旧的行为, 我们必须有一个关心的人,回去检查每一个 单个特殊情况、死锁和竞争。

解决方案是实际启动在子进程中被跟踪的进程 - 您需要使 ptracing 进程成为另一个进程的父进程。

以下是基于another answer that I wrote 的概述:

// this number is arbitrary - find a better one.
#define STACK_SIZE (1024 * 1024)

int main_thread(void *ptr) {
    // do work for main thread
}

int main(int argc, char *argv[]) {
    void *vstack = malloc(STACK_SIZE);
    pid_t v;
    if (clone(main_thread, vstack + STACK_SIZE, CLONE_PARENT_SETTID | CLONE_FILES | CLONE_FS | CLONE_IO, NULL, &v) == -1) { // you'll want to check these flags
        perror("failed to spawn child task");
        return 3;
    }
    long ptv = ptrace(PTRACE_SEIZE, v, NULL, NULL);
    if (ptv == -1) {
        perror("failed monitor sieze");
        return 1;
    }
    // do actual ptrace work
}

【讨论】:

    猜你喜欢
    • 2011-11-09
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    相关资源
    最近更新 更多