diff options
author | Eugene Tarassov | 2011-10-07 00:40:52 +0000 |
---|---|---|
committer | Eugene Tarassov | 2011-10-07 00:40:52 +0000 |
commit | 9a8eb4b3a2582b910c4b3e9b9a96d2d88324046d (patch) | |
tree | 759ba17bd20f26e66c1b47b4915ba3c9f5ad1eb4 /system/GNU/Linux/context-linux.c | |
parent | 6ac2b9cdaaebcbbbca360b2a55d57d5ad78e2863 (diff) | |
download | org.eclipse.tcf.agent-9a8eb4b3a2582b910c4b3e9b9a96d2d88324046d.tar.gz org.eclipse.tcf.agent-9a8eb4b3a2582b910c4b3e9b9a96d2d88324046d.tar.xz org.eclipse.tcf.agent-9a8eb4b3a2582b910c4b3e9b9a96d2d88324046d.zip |
TCF Agent: Linux: fixed removing of breakpoints after fork when children auto-attach is off.
Diffstat (limited to 'system/GNU/Linux/context-linux.c')
-rw-r--r-- | system/GNU/Linux/context-linux.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/system/GNU/Linux/context-linux.c b/system/GNU/Linux/context-linux.c index b7f90b82..e1577d52 100644 --- a/system/GNU/Linux/context-linux.c +++ b/system/GNU/Linux/context-linux.c @@ -76,6 +76,8 @@ static const int PTRACE_FLAGS = #endif PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXEC | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXIT; @@ -105,6 +107,7 @@ static size_t context_extension_offset = 0; #include <system/pid-hash.h> static LINK pending_list; +static LINK detach_list; static MemoryErrorInfo mem_err_info; @@ -808,24 +811,35 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) { } } - if (ctx == NULL) return; + if (ctx == NULL) { + ctx = context_find_from_pid(pid, 0); + if (ctx != NULL) { + /* Fork child that we don't want to attach */ + unplant_breakpoints(ctx); + assert(ctx->ref_count == 1); + ctx->exited = 1; + if (ptrace((enum __ptrace_request)PTRACE_DETACH, pid, 0, 0) < 0) { + trace(LOG_ALWAYS, "error: ptrace(PTRACE_DETACH) failed: pid %d, error %d %s", + pid, errno, errno_to_str(errno)); + } + list_remove(ctx2pidlink(ctx)); + context_unlock(ctx); + } + detach_waitpid_process(); + return; + } ext = EXT(ctx); assert(!ctx->exited); assert(!ext->attach_callback); if (ext->ptrace_flags == 0) { - int flags = PTRACE_FLAGS; - if (ext->attach_children) { - flags |= PTRACE_O_TRACEFORK; - flags |= PTRACE_O_TRACEVFORK; - } - if (ptrace((enum __ptrace_request)PTRACE_SETOPTIONS, ext->pid, 0, flags) < 0 && errno != ESRCH) { + if (ptrace((enum __ptrace_request)PTRACE_SETOPTIONS, ext->pid, 0, PTRACE_FLAGS) < 0 && errno != ESRCH) { int err = errno; trace(LOG_ALWAYS, "error: ptrace(PTRACE_SETOPTIONS) failed: pid %d, error %d %s", ext->pid, err, errno_to_str(err)); } else { - ext->ptrace_flags = flags; + ext->ptrace_flags = PTRACE_FLAGS; } } @@ -877,8 +891,13 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) { prs2->sig_dont_stop = ctx->sig_dont_stop; prs2->sig_dont_pass = ctx->sig_dont_pass; link_context(prs2); - send_context_created_event(prs2); clone_breakpoints_on_process_fork(ctx, prs2); + if (!ext->attach_children) { + list_remove(&prs2->ctxl); + list_add_first(&prs2->ctxl, &detach_list); + break; + } + send_context_created_event(prs2); } ctx2 = create_context(pid2id(msg, EXT(prs2)->pid)); @@ -1135,6 +1154,7 @@ static void eventpoint_at_main(Context * ctx, void * args) { void init_contexts_sys_dep(void) { list_init(&pending_list); + list_init(&detach_list); context_extension_offset = context_extension(sizeof(ContextExtensionLinux)); add_waitpid_listener(waitpid_listener, NULL); ini_context_pid_hash(); |