> - PTRACE_SINGLESTEP does user_enable_single_step() > > - when the tracee returns to user mode, the next instruction > causes exception, do_debug()->send_sigtrap() sends SIGTRAP > > - the tracee notices the signal and reports this SIGTRAP
Correct. But if the tracee is inside the syscall path at the time, then it's a little different. TIF_SINGLESTEP being set means it will go to the syscall_trace_leave path and send a signal before it actually returns to user mode. The next time around, when "returns to user mode" really means the final signals-check-and-return-user path, it will indeed be the hardware TF exception firing after a user instruction. (We do this since for the syscall instruction itself, any hardware TF there might have been wasn't helpful--we want to send SIGTRAP when the user's system call has finished, not when the hardware user->kernel entry has finished.) > But, whatever I did this doesn't work. So, what user_enable_single_step() > actually means? It works very well in the vanilla kernel, so you can always go back to that and start poking things to watch it happening. (Just for good measure, I did boot vanilla v2.6.31-6618-gebc79c4 and verify that e.g. ptrace-tests tests/step-simple does still work. I don't think anything about this stuff has changed recently.) > I tried > > task_pt_regs(current)->flags |= X86_EFLAGS_TF; > > instead of user_enable_single_step(), this doesn't work too. It's great to get to understand this level of stuff, but really you should not have to for the work you are doing now. The existing arch layer should work for you just the same as it works in the vanilla kernel today. If it doesn't, I can probably be the one to worry about how it needs to be fixed. I tried your prctl hack on the vanilla kernel and a test program does indeed get a SIGTRAP. (This is an x86_64 kernel on an Intel chip, trying both 32-bit and 64-bit test programs.) > Perhaps there is some magic with syscall/sysret? Damn! I failed to google > the low-level description of these instructions. Does sysret restore flags? There is lots of magic. :-) Yes, sysret restores flags, though sysexit does not (and that's what 32-bit tasks on Intel chips use--so the sysexit code paths restore flags directly with popf). But there are two more things about that (and that's not even to go into syscall or sysenter on 32-bit kernels!). First, when syscall exits do set TF that is only to cause a trap after the *next* user instruction. To simulate the hardware effect of TF across the syscall instruction (i.e. for "stepi" over "syscall", "sysenter", or "int $0x80" to stop right after that instruction itself), we have TIF_SINGLESTEP. Second, lots of things lead you to actually take the "iret" return path instead, and that is what always happens in ptrace situations in practice. If you're either in the handle_signal path, or in the syscall_trace_leave path, then you're always going to wind up taking the iret path (and there are lots of other causes to wind up on that path). > At least. Is it true that X86_EFLAGS_TF should provoke the exception/do_debug? Yes. You can even set it yourself in userland with: pushf orl $0x100, (%rsp) /* or (%esp) */ popf and see the signal. The hardware feature is that when TF is set, the completion of an instruction generates the trap (do_debug path). (There are magic caveats like "popf" setting TF makes it apply to the next instruction's completion rather than to the completion of "popf".) > Otherwise, what triggers do_debug()->send_sigtrap() ? > > Oh. I guess I should read some intel docs, but I don't know where to start. http://www.intel.com/products/processor/manuals/index.htm You can also (at least in the US, don't know about EU), request free printed versions of the same manuals they have there in PDF, which I like to have. (Though they add new things more often than I want new printed manuals.) Thanks, Roland