Trash Sessions - Sexta 18 Dezembro @ Bar O Seculo
Se não visualizares esta página correctamente, clica aqui http://www.divulgacaodigital.com/void-creations/newsletters/trash-sessions/2/email.html Adiciona-nos à tua safe-list, para garantir que recebes sempre a info dos nossos eventos. ** http://www.divulgacaodigital.com/void-creations/newsletters/trash-sessions/email.html ** **Apresenta:** Atenção, atenção…aviso à população: as Trash Sessions estão de volta!!! Depois de uma sessão inaugural de arromba - que envolveu bombas, tsunamis, playgirls, invasores extraterrestres e muito mais - reciclámo-nos e trazemos a Trash Sessions #2 de volta ao Século http://www.oseculo.com/ já na próxima sexta-feira 18 de Dezembro. Nesta segunda edição, teremos a exibição do filme de culto «The Toxic Avenger», o extraordinário «one man show» de Peltzer http://www.myspace.com/peltzermusic , que parte do ódio da máquina para criar o amor da máquina e, a terminar, o dj set dos irreverentes Blare!!! http://www.myspace.com/blaring , cujas sonoridades electrónicas irão levar os ânimos ao rubro na pista de dança e pôr toda a gente a pedir por mais. Por volta das 21h30, abrimos a tampa do contentor com a exibição do filme The Toxic Avenger http://www.imdb.com/title/tt0090190/ , um dos mais conhecidos da produtora trash Troma Entertainment. A obra ficou conhecida pela ultra-exploração da estética trash, repisando clichets dos mais variados tipos – sempre com um toque de comédia – mas ao qual se acrescenta uma curiosa vertente séria, que aborda o pior da cultura norte-americana. «Fruto da interacção homem-máquina», Peltzer http://www.myspace.com/peltzermusic viaja pelo sistema binário em procura do beat perfeito, fazendo incursões extensivas ao electro pop em canções melódicas, bem estruturadas e sempre acompanhadas de uma imagética própria. Um dos Talentos Fnac 2009 – e já com uns aninhos de estrada - este robot muito humano confessa que «odeia máquinas», já que o tornam «preguiçoso, ansioso, confuso e eufórico». Porém, utiliza-as, admira-as e explora periféricos, criando atmosferas repletas de biologia mecânica que aquecem o coração ao mais frio dos robots. O dj set de Blare!!! http://www.myspace.com/blaring , composto por Bernardo Drummundo e Miguel Azevedo, começou inicialmente pelos remixes de nomes consagrados das pistas de dança como Miss Kittin, Basement Jaxx, Spektrum e outras variações como Nine Inch Nails ou Gorilaz. Porém, embora o seu leque de influências seja vasto (dos 70’s. 80’s, jazz, música clássica, etc) é na electrónica que se encontram e que põem toda a gente a dançar. Juntos, passam som para passar vibrações positivas, energia e levar o público aos limites da euforia! Os visuais estarão a cargo da VJ Psyberdoll, que desde 2005 encontrou nos audiovisuais a sua melhor forma de expressão. Desde então, tem explorado as potencialidades de fusão entre o orgânico e o tecnológico. Toda a gente está convidada e a festa está prontíssima! Vamos contar com o assobiador do Chiado e muitas mais personagens obscuras. Do you think you got what it takes...? Aparece!! A entrada é livre com flyer! Local: O Século – Centro Cultural Hora: 21h30 Entrada: Livre com apresentação de flyer / sem flyer 3€ Morada: Rua do Século nº 80, 1200-436, Bairro Alto, Lisboa Mapa: ** ** Contactos: Void Creations E-mail: i...@voidcreations.org www.voidcreations.org @ http://www.voidcreations.blogspot.com http://www.voidcreations.blogspot.com http://www.myspace.com/voidcreations http://twitter.com/voidcreations http://www.hi5.com/friend/profile/displayProfile.do?userid=60279032 http://www.youtube.com/user/voidcreations - é favor divulgar - ** ** Para RE-ENVIAR / To FORWARD - http://www.divulgacaodigital.com/void-creations/?p=forwarduid=8796d6f78d5efbb8958965a0e70ab9c8mid=21 Para REMOVER / To REMOVE - http://www.divulgacaodigital.com/void-creations/?p=unsubscribeuid=8796d6f78d5efbb8958965a0e70ab9c8 Para MODIFICAR / To MODIFY - http://www.divulgacaodigital.com/void-creations/?p=preferencesuid=8796d6f78d5efbb8958965a0e70ab9c8 -- Powered by PHPlist, www.phplist.com -- inline: powerphplist.png
[PATCH 1/2] utrace: s/rmb/mb/ in tracehook_notify_resume()
It was always supposed to be mb(), not rmb(). Signed-off-by: Oleg Nesterov o...@redhat.com --- include/linux/tracehook.h | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) --- UTRACE_PTRACE/include/linux/tracehook.h~1_NOTIFY_RESUME_MB 2009-12-17 17:00:31.0 +0100 +++ UTRACE_PTRACE/include/linux/tracehook.h 2009-12-17 23:53:51.0 +0100 @@ -670,12 +670,12 @@ static inline void tracehook_notify_resu { struct task_struct *task = current; /* -* If we race with attach which sets nonzero -utrace_flags, -* make sure we do not read -utrace_flags before the caller -* clears TIF_NOTIFY_RESUME. This pairs with the implicit mb() -* before setting TIF_NOTIFY_RESUME in set_notify_resume(). +* Prevent the following store/load from getting ahead of the +* caller which clears TIF_NOTIFY_RESUME. This pairs with the +* implicit mb() before setting TIF_NOTIFY_RESUME in +* set_notify_resume(). */ - smp_rmb(); + smp_mb(); if (task_utrace_flags(task)) utrace_resume(task, regs); }
[PATCH 2/2] utrace: move CONFIG_UTRACE after AUDITSYSCALL in init/Kconfig
Somehow I placed CONFIG_UTRACE between AUDIT and AUDITSYSCALL, move it down after AUDITSYSCALL. Signed-off-by: Oleg Nesterov o...@redhat.com --- init/Kconfig | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) --- UTRACE_PTRACE/init/Kconfig~2_CONFIG_UTRACE_AUDIT2009-12-17 17:00:31.0 +0100 +++ UTRACE_PTRACE/init/Kconfig 2009-12-17 23:59:11.0 +0100 @@ -295,15 +295,6 @@ config AUDIT logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL. -config UTRACE - bool Infrastructure for tracing and debugging user processes - depends on EXPERIMENTAL - depends on HAVE_ARCH_TRACEHOOK - help - Enable the utrace process tracing interface. This is an internal - kernel interface exported to kernel modules, to track events in - user threads, extract and change user thread state. - config AUDITSYSCALL bool Enable system-call auditing support depends on AUDIT (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH) @@ -319,6 +310,15 @@ config AUDIT_TREE depends on AUDITSYSCALL select INOTIFY +config UTRACE + bool Infrastructure for tracing and debugging user processes + depends on EXPERIMENTAL + depends on HAVE_ARCH_TRACEHOOK + help + Enable the utrace process tracing interface. This is an internal + kernel interface exported to kernel modules, to track events in + user threads, extract and change user thread state. + menu RCU Subsystem choice
x86: do_debug PTRACE_SINGLESTEP broken by 08d68323d1f0c34452e614263b212ca556dae47f
Hi. do_debug() is obviously wrong wrt PTRACE_SINGLESTEP/TIF_SINGLESTEP, no? Afaics this was broken by hw-breakpoints: modifying generic debug exception to use thread-specific debug registers commit 08d68323d1f0c34452e614263b212ca556dae47f To verify, the patch below fixes the stepping for me, not sure what is the proper fix... Oleg. --- arch/x86/kernel/traps.c~2009-12-18 00:20:49.0 +0100 +++ arch/x86/kernel/traps.c 2009-12-18 01:44:05.0 +0100 @@ -575,7 +575,7 @@ dotraplinkage void __kprobes do_debug(st regs-flags = ~X86_EFLAGS_TF; } si_code = get_si_code(tsk-thread.debugreg6); - if (tsk-thread.debugreg6 (DR_STEP | DR_TRAP_BITS)) +// if (tsk-thread.debugreg6 (DR_STEP | DR_TRAP_BITS)) send_sigtrap(tsk, regs, error_code, si_code); preempt_conditional_cli(regs);
[PATCH 3/7] ptrace_signal: check PT_PTRACED before reporting a signal
No functional changes, preparation for utrace-ptrace. Change ptrace_signal() to check PT_PTRACED instead of task_ptrace() != 0. Currently this is the same, PT_PTRACED must be always set if the task is ptraced. This change is needed to make sure ptrace_signal() does nothing if ptrace is implemented on top of utrace, eventually this code will be removed completely. Signed-off-by: Roland McGrath rol...@redhat.com Signed-off-by: Oleg Nesterov o...@redhat.com --- kernel/signal.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- V1/kernel/signal.c~3_PTRACE_SIGNAL_CK_PTRACED 2009-12-18 00:20:50.0 +0100 +++ V1/kernel/signal.c 2009-12-18 00:48:35.0 +0100 @@ -1764,7 +1764,7 @@ static int do_signal_stop(int signr) static int ptrace_signal(int signr, siginfo_t *info, struct pt_regs *regs, void *cookie) { - if (!task_ptrace(current)) + if (!(task_ptrace(current) PT_PTRACED)) return signr; ptrace_signal_deliver(regs, cookie);
[PATCH 4/7] export __ptrace_detach() and do_notify_parent_cldstop()
Export __ptrace_detach() and do_notify_parent_cldstop() for ptrace-utrace. Signed-off-by: Roland McGrath rol...@redhat.com Signed-off-by: Oleg Nesterov o...@redhat.com --- include/linux/ptrace.h |1 + include/linux/sched.h |1 + kernel/ptrace.c|2 +- kernel/signal.c|2 +- 4 files changed, 4 insertions(+), 2 deletions(-) --- V1/include/linux/ptrace.h~4_EXPORT_2_HELPERS2009-12-18 00:20:50.0 +0100 +++ V1/include/linux/ptrace.h 2009-12-18 00:53:58.0 +0100 @@ -85,6 +85,7 @@ extern int ptrace_traceme(void); extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); extern int ptrace_attach(struct task_struct *tsk); +extern bool __ptrace_detach(struct task_struct *tracer, struct task_struct *tracee); extern int ptrace_detach(struct task_struct *, unsigned int); extern void ptrace_disable(struct task_struct *); extern int ptrace_check_attach(struct task_struct *task, int kill); --- V1/include/linux/sched.h~4_EXPORT_2_HELPERS 2009-12-18 00:20:50.0 +0100 +++ V1/include/linux/sched.h2009-12-18 00:53:58.0 +0100 @@ -2081,6 +2081,7 @@ extern int kill_pgrp(struct pid *pid, in extern int kill_pid(struct pid *pid, int sig, int priv); extern int kill_proc_info(int, struct siginfo *, pid_t); extern int do_notify_parent(struct task_struct *, int); +extern void do_notify_parent_cldstop(struct task_struct *, int); extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent); extern void force_sig(int, struct task_struct *); extern int send_sig(int, struct task_struct *, int); --- V1/kernel/ptrace.c~4_EXPORT_2_HELPERS 2009-09-24 21:38:54.0 +0200 +++ V1/kernel/ptrace.c 2009-12-18 00:53:58.0 +0100 @@ -271,7 +271,7 @@ static int ignoring_children(struct sigh * reap it now, in that case we must also wake up sub-threads sleeping in * do_wait(). */ -static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) +bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) { __ptrace_unlink(p); --- V1/kernel/signal.c~4_EXPORT_2_HELPERS 2009-12-18 00:48:35.0 +0100 +++ V1/kernel/signal.c 2009-12-18 00:53:58.0 +0100 @@ -1494,7 +1494,7 @@ int do_notify_parent(struct task_struct return ret; } -static void do_notify_parent_cldstop(struct task_struct *tsk, int why) +void do_notify_parent_cldstop(struct task_struct *tsk, int why) { struct siginfo info; unsigned long flags;
[PATCH 5/7] reorder the code in kernel/ptrace.c
No functional changes, preparation for the next patch. Move the code which can be shared with ptrace-utrace up, before __ptrace_link(). This way ptrace-utrace needs a single #ifdef in ptrace.c. Signed-off-by: Roland McGrath rol...@redhat.com Signed-off-by: Oleg Nesterov o...@redhat.com --- kernel/ptrace.c | 556 1 file changed, 278 insertions(+), 278 deletions(-) --- V1/kernel/ptrace.c~5_REORDER_PTRACE_C 2009-12-18 00:53:58.0 +0100 +++ V1/kernel/ptrace.c 2009-12-18 01:00:26.0 +0100 @@ -23,6 +23,284 @@ #include linux/syscalls.h #include linux/uaccess.h +int __ptrace_may_access(struct task_struct *task, unsigned int mode) +{ + const struct cred *cred = current_cred(), *tcred; + + /* May we inspect the given task? +* This check is used both for attaching with ptrace +* and for allowing access to sensitive information in /proc. +* +* ptrace_attach denies several cases that /proc allows +* because setting up the necessary parent/child relationship +* or halting the specified task is impossible. +*/ + int dumpable = 0; + /* Don't let security modules deny introspection */ + if (task == current) + return 0; + rcu_read_lock(); + tcred = __task_cred(task); + if ((cred-uid != tcred-euid || +cred-uid != tcred-suid || +cred-uid != tcred-uid || +cred-gid != tcred-egid || +cred-gid != tcred-sgid || +cred-gid != tcred-gid) + !capable(CAP_SYS_PTRACE)) { + rcu_read_unlock(); + return -EPERM; + } + rcu_read_unlock(); + smp_rmb(); + if (task-mm) + dumpable = get_dumpable(task-mm); + if (!dumpable !capable(CAP_SYS_PTRACE)) + return -EPERM; + + return security_ptrace_access_check(task, mode); +} + +bool ptrace_may_access(struct task_struct *task, unsigned int mode) +{ + int err; + task_lock(task); + err = __ptrace_may_access(task, mode); + task_unlock(task); + return !err; +} + +/* + * Called with irqs disabled, returns true if childs should reap themselves. + */ +static int ignoring_children(struct sighand_struct *sigh) +{ + int ret; + spin_lock(sigh-siglock); + ret = (sigh-action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || + (sigh-action[SIGCHLD-1].sa.sa_flags SA_NOCLDWAIT); + spin_unlock(sigh-siglock); + return ret; +} + +/* + * Called with tasklist_lock held for writing. + * Unlink a traced task, and clean it up if it was a traced zombie. + * Return true if it needs to be reaped with release_task(). + * (We can't call release_task() here because we already hold tasklist_lock.) + * + * If it's a zombie, our attachedness prevented normal parent notification + * or self-reaping. Do notification now if it would have happened earlier. + * If it should reap itself, return true. + * + * If it's our own child, there is no notification to do. But if our normal + * children self-reap, then this child was prevented by ptrace and we must + * reap it now, in that case we must also wake up sub-threads sleeping in + * do_wait(). + */ +bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) +{ + __ptrace_unlink(p); + + if (p-exit_state == EXIT_ZOMBIE) { + if (!task_detached(p) thread_group_empty(p)) { + if (!same_thread_group(p-real_parent, tracer)) + do_notify_parent(p, p-exit_signal); + else if (ignoring_children(tracer-sighand)) { + __wake_up_parent(p, tracer); + p-exit_signal = -1; + } + } + if (task_detached(p)) { + /* Mark it as in the process of being reaped. */ + p-exit_state = EXIT_DEAD; + return true; + } + } + + return false; +} + +int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) +{ + int copied = 0; + + while (len 0) { + char buf[128]; + int this_len, retval; + + this_len = (len sizeof(buf)) ? sizeof(buf) : len; + retval = access_process_vm(tsk, src, buf, this_len, 0); + if (!retval) { + if (copied) + break; + return -EIO; + } + if (copy_to_user(dst, buf, retval)) + return -EFAULT; + copied += retval; + src += retval; + dst += retval; + len -= retval; + } + return copied; +} + +int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int
[PATCH 6/7] implement utrace-ptrace
The patch adds the new file, kernel/ptrace-utrace.c, which contains the new implementation of ptrace over utrace. This file is not compiled until we have CONFIG_UTRACE option, will be added by the next utrace core patch. It's supposed to be an invisible implementation change, nothing should change to userland when CONFIG_UTRACE is enabled. Signed-off-by: Roland McGrath rol...@redhat.com Signed-off-by: Oleg Nesterov o...@redhat.com --- include/linux/ptrace.h |2 kernel/Makefile|1 kernel/ptrace.c|2 kernel/ptrace-utrace.c | 1080 + 4 files changed, 1084 insertions(+), 1 deletion(-) --- V1/include/linux/ptrace.h~6_UTRACE_PTRACE 2009-12-18 00:53:58.0 +0100 +++ V1/include/linux/ptrace.h 2009-12-18 01:04:56.0 +0100 @@ -79,7 +79,7 @@ #include linux/compiler.h/* For unlikely. */ #include linux/sched.h /* For struct task_struct. */ - +extern void ptrace_notify_stop(struct task_struct *tracee); extern long arch_ptrace(struct task_struct *child, long request, long addr, long data); extern int ptrace_traceme(void); extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); --- V1/kernel/Makefile~6_UTRACE_PTRACE 2009-12-18 00:20:50.0 +0100 +++ V1/kernel/Makefile 2009-12-18 01:57:41.0 +0100 @@ -69,6 +69,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o obj-$(CONFIG_STOP_MACHINE) += stop_machine.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o +obj-$(CONFIG_UTRACE) += ptrace-utrace.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o audit_watch.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_GCOV_KERNEL) += gcov/ --- V1/kernel/ptrace.c~6_UTRACE_PTRACE 2009-12-18 01:00:26.0 +0100 +++ V1/kernel/ptrace.c 2009-12-18 01:04:56.0 +0100 @@ -302,6 +302,7 @@ asmlinkage long compat_sys_ptrace(compat } #endif /* CONFIG_COMPAT */ +#ifndef CONFIG_UTRACE /* * ptrace a task: make the debugger its new parent and * move it to the ptrace list. @@ -762,3 +763,4 @@ int compat_ptrace_request(struct task_st return ret; } #endif /* CONFIG_COMPAT */ +#endif /* CONFIG_UTRACE */ --- /dev/null 2009-12-15 18:13:27.615265787 +0100 +++ V1/kernel/ptrace-utrace.c 2009-12-18 01:09:36.0 +0100 @@ -0,0 +1,1080 @@ +/* + * linux/kernel/ptrace.c + * + * (C) Copyright 1999 Linus Torvalds + * + * Common interfaces for ptrace() which we do not want + * to continually duplicate across every architecture. + */ + +#include linux/capability.h +#include linux/module.h +#include linux/sched.h +#include linux/errno.h +#include linux/mm.h +#include linux/highmem.h +#include linux/pagemap.h +#include linux/smp_lock.h +#include linux/ptrace.h +#include linux/utrace.h +#include linux/security.h +#include linux/signal.h +#include linux/audit.h +#include linux/pid_namespace.h +#include linux/syscalls.h +#include linux/uaccess.h + +/* + * ptrace a task: make the debugger its new parent and + * move it to the ptrace list. + * + * Must be called with the tasklist lock write-held. + */ +void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) +{ + BUG_ON(!list_empty(child-ptrace_entry)); + list_add(child-ptrace_entry, new_parent-ptraced); + child-parent = new_parent; +} + +/* + * unptrace a task: move it back to its original parent and + * remove it from the ptrace list. + * + * Must be called with the tasklist lock write-held. + */ +void __ptrace_unlink(struct task_struct *child) +{ + BUG_ON(!child-ptrace); + + child-ptrace = 0; + child-parent = child-real_parent; + list_del_init(child-ptrace_entry); + + arch_ptrace_untrace(child); +} + +struct ptrace_context { + int options; + + int signr; + siginfo_t *siginfo; + + int stop_code; + unsigned long eventmsg; + + enum utrace_resume_action resume; +}; + +#define PT_UTRACED 0x1000 + +#define PTRACE_O_SYSEMU0x100 + +#define PTRACE_EVENT_SYSCALL (1 16) +#define PTRACE_EVENT_SIGTRAP (2 16) +#define PTRACE_EVENT_SIGNAL(3 16) +/* events visible to user-space */ +#define PTRACE_EVENT_MASK 0x + +static inline bool ptrace_event_pending(struct ptrace_context *ctx) +{ + return ctx-stop_code != 0; +} + +static inline int get_stop_event(struct ptrace_context *ctx) +{ + return ctx-stop_code 8; +} + +static inline void set_stop_code(struct ptrace_context *ctx, int event) +{ + ctx-stop_code = (event 8) | SIGTRAP; +} + +static inline struct ptrace_context * +ptrace_context(struct utrace_engine *engine) +{ + return engine-data; +} + +static const struct utrace_engine_ops ptrace_utrace_ops; /*
Re: x86: do_debug PTRACE_SINGLESTEP broken by 08d68323d1f0c34452e614263b212ca556dae47f
Comparing to the old (2.6.32) logic, I think it might be this (untested). I also note this is the sole use of get_si_code, seems like it should just be rolled in here. Thanks, Roland diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 3339917..16a88f5 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -530,7 +530,6 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) { struct task_struct *tsk = current; unsigned long dr6; - int si_code; get_debugreg(dr6, 6); @@ -569,14 +568,15 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) * We already checked v86 mode above, so we can check for kernel mode * by just checking the CPL of CS. */ + dr6 = tsk-thread.debugreg6; if ((dr6 DR_STEP) !user_mode(regs)) { tsk-thread.debugreg6 = ~DR_STEP; set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs-flags = ~X86_EFLAGS_TF; + } else if (dr6 (DR_STEP | DR_TRAP_BITS)) { + send_sigtrap(tsk, regs, error_code, get_si_code(dr6)); } - si_code = get_si_code(tsk-thread.debugreg6); - if (tsk-thread.debugreg6 (DR_STEP | DR_TRAP_BITS)) - send_sigtrap(tsk, regs, error_code, si_code); + preempt_conditional_cli(regs); return;
Re: x86: do_debug PTRACE_SINGLESTEP broken by 08d68323d1f0c34452e614263b212ca556dae47f
On 12/17, Roland McGrath wrote: Comparing to the old (2.6.32) logic, I think it might be this (untested). I also note this is the sole use of get_si_code, seems like it should just be rolled in here. Well, it is too late for me to even try to read this patch ;) but... @@ -569,14 +568,15 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) * We already checked v86 mode above, so we can check for kernel mode * by just checking the CPL of CS. */ + dr6 = tsk-thread.debugreg6; why? we have tsk-thread.debugreg6 = dr6 above if ((dr6 DR_STEP) !user_mode(regs)) { tsk-thread.debugreg6 = ~DR_STEP; set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs-flags = ~X86_EFLAGS_TF; this looks strange... we set TIF_SINGLESTEP but clear X86_EFLAGS_TF + } else if (dr6 (DR_STEP | DR_TRAP_BITS)) { + send_sigtrap(tsk, regs, error_code, get_si_code(dr6)); } - si_code = get_si_code(tsk-thread.debugreg6); - if (tsk-thread.debugreg6 (DR_STEP | DR_TRAP_BITS)) - send_sigtrap(tsk, regs, error_code, si_code); + can't understand how this change can fix the problem. We should always send SIGTRAP if the task returns to user-mode with X86_EFLAGS_TF? OK. I blindly applied this patch, step-simple still fails. Oleg.
Re: x86: do_debug PTRACE_SINGLESTEP broken by 08d68323d1f0c34452e614263b212ca556dae47f
On Fri, Dec 18, 2009 at 03:10:42AM +0100, Oleg Nesterov wrote: On 12/17, Roland McGrath wrote: Comparing to the old (2.6.32) logic, I think it might be this (untested). I also note this is the sole use of get_si_code, seems like it should just be rolled in here. Well, it is too late for me to even try to read this patch ;) but... @@ -569,14 +568,15 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) * We already checked v86 mode above, so we can check for kernel mode * by just checking the CPL of CS. */ + dr6 = tsk-thread.debugreg6; why? we have tsk-thread.debugreg6 = dr6 above Yeah. if ((dr6 DR_STEP) !user_mode(regs)) { tsk-thread.debugreg6 = ~DR_STEP; set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs-flags = ~X86_EFLAGS_TF; this looks strange... we set TIF_SINGLESTEP but clear X86_EFLAGS_TF Yep, I don't understand what happens here either. This logic was there before the refactoring and the comment indicates we want to ignore traps from kernel. Why do we set this flag in a random thread? + } else if (dr6 (DR_STEP | DR_TRAP_BITS)) { + send_sigtrap(tsk, regs, error_code, get_si_code(dr6)); } - si_code = get_si_code(tsk-thread.debugreg6); - if (tsk-thread.debugreg6 (DR_STEP | DR_TRAP_BITS)) - send_sigtrap(tsk, regs, error_code, si_code); + can't understand how this change can fix the problem. We should always send SIGTRAP if the task returns to user-mode with X86_EFLAGS_TF? OK. I blindly applied this patch, step-simple still fails. Yep, that doesn't fix your problem but this patch makes sense in that if we were not in user mode while the step occured, we shouldn't send the signal.
Re: x86: do_debug PTRACE_SINGLESTEP broken by 08d68323d1f0c34452e614263b212ca556dae47f
+ dr6 = tsk-thread.debugreg6; why? we have tsk-thread.debugreg6 = dr6 above Yeah, it's a little superfluous. Except that the existing code uses tsk-thread.debugreg6 and dr6 inconsistently. It only matters either way if some notifier function might change thread.debugreg6, which I wasn't sure that none might. i.e., does/should hw_breakpoint hide/remap the watchpoint-fired bits when they are not for the same-numbered, ptrace-installed virtual debugreg? And does/should kprobes, kgdb, and whatnot, hide DR_STEP from thread.debugreg6 for a step that's not from user_enable_single_step? if ((dr6 DR_STEP) !user_mode(regs)) { tsk-thread.debugreg6 = ~DR_STEP; set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs-flags = ~X86_EFLAGS_TF; this looks strange... we set TIF_SINGLESTEP but clear X86_EFLAGS_TF This was the original purpose of TIF_SINGLESTEP from long, long ago. This happens when TF was set in user mode and then it did syscall/sysenter so TF is still set at the first instruction in kernel mode. TF is cleared from the interrupted kernel registers so the kernel can resume normally. In the original logic, TIF_SINGLESTEP served just to make it turn TF back on when going to user mode. Since then we grew the complicated step.c stuff and it all fits together slightly differently than it did when the original traps.c path was written. can't understand how this change can fix the problem. We should always send SIGTRAP if the task returns to user-mode with X86_EFLAGS_TF? If the debug exception happened in user mode, then we should send SIGTRAP. In the old (2.6.32) code with its goto-heavy logic the !user_mode(regs) was goto clear_TF_reenable; and that is: clear_TF_reenable: set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs-flags = ~X86_EFLAGS_TF; preempt_conditional_cli(regs); return; I thought the new logic was falling through to the send_sigtrap case after if ((dr6 DR_STEP) !user_mode(regs)). But now I see that the subtle use of dr6 vs tsk-thread.debugreg6 (without comments about it!) meant that DR_STEP is cleared from tsk-thread.debugreg6 before we test it. So I guess the idea there is that the !user_mode case would swallow the step indication but still leave some DR_TRAP_BITS set and so you'd generate a user SIGTRAP in honor of those (i.e. watchpoint hits). But I thought the hardware behavior was that a step will set DR_STEP in DR6 but not clear any DR_TRAP_BITS set from before, so I'm not sure this can't sometimes send a SIGTRAP twice for a combination of a watchpoint hit and a delayed step. OK. I blindly applied this patch, step-simple still fails. Yeah, it was a quick reaction to the funny-looking control flow. But I didn't really investigate what is actually happening. Thanks, Roland