[PATCH 47] mv task_struct->last_siginfo ptrace_context->siginfo
Oleg Nesterov
oleg at redhat.com
Thu Sep 17 19:08:21 UTC 2009
Introduce ptrace_context->siginfo. Of course the usage of context->siginfo
is still wrong. But this change is important, previously PTRACE_DETACH can
leave the tracee with ->last_siginfo != NULL.
ptrace_getsiginfo/ptrace_setsiginfo need cleanups (and fixes). I think we
need ptrace_lookup_engine() helper, and ptrace_request() should find the
engine and pass it to ptrace_resume/etc.
---
kernel/ptrace.c | 38 +++++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)
--- PU/kernel/ptrace.c~47_CTX_SIGINFO 2009-09-17 19:33:34.000000000 +0200
+++ PU/kernel/ptrace.c 2009-09-17 20:13:24.000000000 +0200
@@ -38,6 +38,8 @@ struct ptrace_event {
struct ptrace_context {
int options;
+ siginfo_t *siginfo;
+
struct ptrace_event ev_array[2];
unsigned int ev_first, ev_last;
};
@@ -319,7 +321,7 @@ static u32 ptrace_report_exec(enum utrac
static void ptrace_resume_signal(struct utrace_engine *engine,
struct task_struct *tracee, long data)
{
- siginfo_t *info = tracee->last_siginfo;
+ siginfo_t *info = ptrace_context(engine)->siginfo;
if (WARN_ON(!info))
return;
@@ -355,12 +357,12 @@ static u32 ptrace_report_signal(u32 acti
case UTRACE_SIGNAL_HANDLER:
WARN_ON(1);
case UTRACE_SIGNAL_REPORT:
- if (!task->last_siginfo)
+ if (!context->siginfo)
return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
- if (WARN_ON(task->last_siginfo != info))
+ if (WARN_ON(context->siginfo != info))
return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
- task->last_siginfo = NULL;
+ context->siginfo = NULL;
if (!info->si_signo) // debugger cancelled sig
return UTRACE_RESUME | UTRACE_SIGNAL_IGN;
@@ -379,10 +381,10 @@ static u32 ptrace_report_signal(u32 acti
return UTRACE_RESUME | UTRACE_SIGNAL_DELIVER;
default:
- WARN_ON(task->last_siginfo);
- task->last_siginfo = info;
+ WARN_ON(context->siginfo);
+ context->siginfo = info;
// Make sure the next UTRACE_SIGNAL_REPORT
- // will clear ->last_siginfo
+ // will clear context->siginfo
utrace_control(task, engine, UTRACE_INTERRUPT);
ev = ev_push(context);
@@ -817,33 +819,47 @@ static int ptrace_set_options(struct tas
static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
{
+ struct utrace_engine *engine = utrace_attach_task(child, UTRACE_ATTACH_MATCH_OPS,
+ &ptrace_utrace_ops, NULL);
unsigned long flags;
int error = -ESRCH;
+ if (IS_ERR(engine))
+ return error;
+
if (lock_task_sighand(child, &flags)) {
error = -EINVAL;
- if (likely(child->last_siginfo != NULL)) {
- *info = *child->last_siginfo;
+ if (likely(ptrace_context(engine)->siginfo != NULL)) {
+ *info = *ptrace_context(engine)->siginfo;
error = 0;
}
unlock_task_sighand(child, &flags);
}
+
+ utrace_engine_put(engine);
return error;
}
static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info)
{
+ struct utrace_engine *engine = utrace_attach_task(child, UTRACE_ATTACH_MATCH_OPS,
+ &ptrace_utrace_ops, NULL);
unsigned long flags;
int error = -ESRCH;
+ if (IS_ERR(engine))
+ return error;
+
if (lock_task_sighand(child, &flags)) {
error = -EINVAL;
- if (likely(child->last_siginfo != NULL)) {
- *child->last_siginfo = *info;
+ if (likely(ptrace_context(engine)->siginfo != NULL)) {
+ *ptrace_context(engine)->siginfo = *info;
error = 0;
}
unlock_task_sighand(child, &flags);
}
+
+ utrace_engine_put(engine);
return error;
}
More information about the utrace-devel
mailing list