Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kerneltoast/f143ef88da408449bbdfbd13b4f50c01 to your computer and use it in GitHub Desktop.
Save kerneltoast/f143ef88da408449bbdfbd13b4f50c01 to your computer and use it in GitHub Desktop.
From 103a2cf9c1fee88516584716ed5ea15b43e0d162 Mon Sep 17 00:00:00 2001
From: Sultan Alsawaf <sultan@openresty.com>
Date: Thu, 29 Oct 2020 11:05:53 -0700
Subject: [PATCH] task_finder2: change the default engine action to
UTRACE_INTERRUPT
There is a race condition where, right after an engine is attached, a
reporting pass will occur before the engine can actually request what it
wants from the target process. In this case, the action that the engine
used when it was first attached will be carried out during the reporting
pass. When the default action is UTRACE_STOP, this means that the
reporting pass will think the newly-attached engine wants to stop the
target process, at which point the target process will be moved into the
TASK_TRACED state (visible via `ps aux | grep ' t '`) and will be
halted forever (until it receives a SIGKILL) because the engine will
never send a UTRACE_RESUME request to bring the target process back to
life. This seems to be an issue with the UTRACE_STOP machinery; it's not
clear how *any* process entering the UTRACE_STOP state can exit that
state naturally. It's also dubious whether the UTRACE_STOP state is even
needed, since tracing is done from within task workers that run inside
the context of the process we're trying to analyze, which allows us to
to safely analyze the process without needing to stop it.
Regardless, it's clear that a newly-attached engine would definitely not
want to stop the process it's trying to analyze; after all, there's
nothing interesting to see if the process is just halted. The common
engine action seems to be UTRACE_INTERRUPT, so let's set that to be the
default instead of UTRACE_STOP.
---
runtime/linux/task_finder2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
index 32c66370a..8607034d7 100644
--- a/runtime/linux/task_finder2.c
+++ b/runtime/linux/task_finder2.c
@@ -918,7 +918,7 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk,
// when the thread gets quiesced.
rc = __stp_utrace_attach(tsk, &tgt->ops, tgt,
__STP_ATTACHED_TASK_EVENTS,
- UTRACE_STOP);
+ UTRACE_INTERRUPT);
if (rc != 0 && rc != EPERM)
break;
tgt->engine_attached = 1;
@@ -1868,7 +1868,7 @@ stap_start_task_finder(void)
// Set up events we need for attached tasks.
rc = __stp_utrace_attach(tsk, &tgt->ops, tgt,
__STP_ATTACHED_TASK_EVENTS,
- UTRACE_STOP);
+ UTRACE_INTERRUPT);
dbug_task(2, "__stp_utrace_attach() for %d returned %d", tsk->tgid,
rc);
--
2.29.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment