Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)
On Mon, 4 Jan 2010 19:14:12 +0100 Oleg Nesterov o...@redhat.com wrote: On 01/04, Martin Schwidefsky wrote: Subject: [PATCH] fix loading of PER control registers for utrace. From: Martin Schwidefsky schwidef...@de.ibm.com If the current task enables / disables PER tracing for itself the PER control registers need to be loaded in FixPerRegisters. Signed-off-by: Martin Schwidefsky schwidef...@de.ibm.com --- arch/s390/kernel/ptrace.c |3 +++ 1 file changed, 3 insertions(+) --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -98,6 +98,9 @@ FixPerRegisters(struct task_struct *task per_info-control_regs.bits.storage_alt_space_ctl = 1; else per_info-control_regs.bits.storage_alt_space_ctl = 0; + + if (task == current) + __ctl_load(per_info-control_regs.words, 9, 11); } Yes it does fix the problem! Thanks a lot Martin. Ok, I will add that patch to the git390 queue. However. Could you please look at 6580807da14c423f0d0a708108e6df6ebc8bc83d ? I am worried, perhaps this commit is not enough for s390. OK, do_single_step() tracehook_consider_fatal_signal(), this means the forked thread will not be killed by SIGTRAP if it is not auto-attached, but still this may be wrong. IOW. I think this problem is minor and probably can be ignored, but if I remove tracehook_consider_fatal_signal() check from do_single_step(), --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -382,8 +382,7 @@ void __kprobes do_single_step(struct pt_ SIGTRAP) == NOTIFY_STOP){ return; } - if (tracehook_consider_fatal_signal(current, SIGTRAP)) - force_sig(SIGTRAP, current); + force_sig(SIGTRAP, current); } static void default_trap_handler(struct pt_regs * regs, long interruption_code) --- then the test-case from 6580807da14c423f0d0a708108e6df6ebc8bc83d fails. This probably means that copy_process()-user_disable_single_step() is not enough to clear the this task wants single-stepping copied from parent. user_disable_single_step() does not remove the TIF_SINGLE_STEP bit from the forked task. Perhaps we should just clear the bit in the function. -- blue skies, Martin. Reality continues to ruin my life. - Calvin.
Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)
On 01/05, Martin Schwidefsky wrote: On Mon, 4 Jan 2010 13:11:47 -0800 (PST) Roland McGrath rol...@redhat.com wrote: This probably means that copy_process()-user_disable_single_step() is not enough to clear the this task wants single-stepping copied from parent. I would suspect s390's TIF_SINGLE_STEP flag here. That flag means a single-step trap occurred. This is what causes do_single_step to be called before returning to user mode, rather than the machine trap doing it directly as is done in the other arch implementations. Just my thinking as well. Oh, I am not sure. But I don't understand TIF_SINGLE_STEP on s390, absolutely. For example, why do_signal() sets TIF_SINGLE_STEP? Why can't we do --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -500,18 +500,10 @@ void do_signal(struct pt_regs *regs) clear_thread_flag(TIF_RESTORE_SIGMASK); /* -* If we would have taken a single-step trap -* for a normal instruction, act like we took -* one for the handler setup. -*/ - if (current-thread.per_info.single_step) - set_thread_flag(TIF_SINGLE_STEP); - - /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, info, ka, regs, - test_thread_flag(TIF_SINGLE_STEP)); + current-thread.per_info.single_step); } return; } ? Apart from arch/s390/signal.c, TIF_SINGLE_STEP is used by entry.S but I don't understand this asm at all. Anyway. I modified the debugging patch a bit: --- K/arch/s390/kernel/traps.c~ 2009-12-22 10:41:52.909174198 -0500 +++ K/arch/s390/kernel/traps.c 2010-01-05 09:49:19.541792379 -0500 @@ -384,6 +384,8 @@ void __kprobes do_single_step(struct pt_ } if (tracehook_consider_fatal_signal(current, SIGTRAP)) force_sig(SIGTRAP, current); + else + printk(XXX: %d %d\n, current-pid, test_thread_flag(TIF_SINGLE_STEP)); } static void default_trap_handler(struct pt_regs * regs, long interruption_code) --- Now, when I run this test-case #include stdio.h #include unistd.h #include signal.h #include sys/ptrace.h #include sys/wait.h #include assert.h int main(void) { int pid, status; if (!(pid = fork())) { assert(ptrace(PTRACE_TRACEME) == 0); kill(getpid(), SIGSTOP); if (!fork()) return 43; wait(status); return WEXITSTATUS(status); } for (;;) { assert(pid == wait(status)); if (WIFEXITED(status)) break; assert(ptrace(PTRACE_SINGLESTEP, pid, 0,0) == 0); } assert(WEXITSTATUS(status) == 43); return 0; } dmesg shows 799 lines of XXX: 2389 0 The kernel is 2.6.32.2 + utrace, but CONFIG_UTRACE is not set. Oleg.
Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)
On Tue, 5 Jan 2010 16:36:33 +0100 Oleg Nesterov o...@redhat.com wrote: On 01/05, Martin Schwidefsky wrote: On Mon, 4 Jan 2010 13:11:47 -0800 (PST) Roland McGrath rol...@redhat.com wrote: This probably means that copy_process()-user_disable_single_step() is not enough to clear the this task wants single-stepping copied from parent. I would suspect s390's TIF_SINGLE_STEP flag here. That flag means a single-step trap occurred. This is what causes do_single_step to be called before returning to user mode, rather than the machine trap doing it directly as is done in the other arch implementations. Just my thinking as well. Oh, I am not sure. But I don't understand TIF_SINGLE_STEP on s390, absolutely. For example, why do_signal() sets TIF_SINGLE_STEP? Why can't we do --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -500,18 +500,10 @@ void do_signal(struct pt_regs *regs) clear_thread_flag(TIF_RESTORE_SIGMASK); /* -* If we would have taken a single-step trap -* for a normal instruction, act like we took -* one for the handler setup. -*/ - if (current-thread.per_info.single_step) - set_thread_flag(TIF_SINGLE_STEP); - - /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, info, ka, regs, - test_thread_flag(TIF_SINGLE_STEP)); + current-thread.per_info.single_step); } return; } ? The reason why we set the TIF_SINGLE_STEP bit in do_signal is that we want to be able to stop the debugged program before the first instruction of the signal handler has been executed. The PER single step causes a trap after an instruction has been executed. That first instruction can do bad things to the arguments of the signal handler.. Apart from arch/s390/signal.c, TIF_SINGLE_STEP is used by entry.S but I don't understand this asm at all. Anyway. I modified the debugging patch a bit: --- K/arch/s390/kernel/traps.c~ 2009-12-22 10:41:52.909174198 -0500 +++ K/arch/s390/kernel/traps.c2010-01-05 09:49:19.541792379 -0500 @@ -384,6 +384,8 @@ void __kprobes do_single_step(struct pt_ } if (tracehook_consider_fatal_signal(current, SIGTRAP)) force_sig(SIGTRAP, current); + else + printk(XXX: %d %d\n, current-pid, test_thread_flag(TIF_SINGLE_STEP)); } static void default_trap_handler(struct pt_regs * regs, long interruption_code) --- Now, when I run this test-case #include stdio.h #include unistd.h #include signal.h #include sys/ptrace.h #include sys/wait.h #include assert.h int main(void) { int pid, status; if (!(pid = fork())) { assert(ptrace(PTRACE_TRACEME) == 0); kill(getpid(), SIGSTOP); if (!fork()) return 43; wait(status); return WEXITSTATUS(status); } for (;;) { assert(pid == wait(status)); if (WIFEXITED(status)) break; assert(ptrace(PTRACE_SINGLESTEP, pid, 0,0) == 0); } assert(WEXITSTATUS(status) == 43); return 0; } dmesg shows 799 lines of XXX: 2389 0 The kernel is 2.6.32.2 + utrace, but CONFIG_UTRACE is not set. With or without my bug fix ? -- blue skies, Martin. Reality continues to ruin my life. - Calvin.
Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)
On 01/05, Oleg Nesterov wrote: Anyway. I modified the debugging patch a bit: --- K/arch/s390/kernel/traps.c~ 2009-12-22 10:41:52.909174198 -0500 +++ K/arch/s390/kernel/traps.c2010-01-05 09:49:19.541792379 -0500 @@ -384,6 +384,8 @@ void __kprobes do_single_step(struct pt_ } if (tracehook_consider_fatal_signal(current, SIGTRAP)) force_sig(SIGTRAP, current); + else + printk(XXX: %d %d\n, current-pid, test_thread_flag(TIF_SINGLE_STEP)); } static void default_trap_handler(struct pt_regs * regs, long interruption_code) --- Ah, please ignore. I guess TIF_SINGLE_STEP was already cleared by the caller in entry.S Oleg.
Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)
On Tue, 5 Jan 2010 16:47:25 +0100 Oleg Nesterov o...@redhat.com wrote: On 01/05, Oleg Nesterov wrote: Anyway. I modified the debugging patch a bit: --- K/arch/s390/kernel/traps.c~ 2009-12-22 10:41:52.909174198 -0500 +++ K/arch/s390/kernel/traps.c 2010-01-05 09:49:19.541792379 -0500 @@ -384,6 +384,8 @@ void __kprobes do_single_step(struct pt_ } if (tracehook_consider_fatal_signal(current, SIGTRAP)) force_sig(SIGTRAP, current); + else + printk(XXX: %d %d\n, current-pid, test_thread_flag(TIF_SINGLE_STEP)); } static void default_trap_handler(struct pt_regs * regs, long interruption_code) --- Ah, please ignore. I guess TIF_SINGLE_STEP was already cleared by the caller in entry.S Yes, TIF_SINGLE_STEP is checked in entry.S and cleared before do_signal is called. That is the ni instruction at sysc_singlestep and sysc_sigpending. -- blue skies, Martin. Reality continues to ruin my life. - Calvin.
Re: s390 user_enable_single_step() (Was: odd utrace testing results on s390x)
On 01/05, Martin Schwidefsky wrote: On Tue, 5 Jan 2010 16:36:33 +0100 Oleg Nesterov o...@redhat.com wrote: For example, why do_signal() sets TIF_SINGLE_STEP? Why can't we do --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -500,18 +500,10 @@ void do_signal(struct pt_regs *regs) clear_thread_flag(TIF_RESTORE_SIGMASK); /* -* If we would have taken a single-step trap -* for a normal instruction, act like we took -* one for the handler setup. -*/ - if (current-thread.per_info.single_step) - set_thread_flag(TIF_SINGLE_STEP); - - /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, info, ka, regs, - test_thread_flag(TIF_SINGLE_STEP)); + current-thread.per_info.single_step); } return; } ? The reason why we set the TIF_SINGLE_STEP bit in do_signal is that we want to be able to stop the debugged program before the first instruction of the signal handler has been executed. The PER single step causes a trap after an instruction has been executed. That first instruction can do bad things to the arguments of the signal handler.. Yes, but afaics all we need is to pass the correct int stepping arg to tracehook_signal_handler(). If it is true, the tracee does ptrace_notify() before it returns to user-mode. dmesg shows 799 lines of XXX: 2389 0 The kernel is 2.6.32.2 + utrace, but CONFIG_UTRACE is not set. With or without my bug fix ? With, but please see another email. I'll add clear_bit(TIF_SINGLE_STEP) into do_fork() path and re-test. Oleg.