【问题标题】:Any good guides on using PTRACE_SYSEMU?关于使用 PTRACE_SYSEMU 的任何好的指南?
【发布时间】:2011-07-20 17:27:10
【问题描述】:

有人对PTRACE_SYSEMU的使用有什么好的解释、教程、书籍或指南吗?

【问题讨论】:

  • 这是非常具体的 x86 用户模式 ​​linux 优化,请查看作者的sysemu.sourceforge.net 站点。基本上你不应该使用 ptrace 的 SYSEMU。

标签: linux ptrace


【解决方案1】:

我发现有趣的事情:

还有让使用 ptrace 更容易的编程库:

对于 pinktrace 有示例,sydbox 源是复杂的 pinktrace 用例的示例。总的来说,我发现作者是有关使用和测试 pinktrace 的好人。

【讨论】:

  • 我一般都知道如何使用 ptrace,只是不知道 PTRACE_SYSEMU 选项。我正在寻找专门的指南,这些文章都没有涵盖。我知道用户模式的 Linux 曾经使用过它,但我希望有一些更高级的东西,而不是涉足代码。
  • 我认为询问 PTRACE_SYSEMU 用法的好人可能是pinktrace author - 试试吧;)。
  • @GrzegorzWierzowiecki:甚至我也想要一些解释一些高级选项的指南。如果你发现任何你可以在这里更新它吗? :) 在此先感谢 :)
  • 嘿,它的 2016 年我不知道您是否找到任何资源,但手册页仍然声明 PTRACE_SINGLESTEP、PTRACE_SYSEMU、PTRACE_SYSEMU_SINGLESTEP 此类停止的详细信息尚未记录在案。那么你找到资源了吗?
【解决方案2】:

Linux 内核源代码中有一个使用 PTRACE_SYSEMU 的小测试:

http://code.metager.de/source/xref/linux/stable/tools/testing/selftests/x86/ptrace_syscall.chttp://lxr.free-electrons.com/source/tools/testing/selftests/x86/ptrace_syscall.c

186 struct user_regs_struct regs;
187
188 printf("[RUN]\tSYSEMU\n");
189 if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
190     err(1, "PTRACE_SYSCALL");
191 wait_trap(chld);
192
193 if (ptrace(PTRACE_GETREGS, chld, 0, &regs) != 0)
194     err(1, "PTRACE_GETREGS");
195
196 if (regs.user_syscall_nr != SYS_gettid ||
197     regs.user_arg0 != 10 || regs.user_arg1 != 11 ||
198     regs.user_arg2 != 12 || regs.user_arg3 != 13 ||
199     regs.user_arg4 != 14 || regs.user_arg5 != 15) {
200     printf("[FAIL]\tInitial args are wrong (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long)regs.user_syscall_nr, (unsigned long)regs.user_arg0, (unsigned long)regs.user_arg1, (unsigned long)regs.user_arg2, (unsigned long)regs.user_arg3, (unsigned long)regs.user_arg4, (unsigned long)regs.user_arg5);
201     nerrs++;
202 } else {
203     printf("[OK]\tInitial nr and args are correct\n");
204 }
205
206 printf("[RUN]\tRestart the syscall (ip = 0x%lx)\n",
207        (unsigned long)regs.user_ip);
208
209 /*
210  * This does exactly what it appears to do if syscall is int80 or
211  * SYSCALL64.  For SYSCALL32 or SYSENTER, though, this is highly
212  * magical.  It needs to work so that ptrace and syscall restart
213  * work as expected.
214  */
215 regs.user_ax = regs.user_syscall_nr;
216 regs.user_ip -= 2;
217 if (ptrace(PTRACE_SETREGS, chld, 0, &regs) != 0)
218     err(1, "PTRACE_SETREGS");
219
220 if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
221     err(1, "PTRACE_SYSCALL");
222 wait_trap(chld);
223
224 if (ptrace(PTRACE_GETREGS, chld, 0, &regs) != 0)
225     err(1, "PTRACE_GETREGS");
226

所以,它看起来只是另一个ptrace 调用,它将允许程序运行直到它进行下一个系统调用;然后停止孩子并向 ptracer 发出信号。它可以读取寄存器,可选地更改一些并重新启动系统调用。

http://lxr.free-electrons.com/source/kernel/ptrace.c?v=4.10#L1039 中实现,就像其他步进ptrace 调用一样:

1039 #ifdef PTRACE_SINGLESTEP
1040         case PTRACE_SINGLESTEP:
1041 #endif
1042 #ifdef PTRACE_SINGLEBLOCK
1043         case PTRACE_SINGLEBLOCK:
1044 #endif
1045 #ifdef PTRACE_SYSEMU
1046         case PTRACE_SYSEMU:
1047         case PTRACE_SYSEMU_SINGLESTEP:
1048 #endif
1049         case PTRACE_SYSCALL:
1050         case PTRACE_CONT:
1051                 return ptrace_resume(child, request, data);

手册页有一些信息:http://man7.org/linux/man-pages/man2/ptrace.2.html

PTRACE_SYSEMU、PTRACE_SYSEMU_SINGLESTEP(自 Linux 2.6.14 起) 对于 PTRACE_SYSEMU,继续并在进入下一个时停止 系统调用,不会被执行。见 下面有关系统调用停止的文档。为了 PTRACE_SYSEMU_SINGLESTEP,做同样的事情,但也是单步,如果 不是系统调用。此调用由 User 等程序使用 模式 Linux 想要模拟所有被跟踪者的系统调用。 数据参数被视为 PTRACE_CONT。地址 参数被忽略。当前支持这些请求 仅在 x86 上。

因此,它不可移植,仅用于 x86 平台上的 Usermode linux (um),作为经典 PTRACE_SYSCALL 的变体。还有一些 cmets 对 sysemu 的 um 测试在这里:http://lxr.free-electrons.com/source/arch/um/os-Linux/start_up.c?v=4.10#L155

155 __uml_setup("nosysemu", nosysemu_cmd_param,
156 "nosysemu\n"
157 "    Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
158 "    SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n"
159 "    behaviour of ptrace() and helps reducing host context switch rate.\n"
160 "    To make it working, you need a kernel patch for your host, too.\n"
161 "    See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n"
162 "    information.\n\n");
163 
164 static void __init check_sysemu(void)

评论中的链接从 2004 年开始重定向到秘密站点 http://sysemu.sourceforge.net/

为什么?

UML 使用 ptrace() 和 PTRACE_SYSCALL 来捕获系统调用。但是,通过 这样,您无法删除真正的系统调用,只能对其进行监视。 UML, 为了避免真正的系统调用并模拟它,将真正的系统调用替换为 调用 getpid()。此方法生成两个上下文切换 之一。解决方案

一个解决方案是改变 ptrace() 的行为以不调用真正的 syscall,因此我们不必通过调用 getpid() 来替换它。 怎么样?

通过向 ptrace() 添加一个新命令 PTRACE_SYSEMU,其作用类似于 PTRACE_SYSCALL 不执行系统调用。要添加这个命令,我们需要 修补主机内核。为了在 UML 内核中使用这个新命令,我们 还需要修补 UML 内核。

【讨论】:

猜你喜欢
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 2011-05-16
  • 2011-09-13
  • 1970-01-01
相关资源
最近更新 更多