- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
为什么 orig_eax
成员包含在 sys/user.h
的 struct user_regs_struct
中?
最佳答案
因为它在 struct pt_regs
中,它是.... http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/arch/x86/include/asm/user_32.h#L77
73 * is still the layout used by user mode (the new
74 * pt_regs doesn't have all registers as the kernel
75 * doesn't use the extra segment registers)
因此,许多用户空间实用程序都希望这里有一个 orig_eax
字段,所以它也包含在 user_regs_struct
中(与旧的调试器和 兼容)追踪
rs)
下一个问题是“为什么 orig_eax
成员包含在 struct pt_regs
中?”。
它是在 linux 0.95 中添加的 http://lxr.linux.no/#linux-old+v0.95/include/sys/ptrace.h#L44 .我建议这是在其他带有 pt_regs
结构的 unix 之后完成的。评论在 0.95 说
29 * this struct defines the way the registers are stored on the
30 * stack during a system call.
因此,orig_eax
的位置由系统调用接口(interface)定义。这是http://lxr.linux.no/#linux-old+v0.95/kernel/sys_call.s
17 * Stack layout in 'ret_from_system_call':
18 * ptrace needs to have all regs on the stack.
19 * if the order here is changed, it needs to be
20 * updated in fork.c:copy_process, signal.c:do_signal,
21 * ptrace.c ptrace.h
22 *
23 * 0(%esp) - %ebx
...
29 * 18(%esp) - %eax
...
34 * 2C(%esp) - orig_eax
为什么我们需要保存旧的 eax
两次?因为 eax
将用于 syscall 的返回值(同一个文件,下面一点):
96_system_call:
97 cld
98 pushl %eax # save orig_eax
99 push %gs
...
102 push %ds
103 pushl %eax # save eax. The return value will be put here.
104 pushl %ebp
...
117 call _sys_call_table(,%eax,4)
Ptrace 需要能够读取系统调用之前的所有寄存器状态和系统调用的返回值;但返回值写入%eax
。那么在系统调用之前使用的原始 eax
将丢失。为了保存它,有一个 orig_eax
字段。
更新:感谢 R.. 和出色的 LXR,我在 linux 0.95 中对 orig_eax
进行了全面搜索。
不仅在ptrace中使用,在do_signal中也有使用重新启动系统调用时(如果有系统调用,以 ERESTARTSYS
结束)
158 *(&eax) = orig_eax;
更新 2:林纳斯 said有趣的是:
It's important that ORIG_EAX be set to some value that is not a valid system call number, so that the system call restart logic (see the signal handling code) doesn't trigger.
更新 3:ptrace
r 应用程序(调试器)可以更改 orig_eax
以更改要调用的系统调用号:http://lkml.org/lkml/1999/10/30/82 (在某些版本的内核中,是 EIO 将 ptrace 中的 ORIG_EAX 更改)
关于c - 为什么除了eax还要提供orig_eax?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6468896/
我正在使用 ptrace(PTRACE_ATTACH...) 附加到一个进程,而它在一个系统调用中(比如 nanosleep())。我可以使用 PTRACE_GETREGS 获取寄存器内容,并且 ei
如果子进程进行读取和写入以外的其他系统调用(甚至也过滤这些调用,但这是另一回事),我想终止它,但有些系统调用是默认完成的。 我编译了一个空的测试子(立即退出)程序,我还有一个父进程,它 fork 、启
我正在浏览一篇文章 here并正在尝试我在下面复制的代码片段:- #include #include #include #include #include /* For constant
当系统调用返回时,我在 %eax 中得到系统调用返回值,但是在输入时我得到 -38,即十六进制的 0xFFFFFFDA。这适用于写/读。这个数字是多少?它能否用于安全区分入口和导出? 最佳答案 系统调
我是一名优秀的程序员,十分优秀!