Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2011-10-07 00:40:52 +0000
committerEugene Tarassov2011-10-07 00:40:52 +0000
commit9a8eb4b3a2582b910c4b3e9b9a96d2d88324046d (patch)
tree759ba17bd20f26e66c1b47b4915ba3c9f5ad1eb4 /system/GNU/Linux/context-linux.c
parent6ac2b9cdaaebcbbbca360b2a55d57d5ad78e2863 (diff)
downloadorg.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.c38
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();

Back to the top