进行实验ptrace()
系统调用,我试图跟踪同一进程的另一个线程。根据手册页,跟踪器和被跟踪者都是特定的线程(而不是进程),所以我看不出它不应该工作的原因。到目前为止,我已经尝试了以下方法:
- use
PTRACE_TRACEME
来自clone()
d child:调用成功,但没有执行我想要的操作,可能是因为要跟踪的线程的父级不是调用的线程clone()
- use
PTRACE_ATTACH
or PTRACE_SEIZE
来自父线程:这总是失败EPERM
,即使该进程以 root 身份运行并使用prctl(PR_SET_DUMPABLE, 1)
在所有情况下,waitpid(-1, &status, __WALL)
失败了ECHILD
(与显式传递子 pid 时相同)。
我应该怎么做才能让它发挥作用?
如果根本不可能,是设计使然还是内核中的错误(我使用的是 3.8.0 版本)。在前一种情况下,您能给我指出文档的正确部分吗?
正如 @mic_e 指出的,这是关于内核的已知事实 - 不完全是一个错误,但也不完全正确。请参阅内核邮件列表主题。 http://yarchive.net/comp/linux/ptrace_self_attach.html提供 Linus Torvalds 的摘录:
那张“新”(去年 11 月)支票不太可能消失。解决了so许多问题(安全性和稳定性),并考虑到
(a) 一年内,只有两个人曾经达到过noticed
(b) 有一个如上所述的解决方法,该解决方法并不是非常具有侵入性
我不得不说,为了真正回到原来的行为,
我们必须有人关心我们deeply,返回并检查每个
单一特殊情况、死锁和竞争。
解决方案是实际启动在子进程中跟踪的进程 - 您需要使 ptracing 进程成为另一个进程的父进程。
这是基于以下内容的概述:我写的另一个答案 https://stackoverflow.com/a/30092189/3369324:
// 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
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)