Skip to content

Instantly share code, notes, and snippets.

@agentzh
Created October 1, 2020 21:44
Show Gist options
  • Save agentzh/390c64b938018251d75b442e86e183e9 to your computer and use it in GitHub Desktop.
Save agentzh/390c64b938018251d75b442e86e183e9 to your computer and use it in GitHub Desktop.
commit 2a73da6fc0913bc08fb249138937765fceb7e650
Author: Sultan Alsawaf <sultan@openresty.com>
Date: Wed Sep 30 21:09:31 2020 -0700
task_finder2: don't filter out UTRACE_RESUME actions to fix stapio Dl+ hangs
UTRACE_RESUME is the complement to UTRACE_STOP, and currently it is always
ignored. So when UTRACE_STOP is done, the traced process can remain stuck
sleeping forever inside the utrace_stop() function at the schedule() line.
The only ways to wake the sleeping process from its endless sleep are to
either send a SIGKILL to it or to restore it with UTRACE_RESUME.
When processes hang due to this bug, stp_task_work_exit() loops forever
waiting for the stp_task_work_callbacks counter to hit zero, which will
never happen.
diff --git a/runtime/linux/task_finder2.c b/runtime/linux/task_finder2.c
index 0ba614741..917ec46f1 100644
--- a/runtime/linux/task_finder2.c
+++ b/runtime/linux/task_finder2.c
@@ -553,20 +553,18 @@ __stp_utrace_attach(struct task_struct *tsk,
if (rc == 0) {
debug_task_finder_attach();
- if (action != UTRACE_RESUME) {
- rc = utrace_control(tsk, engine, action);
- dbug_task(2, "utrace_control(%d) returned %d", action, rc);
- /* If utrace_control() returns
- * EINPROGRESS when we're trying to
- * stop/interrupt, that means the task
- * hasn't stopped quite yet, but will
- * soon. Ignore this error. */
- if (rc != 0 && rc != -EINPROGRESS) {
- _stp_error("utrace_control returned error %d on pid %d",
- rc, (int)tsk->pid);
- }
- rc = 0;
+ rc = utrace_control(tsk, engine, action);
+ dbug_task(2, "utrace_control(%d) returned %d", action, rc);
+ /* If utrace_control() returns
+ * EINPROGRESS when we're trying to
+ * stop/interrupt, that means the task
+ * hasn't stopped quite yet, but will
+ * soon. Ignore this error. */
+ if (rc != 0 && rc != -EINPROGRESS) {
+ _stp_error("utrace_control returned error %d on pid %d",
+ rc, (int)tsk->pid);
}
+ rc = 0;
}
else if (rc != -ESRCH && rc != -EALREADY)
_stp_error("utrace_set_events2 returned error %d on pid %d",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment