Last active
February 6, 2021 02:21
-
-
Save kerneltoast/10e6ffdecac6510818324c4b7835fd9d to your computer and use it in GitHub Desktop.
utrace refcount
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From b807d68401ccaf3c4ef17b89144ec2c58c9b081a Mon Sep 17 00:00:00 2001 | |
From: Sultan Alsawaf <sultan@openresty.com> | |
Date: Fri, 5 Feb 2021 13:09:16 -0800 | |
Subject: [PATCH 1/4] stp_utrace: remove outdated utrace_cleanup_lock comment | |
This lock doesn't exist anymore. | |
--- | |
runtime/stp_utrace.c | 2 -- | |
1 file changed, 2 deletions(-) | |
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c | |
index 9cc910222..1e79ec52a 100644 | |
--- a/runtime/stp_utrace.c | |
+++ b/runtime/stp_utrace.c | |
@@ -532,8 +532,6 @@ stp_task_notify_resume(struct task_struct *target, struct utrace *utrace) | |
/* | |
* Clean up everything associated with @task.utrace. | |
- * | |
- * This routine must be called under the utrace_cleanup_lock. | |
*/ | |
static void utrace_cleanup(struct utrace *utrace) | |
{ | |
-- | |
2.30.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 109c51173a67373c604ee85ea15fd61215ce41c5 Mon Sep 17 00:00:00 2001 | |
From: Sultan Alsawaf <sultan@openresty.com> | |
Date: Fri, 5 Feb 2021 13:22:16 -0800 | |
Subject: [PATCH 2/4] stp_utrace: remove useless RCU read locks | |
These RCU read locks don't actually protect anything. The task struct | |
pointer is not actually dereferenced in get_utrace_lock(), and the RCU | |
read lock in utrace_reset() serves no purpose at all. | |
--- | |
runtime/stp_utrace.c | 27 +++------------------------ | |
1 file changed, 3 insertions(+), 24 deletions(-) | |
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c | |
index 1e79ec52a..581964289 100644 | |
--- a/runtime/stp_utrace.c | |
+++ b/runtime/stp_utrace.c | |
@@ -1022,34 +1022,22 @@ static struct utrace *get_utrace_lock(struct task_struct *target, | |
struct utrace_bucket *bucket; | |
struct utrace *utrace; | |
- rcu_read_lock(); | |
- | |
/* | |
- * If this engine was already detached, bail out before we look at | |
- * the task_struct pointer at all. If it's detached after this | |
- * check, then RCU is still keeping this task_struct pointer valid. | |
- * | |
* The ops pointer is NULL when the engine is fully detached. | |
* It's &utrace_detached_ops when it's marked detached but still | |
* on the list. In the latter case, utrace_barrier() still works, | |
* since the target might be in the middle of an old callback. | |
*/ | |
- if (unlikely(!engine->ops)) { | |
- rcu_read_unlock(); | |
+ if (unlikely(!engine->ops)) | |
return ERR_PTR(-ESRCH); | |
- } | |
- if (unlikely(engine->ops == &utrace_detached_ops)) { | |
- rcu_read_unlock(); | |
+ if (unlikely(engine->ops == &utrace_detached_ops)) | |
return attached ? ERR_PTR(-ESRCH) : ERR_PTR(-ERESTARTSYS); | |
- } | |
bucket = get_utrace_bucket(target); | |
utrace = task_utrace_struct(bucket, target); | |
- if (unlikely(!utrace)) { | |
- rcu_read_unlock(); | |
+ if (unlikely(!utrace)) | |
return ERR_PTR(-ESRCH); | |
- } | |
spin_lock(&utrace->lock); | |
if (unlikely(utrace->reap) || unlikely(!engine->ops) || | |
@@ -1063,7 +1051,6 @@ static struct utrace *get_utrace_lock(struct task_struct *target, | |
if (!attached && engine->ops == &utrace_detached_ops) | |
utrace = ERR_PTR(-ERESTARTSYS); | |
} | |
- rcu_read_unlock(); | |
return utrace; | |
} | |
@@ -1346,15 +1333,7 @@ static bool utrace_reset(struct task_struct *task, struct utrace *utrace) | |
if (task_is_traced(task) && !(flags & ENGINE_STOP)) | |
utrace_wakeup(task, utrace); | |
- /* | |
- * In theory spin_lock() doesn't imply rcu_read_lock(). | |
- * Once we clear ->utrace_flags this task_struct can go away | |
- * because tracehook_prepare_release_task() path does not take | |
- * utrace->lock when ->utrace_flags == 0. | |
- */ | |
- rcu_read_lock(); | |
utrace->utrace_flags = flags; | |
- rcu_read_unlock(); | |
spin_unlock(&utrace->lock); | |
put_detached_list(&detached); | |
-- | |
2.30.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 420e39b7ad221382b4f1c674e926884dbc0bb21f Mon Sep 17 00:00:00 2001 | |
From: Sultan Alsawaf <sultan@openresty.com> | |
Date: Fri, 5 Feb 2021 14:07:17 -0800 | |
Subject: [PATCH 3/4] stp_utrace: always assume in_atomic() in | |
utrace_report_death() | |
As we've established in the past, in_atomic() only works when PREEMPT is | |
enabled. On non-PREEMPT kernels, in_atomic() will return false even when | |
used inside a spin-locked critical section. Therefore, in order to make | |
utrace_report_death() safe on all configurations, always use a task | |
worker to perform the report work. | |
--- | |
runtime/stp_utrace.c | 49 ++++++++++++++------------------------------ | |
1 file changed, 15 insertions(+), 34 deletions(-) | |
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c | |
index 581964289..869e41d78 100644 | |
--- a/runtime/stp_utrace.c | |
+++ b/runtime/stp_utrace.c | |
@@ -2709,7 +2709,6 @@ static void utrace_report_death(void *cb_data __attribute__ ((unused)), | |
{ | |
struct utrace_bucket *bucket; | |
struct utrace *utrace; | |
- INIT_REPORT(report); | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
@@ -2746,44 +2745,26 @@ static void utrace_report_death(void *cb_data __attribute__ ((unused)), | |
* flag and know that we are not yet fully quiescent for purposes | |
* of detach bookkeeping. | |
*/ | |
- if (in_atomic() || irqs_disabled()) { | |
- if (atomic_add_unless(&utrace->report_work_added, 1, 1)) { | |
- int rc; | |
+ if (atomic_add_unless(&utrace->report_work_added, 1, 1)) { | |
+ int rc; | |
#ifdef STP_TF_DEBUG | |
- printk(KERN_ERR "%s:%d - adding task_work\n", | |
- __FUNCTION__, __LINE__); | |
+ printk(KERN_ERR "%s:%d - adding task_work\n", | |
+ __FUNCTION__, __LINE__); | |
#endif | |
- rc = stp_task_work_add(task, | |
- &utrace->report_work); | |
- if (rc != 0) { | |
- atomic_set(&utrace->report_work_added, 0); | |
- /* stp_task_work_add() returns -ESRCH | |
- * if the task has already passed | |
- * exit_task_work(). Just ignore this | |
- * error. */ | |
- if (rc != -ESRCH) { | |
- printk(KERN_ERR | |
- "%s:%d - task_work_add() returned %d\n", | |
- __FUNCTION__, __LINE__, rc); | |
- } | |
+ rc = stp_task_work_add(task, &utrace->report_work); | |
+ if (rc != 0) { | |
+ atomic_set(&utrace->report_work_added, 0); | |
+ /* stp_task_work_add() returns -ESRCH | |
+ * if the task has already passed | |
+ * exit_task_work(). Just ignore this | |
+ * error. */ | |
+ if (rc != -ESRCH) { | |
+ printk(KERN_ERR | |
+ "%s:%d - task_work_add() returned %d\n", | |
+ __FUNCTION__, __LINE__, rc); | |
} | |
} | |
} | |
- else { | |
- spin_lock(&utrace->lock); | |
- BUG_ON(utrace->death); | |
- utrace->death = 1; | |
- utrace->resume = UTRACE_RESUME; | |
- splice_attaching(utrace); | |
- spin_unlock(&utrace->lock); | |
- | |
- REPORT_CALLBACKS(, task, utrace, &report, UTRACE_EVENT(DEATH), | |
- report_death, engine, -1/*group_dead*/, | |
- -1/*signal*/); | |
- | |
- utrace_maybe_reap(task, utrace, false); | |
- utrace_free(bucket, utrace); | |
- } | |
} | |
/* | |
-- | |
2.30.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 5d9d78b13c5eadabbeaff3d20778b49d032dacee Mon Sep 17 00:00:00 2001 | |
From: Sultan Alsawaf <sultan@openresty.com> | |
Date: Fri, 5 Feb 2021 17:40:22 -0800 | |
Subject: [PATCH 4/4] stp_utrace: fix widespread utrace struct use-after-free | |
-Cancel all the task workers that dereference the utrace struct | |
-Hold a task struct reference so utrace->task is always valid | |
-Use reference counts on the utrace struct itself | |
-Rename get_utrace_bucket() to find_utrace_bucket() since it doesn't | |
grab any references | |
-Rename task_utrace_struct() to get_utrace_struct() to indicate that it | |
grabs a reference on the returned utrace struct | |
--- | |
runtime/stp_utrace.c | 471 ++++++++++++++++++++++++------------------- | |
1 file changed, 269 insertions(+), 202 deletions(-) | |
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c | |
index 869e41d78..ff8c5549d 100644 | |
--- a/runtime/stp_utrace.c | |
+++ b/runtime/stp_utrace.c | |
@@ -121,7 +121,8 @@ struct utrace { | |
atomic_t report_work_added; /* called task_work_add() on | |
* 'report_work' */ | |
- unsigned long utrace_flags; | |
+ atomic_t refcount; | |
+ unsigned int utrace_flags; | |
struct hlist_node hlist; /* task_utrace_table linkage */ | |
struct task_struct *task; | |
@@ -446,7 +447,7 @@ error: | |
return rc; | |
} | |
-static void utrace_cleanup(struct utrace *utrace); | |
+static void utrace_cleanup(struct utrace_bucket *bucket, struct utrace *utrace); | |
static int utrace_exit(void) | |
{ | |
@@ -480,11 +481,8 @@ static int utrace_exit(void) | |
rcu_read_lock(); | |
stap_hlist_for_each_entry_rcu(utrace, node, &bucket->head, hlist) { | |
- stp_spin_lock_irqsave(&bucket->lock, flags); | |
- hlist_del_rcu(&utrace->hlist); | |
- stp_spin_unlock_irqrestore(&bucket->lock, flags); | |
- | |
- utrace_cleanup(utrace); | |
+ if (atomic_read(&utrace->refcount)) | |
+ utrace_cleanup(bucket, utrace); | |
} | |
rcu_read_unlock(); | |
} | |
@@ -513,8 +511,13 @@ static void | |
stp_task_notify_resume(struct task_struct *target, struct utrace *utrace) | |
{ | |
if (atomic_add_unless(&utrace->resume_work_added, 1, 1)) { | |
- int rc = stp_task_work_add(target, &utrace->resume_work); | |
+ int rc; | |
+ | |
+ /* Don't need to use utrace get/put because we have a ref */ | |
+ atomic_inc(&utrace->refcount); | |
+ rc = stp_task_work_add(target, &utrace->resume_work); | |
if (rc != 0) { | |
+ atomic_dec(&utrace->refcount); | |
atomic_set(&utrace->resume_work_added, 0); | |
/* stp_task_work_add() returns -ESRCH if the | |
@@ -533,13 +536,21 @@ stp_task_notify_resume(struct task_struct *target, struct utrace *utrace) | |
/* | |
* Clean up everything associated with @task.utrace. | |
*/ | |
-static void utrace_cleanup(struct utrace *utrace) | |
+static void utrace_cleanup(struct utrace_bucket *bucket, struct utrace *utrace) | |
{ | |
struct utrace_engine *engine, *next; | |
+ unsigned long flags; | |
+ | |
+ /* Remove this utrace from the mapping list of tasks to struct utrace */ | |
+ stp_spin_lock_irqsave(&bucket->lock, flags); | |
+ hlist_del_rcu(&utrace->hlist); | |
+ stp_spin_unlock_irqrestore(&bucket->lock, flags); | |
+ | |
+ /* Put the reference on the task struct */ | |
+ put_task_struct(utrace->task); | |
/* Free engines associated with the struct utrace, starting | |
* with the 'attached' list then doing the 'attaching' list. */ | |
- spin_lock(&utrace->lock); | |
list_for_each_entry_safe(engine, next, &utrace->attached, entry) { | |
#ifdef STP_TF_DEBUG | |
printk(KERN_ERR "%s:%d - removing engine\n", | |
@@ -553,7 +564,6 @@ static void utrace_cleanup(struct utrace *utrace) | |
list_del(&engine->entry); | |
_stp_kfree(engine); | |
} | |
- spin_unlock(&utrace->lock); | |
/* Note that we don't need to worry about | |
* utrace->resume_work_added and utrace->report_work_added, | |
@@ -573,28 +583,29 @@ static void utrace_syscall_exit_work(struct task_work *work); | |
static void utrace_exec_work(struct task_work *work); | |
static void utrace_clone_work(struct task_work *work); | |
-/* MACROS for utrace_cancel_all_task_work(): */ | |
-#ifdef STP_TF_DEBUG | |
-#define CANCEL_IF_WORK(added_field, task_work_func) \ | |
- if (atomic_add_unless(&added_field, \ | |
- -1, 0)) { \ | |
- if (stp_task_work_cancel(utrace->task, \ | |
- &task_work_func) == NULL) \ | |
- printk(KERN_ERR "%s:%d - task_work_cancel() failed for %s? task %p, %d, %s\n", \ | |
- __FUNCTION__, __LINE__, #task_work_func, \ | |
- utrace->task, utrace->task->tgid, \ | |
- (utrace->task->comm \ | |
- ? utrace->task->comm \ | |
- : "UNKNOWN")); \ | |
- } | |
-#else | |
-#define CANCEL_IF_WORK(added_field, task_work_func) \ | |
- if (atomic_add_unless(&added_field, \ | |
- -1, 0)) { \ | |
- stp_task_work_cancel(utrace->task, \ | |
- &task_work_func); \ | |
- } | |
-#endif | |
+static void utrace_cancel_workers(struct utrace_bucket *bucket, | |
+ struct utrace *utrace) | |
+{ | |
+ static const task_work_func_t task_workers[] = { | |
+ utrace_resume, | |
+ utrace_report_work, | |
+ utrace_exec_work, | |
+ utrace_syscall_entry_work, | |
+ utrace_syscall_exit_work, | |
+ utrace_clone_work | |
+ }; | |
+ int i; | |
+ | |
+ /* | |
+ * Cancel every task worker instance. stp_task_work_cancel() only | |
+ * cancels one worker at a time, so we need to run it multiple times to | |
+ * ensure all of the workers are really gone. We don't bother putting | |
+ * the references on the utrace struct because the structs will be freed | |
+ * by force later, after task workers can no longer run or be queued. | |
+ */ | |
+ for (i = 0; i < ARRAY_SIZE(task_workers); i++) | |
+ while (stp_task_work_cancel(utrace->task, task_workers[i])); | |
+} | |
static void utrace_cancel_all_task_work(void) | |
{ | |
@@ -603,7 +614,6 @@ static void utrace_cancel_all_task_work(void) | |
struct hlist_head *head; | |
struct hlist_node *utrace_node; | |
struct __stp_utrace_task_work *task_node; | |
- unsigned long flags; | |
/* Cancel any pending utrace task_work item(s). */ | |
for (i = 0; i < TASK_UTRACE_TABLE_SIZE; i++) { | |
@@ -611,18 +621,11 @@ static void utrace_cancel_all_task_work(void) | |
rcu_read_lock(); | |
stap_hlist_for_each_entry_rcu(utrace, utrace_node, &bucket->head, hlist) { | |
- CANCEL_IF_WORK(utrace->resume_work_added, utrace_resume); | |
- CANCEL_IF_WORK(utrace->report_work_added, utrace_report_work); | |
+ if (atomic_read(&utrace->refcount)) | |
+ utrace_cancel_workers(bucket, utrace); | |
} | |
rcu_read_unlock(); | |
} | |
- | |
- /* Cancel any pending task_work_list item(s). */ | |
- stp_spin_lock_irqsave(&__stp_utrace_task_work_list_lock, flags); | |
- list_for_each_entry(task_node, &__stp_utrace_task_work_list, list) { | |
- stp_task_work_cancel(task_node->task, task_node->work.func); | |
- } | |
- stp_spin_unlock_irqrestore(&__stp_utrace_task_work_list_lock, flags); | |
} | |
static void utrace_shutdown(void) | |
@@ -656,13 +659,13 @@ static void utrace_shutdown(void) | |
utrace_cancel_all_task_work(); | |
} | |
-static struct utrace_bucket *get_utrace_bucket(struct task_struct *task) | |
+static struct utrace_bucket *find_utrace_bucket(struct task_struct *task) | |
{ | |
return &task_utrace_table[hash_ptr(task, TASK_UTRACE_HASH_BITS)]; | |
} | |
-static struct utrace *task_utrace_struct(struct utrace_bucket *bucket, | |
- struct task_struct *task) | |
+static struct utrace *get_utrace_struct(struct utrace_bucket *bucket, | |
+ struct task_struct *task) | |
{ | |
struct utrace *utrace, *found = NULL; | |
struct hlist_node *node; | |
@@ -670,7 +673,8 @@ static struct utrace *task_utrace_struct(struct utrace_bucket *bucket, | |
rcu_read_lock(); | |
stap_hlist_for_each_entry_rcu(utrace, node, &bucket->head, hlist) { | |
if (utrace->task == task) { | |
- found = utrace; | |
+ if (atomic_add_unless(&utrace->refcount, 1, 0)) | |
+ found = utrace; | |
break; | |
} | |
} | |
@@ -697,6 +701,9 @@ static struct utrace *utrace_task_alloc(struct utrace_bucket *bucket, | |
if (unlikely(!utrace)) | |
return NULL; | |
+ /* Acquire a reference to the task struct so it remains valid */ | |
+ get_task_struct(task); | |
+ | |
spin_lock_init(&utrace->lock); | |
INIT_LIST_HEAD(&utrace->attached); | |
INIT_LIST_HEAD(&utrace->attaching); | |
@@ -706,6 +713,7 @@ static struct utrace *utrace_task_alloc(struct utrace_bucket *bucket, | |
stp_init_task_work(&utrace->report_work, &utrace_report_work); | |
atomic_set(&utrace->resume_work_added, 0); | |
atomic_set(&utrace->report_work_added, 0); | |
+ atomic_set(&utrace->refcount, 1); | |
stp_spin_lock_irqsave(&bucket->lock, flags); | |
hlist_add_head_rcu(&utrace->hlist, &bucket->head); | |
@@ -713,20 +721,6 @@ static struct utrace *utrace_task_alloc(struct utrace_bucket *bucket, | |
return utrace; | |
} | |
-/* macros for utrace_free(): */ | |
-#define FREE_IF_WORK(added_field, task_work_func) \ | |
- if (atomic_add_unless(&added_field, -1, 0)) { \ | |
- if ((stp_task_work_cancel(utrace->task, &task_work_func) \ | |
- == NULL) \ | |
- && (utrace->task->flags & ~PF_EXITING) \ | |
- && (utrace->task->exit_state == 0)) \ | |
- printk(KERN_ERR "%s:%d * task_work_cancel() failed for %s? task %p, %d, %s, 0x%lx 0x%x\n", \ | |
- __FUNCTION__, __LINE__, #task_work_func, \ | |
- utrace->task, utrace->task->tgid, \ | |
- (utrace->task->comm ? utrace->task->comm \ | |
- : "UNKNOWN"), utrace->task->state, utrace->task->exit_state); \ | |
- } | |
- | |
/* | |
* Correctly free a @utrace structure. | |
* | |
@@ -734,36 +728,13 @@ static struct utrace *utrace_task_alloc(struct utrace_bucket *bucket, | |
* free_task() when @task is being deallocated. But free_task() has no | |
* tracepoint we can easily hook. | |
*/ | |
-static void utrace_free(struct utrace_bucket *bucket, struct utrace *utrace) | |
+static void put_utrace_struct(struct utrace_bucket *bucket, | |
+ struct utrace *utrace) | |
{ | |
- unsigned long flags; | |
- | |
- if (unlikely(!utrace)) | |
+ if (!utrace || atomic_dec_return(&utrace->refcount)) | |
return; | |
- /* Remove this utrace from the mapping list of tasks to | |
- * struct utrace. */ | |
- stp_spin_lock_irqsave(&bucket->lock, flags); | |
- hlist_del_rcu(&utrace->hlist); | |
- stp_spin_unlock_irqrestore(&bucket->lock, flags); | |
- | |
- /* Free the utrace struct. */ | |
-#ifdef STP_TF_DEBUG | |
- spin_lock(&utrace->lock); | |
- if (unlikely(utrace->reporting) | |
- || unlikely(!list_empty(&utrace->attached)) | |
- || unlikely(!list_empty(&utrace->attaching))) | |
- printk(KERN_ERR "%s:%d - reporting? %p, attached empty %d, attaching empty %d\n", | |
- __FUNCTION__, __LINE__, utrace->reporting, | |
- list_empty(&utrace->attached), | |
- list_empty(&utrace->attaching)); | |
- spin_unlock(&utrace->lock); | |
-#endif | |
- | |
- FREE_IF_WORK(utrace->resume_work_added, utrace_resume); | |
- FREE_IF_WORK(utrace->report_work_added, utrace_report_work); | |
- | |
- kfree_rcu(utrace, rcu); | |
+ utrace_cleanup(bucket, utrace); | |
} | |
/* | |
@@ -839,7 +810,7 @@ static int utrace_add_engine(struct task_struct *target, | |
* utrace_flags is not zero. Since we did unlock+lock | |
* at least once after utrace_task_alloc() installed | |
* ->utrace, we have the necessary barrier which pairs | |
- * with rmb() in task_utrace_struct(). | |
+ * with rmb() in get_utrace_struct(). | |
*/ | |
ret = -ESRCH; | |
/* FIXME: Hmm, no reap in the brave new world... */ | |
@@ -912,9 +883,10 @@ static struct utrace_engine *utrace_attach_task( | |
struct task_struct *target, int flags, | |
const struct utrace_engine_ops *ops, void *data) | |
{ | |
- struct utrace_bucket *bucket = get_utrace_bucket(target); | |
- struct utrace *utrace = task_utrace_struct(bucket, target); | |
+ struct utrace_bucket *bucket = find_utrace_bucket(target); | |
+ struct utrace *utrace = get_utrace_struct(bucket, target); | |
struct utrace_engine *engine; | |
+ bool utrace_found = utrace; | |
int ret; | |
#ifdef STP_TF_DEBUG | |
@@ -923,6 +895,7 @@ static struct utrace_engine *utrace_attach_task( | |
#endif | |
if (!(flags & UTRACE_ATTACH_CREATE)) { | |
+ /* Don't need to put utrace struct if it's NULL */ | |
if (unlikely(!utrace)) | |
return ERR_PTR(-ENOENT); | |
spin_lock(&utrace->lock); | |
@@ -930,27 +903,35 @@ static struct utrace_engine *utrace_attach_task( | |
if (engine) | |
utrace_engine_get(engine); | |
spin_unlock(&utrace->lock); | |
+ put_utrace_struct(bucket, utrace); | |
return engine ?: ERR_PTR(-ENOENT); | |
} | |
- if (unlikely(!ops) || unlikely(ops == &utrace_detached_ops)) | |
+ if (unlikely(!ops) || unlikely(ops == &utrace_detached_ops)) { | |
+ put_utrace_struct(bucket, utrace); | |
return ERR_PTR(-EINVAL); | |
+ } | |
- if (unlikely(target->flags & PF_KTHREAD)) | |
+ if (unlikely(target->flags & PF_KTHREAD)) { | |
/* | |
* Silly kernel, utrace is for users! | |
*/ | |
+ put_utrace_struct(bucket, utrace); | |
return ERR_PTR(-EPERM); | |
+ } | |
if (!utrace) { | |
utrace = utrace_task_alloc(bucket, target); | |
+ /* Don't need to put utrace struct if it's NULL */ | |
if (unlikely(!utrace)) | |
return ERR_PTR(-ENOMEM); | |
} | |
engine = _stp_kmalloc(sizeof(*engine)); | |
- if (unlikely(!engine)) | |
+ if (unlikely(!engine)) { | |
+ put_utrace_struct(bucket, utrace); | |
return ERR_PTR(-ENOMEM); | |
+ } | |
/* | |
* Initialize the new engine structure. It starts out with one ref | |
@@ -969,6 +950,14 @@ static struct utrace_engine *utrace_attach_task( | |
engine = ERR_PTR(ret); | |
} | |
+ /* | |
+ * Don't put the utrace struct if it was just made and successfully | |
+ * attached to, otherwise it'll disappear. We only put the new utrace | |
+ * struct if the engine couldn't be attached. If the utrace struct was | |
+ * acquired via get_utrace_struct() then we must put our reference. | |
+ */ | |
+ if (ret || utrace_found) | |
+ put_utrace_struct(bucket, utrace); | |
return engine; | |
} | |
@@ -1014,13 +1003,11 @@ static const struct utrace_engine_ops utrace_detached_ops = { | |
* utrace_report_death | |
* utrace_release_task | |
*/ | |
-static struct utrace *get_utrace_lock(struct task_struct *target, | |
- struct utrace_engine *engine, | |
- bool attached) | |
+static int get_utrace_lock(struct utrace *utrace, struct utrace_engine *engine, | |
+ bool attached) | |
__acquires(utrace->lock) | |
{ | |
- struct utrace_bucket *bucket; | |
- struct utrace *utrace; | |
+ int ret = 0; | |
/* | |
* The ops pointer is NULL when the engine is fully detached. | |
@@ -1029,15 +1016,10 @@ static struct utrace *get_utrace_lock(struct task_struct *target, | |
* since the target might be in the middle of an old callback. | |
*/ | |
if (unlikely(!engine->ops)) | |
- return ERR_PTR(-ESRCH); | |
+ return -ESRCH; | |
if (unlikely(engine->ops == &utrace_detached_ops)) | |
- return attached ? ERR_PTR(-ESRCH) : ERR_PTR(-ERESTARTSYS); | |
- | |
- bucket = get_utrace_bucket(target); | |
- utrace = task_utrace_struct(bucket, target); | |
- if (unlikely(!utrace)) | |
- return ERR_PTR(-ESRCH); | |
+ return attached ? -ESRCH : -ERESTARTSYS; | |
spin_lock(&utrace->lock); | |
if (unlikely(utrace->reap) || unlikely(!engine->ops) || | |
@@ -1047,12 +1029,13 @@ static struct utrace *get_utrace_lock(struct task_struct *target, | |
* it had been reaped or detached already. | |
*/ | |
spin_unlock(&utrace->lock); | |
- utrace = ERR_PTR(-ESRCH); | |
if (!attached && engine->ops == &utrace_detached_ops) | |
- utrace = ERR_PTR(-ERESTARTSYS); | |
+ ret = -ERESTARTSYS; | |
+ else | |
+ ret = -ESRCH; | |
} | |
- return utrace; | |
+ return ret; | |
} | |
/* | |
@@ -1139,9 +1122,10 @@ static int utrace_set_events(struct task_struct *target, | |
struct utrace_engine *engine, | |
unsigned long events) | |
{ | |
+ struct utrace_bucket *bucket; | |
struct utrace *utrace; | |
unsigned long old_flags, old_utrace_flags; | |
- int ret = -EALREADY; | |
+ int ret; | |
/* | |
* We just ignore the internal bit, so callers can use | |
@@ -1149,9 +1133,14 @@ static int utrace_set_events(struct task_struct *target, | |
*/ | |
events &= ~ENGINE_STOP; | |
- utrace = get_utrace_lock(target, engine, true); | |
- if (unlikely(IS_ERR(utrace))) | |
- return PTR_ERR(utrace); | |
+ bucket = find_utrace_bucket(target); | |
+ utrace = get_utrace_struct(bucket, target); | |
+ if (!utrace) | |
+ return -ESRCH; | |
+ | |
+ ret = get_utrace_lock(utrace, engine, true); | |
+ if (ret) | |
+ goto put_utrace; | |
old_utrace_flags = utrace->utrace_flags; | |
old_flags = engine->flags & ~ENGINE_STOP; | |
@@ -1164,8 +1153,10 @@ static int utrace_set_events(struct task_struct *target, | |
(((events & ~old_flags) & _UTRACE_DEATH_EVENTS) || | |
(utrace->death && | |
((old_flags & ~events) & _UTRACE_DEATH_EVENTS)) || | |
- (utrace->reap && ((old_flags & ~events) & UTRACE_EVENT(REAP))))) | |
+ (utrace->reap && ((old_flags & ~events) & UTRACE_EVENT(REAP))))) { | |
+ ret = -EALREADY; | |
goto unlock; | |
+ } | |
/* | |
* When setting these flags, it's essential that we really | |
@@ -1186,6 +1177,7 @@ static int utrace_set_events(struct task_struct *target, | |
//read_lock(&tasklist_lock); | |
if (unlikely(target->exit_state)) { | |
//read_unlock(&tasklist_lock); | |
+ ret = -EALREADY; | |
goto unlock; | |
} | |
utrace->utrace_flags |= events; | |
@@ -1212,7 +1204,8 @@ static int utrace_set_events(struct task_struct *target, | |
} | |
unlock: | |
spin_unlock(&utrace->lock); | |
- | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
return ret; | |
} | |
@@ -1348,10 +1341,14 @@ static void utrace_finish_stop(void) | |
* sure we do nothing until the tracer drops utrace->lock. | |
*/ | |
if (unlikely(__fatal_signal_pending(current))) { | |
- struct utrace_bucket *bucket = get_utrace_bucket(current); | |
- struct utrace *utrace = task_utrace_struct(bucket, current); | |
- spin_lock(&utrace->lock); | |
- spin_unlock(&utrace->lock); | |
+ struct utrace_bucket *bucket = find_utrace_bucket(current); | |
+ struct utrace *utrace = get_utrace_struct(bucket, current); | |
+ | |
+ if (utrace) { | |
+ spin_lock(&utrace->lock); | |
+ spin_unlock(&utrace->lock); | |
+ put_utrace_struct(bucket, utrace); | |
+ } | |
} | |
} | |
@@ -1640,6 +1637,7 @@ static int utrace_control(struct task_struct *target, | |
struct utrace_engine *engine, | |
enum utrace_resume_action action) | |
{ | |
+ struct utrace_bucket *bucket; | |
struct utrace *utrace; | |
bool reset; | |
int ret; | |
@@ -1663,9 +1661,14 @@ static int utrace_control(struct task_struct *target, | |
return -EINVAL; | |
} | |
- utrace = get_utrace_lock(target, engine, true); | |
- if (unlikely(IS_ERR(utrace))) | |
- return PTR_ERR(utrace); | |
+ bucket = find_utrace_bucket(target); | |
+ utrace = get_utrace_struct(bucket, target); | |
+ if (!utrace) | |
+ return -ESRCH; | |
+ | |
+ ret = get_utrace_lock(utrace, engine, true); | |
+ if (ret) | |
+ goto put_utrace; | |
reset = task_is_traced(target); | |
ret = 0; | |
@@ -1680,7 +1683,7 @@ static int utrace_control(struct task_struct *target, | |
ret = utrace_control_dead(target, utrace, action); | |
if (ret) { | |
spin_unlock(&utrace->lock); | |
- return ret; | |
+ goto put_utrace; | |
} | |
reset = true; | |
} | |
@@ -1779,6 +1782,8 @@ static int utrace_control(struct task_struct *target, | |
else | |
spin_unlock(&utrace->lock); | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
return ret; | |
} | |
@@ -1806,8 +1811,9 @@ static int utrace_control(struct task_struct *target, | |
static int utrace_barrier(struct task_struct *target, | |
struct utrace_engine *engine) | |
{ | |
+ struct utrace_bucket *bucket; | |
struct utrace *utrace; | |
- int ret = -ERESTARTSYS; | |
+ int ret; | |
if (unlikely(target == current)) | |
return 0; | |
@@ -1815,10 +1821,15 @@ static int utrace_barrier(struct task_struct *target, | |
/* If we get here, we might call | |
* schedule_timeout_interruptible(), which sleeps. */ | |
might_sleep(); | |
+ | |
+ bucket = find_utrace_bucket(target); | |
+ utrace = get_utrace_struct(bucket, target); | |
+ if (!utrace) | |
+ return -ESRCH; | |
+ | |
do { | |
- utrace = get_utrace_lock(target, engine, false); | |
- if (unlikely(IS_ERR(utrace))) { | |
- ret = PTR_ERR(utrace); | |
+ ret = get_utrace_lock(utrace, engine, false); | |
+ if (ret) { | |
if (ret != -ERESTARTSYS) | |
break; | |
} else { | |
@@ -1836,6 +1847,8 @@ static int utrace_barrier(struct task_struct *target, | |
*/ | |
if (utrace->reporting != engine) | |
ret = 0; | |
+ else | |
+ ret = -ERESTARTSYS; | |
spin_unlock(&utrace->lock); | |
if (!ret) | |
break; | |
@@ -1843,6 +1856,7 @@ static int utrace_barrier(struct task_struct *target, | |
schedule_timeout_interruptible(1); | |
} while (!signal_pending(current)); | |
+ put_utrace_struct(bucket, utrace); | |
return ret; | |
} | |
@@ -2140,11 +2154,14 @@ static void utrace_report_exec(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
- if (!utrace || !(utrace->utrace_flags & UTRACE_EVENT(EXEC))) | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
return; | |
+ if (!(utrace->utrace_flags & UTRACE_EVENT(EXEC))) | |
+ goto put_utrace; | |
+ | |
#if 0 | |
if (!in_atomic() && !irqs_disabled()) | |
printk(KERN_ERR | |
@@ -2156,16 +2173,20 @@ static void utrace_report_exec(void *cb_data __attribute__ ((unused)), | |
work = __stp_utrace_alloc_task_work(utrace, (void *)NULL); | |
if (work == NULL) { | |
_stp_error("Unable to allocate space for task_work"); | |
- return; | |
+ goto put_utrace; | |
} | |
stp_init_task_work(work, &utrace_exec_work); | |
rc = stp_task_work_add(task, work); | |
+ /* Pass our utrace struct reference onto the worker */ | |
+ if (!rc) | |
+ return; | |
// stp_task_work_add() returns -ESRCH if the task has already | |
// passed exit_task_work(). Just ignore this error. | |
- if (rc != 0 && rc != -ESRCH) { | |
+ if (rc != -ESRCH) | |
printk(KERN_ERR "%s:%d - stp_task_work_add() returned %d\n", | |
__FUNCTION__, __LINE__, rc); | |
- } | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
#else | |
// This is the original version. | |
struct utrace_bucket *bucket; | |
@@ -2174,15 +2195,19 @@ static void utrace_report_exec(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
- if (utrace && utrace->utrace_flags & UTRACE_EVENT(EXEC)) { | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
+ | |
+ if (utrace->utrace_flags & UTRACE_EVENT(EXEC)) { | |
INIT_REPORT(report); | |
/* FIXME: Hmm, can we get regs another way? */ | |
REPORT(task, utrace, &report, UTRACE_EVENT(EXEC), | |
report_exec, NULL, NULL, NULL /* regs */); | |
} | |
+ put_utrace_struct(bucket, utrace); | |
#endif | |
} | |
@@ -2192,6 +2217,7 @@ static void utrace_exec_work(struct task_work *work) | |
container_of(work, struct __stp_utrace_task_work, work); | |
struct utrace *utrace = utrace_work->utrace; | |
struct task_struct *task = current; | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
INIT_REPORT(report); | |
@@ -2202,6 +2228,8 @@ static void utrace_exec_work(struct task_work *work) | |
report_exec, NULL, NULL, NULL /* regs */); | |
__stp_utrace_free_task_work(work); | |
+ put_utrace_struct(bucket, utrace); | |
+ | |
/* Remember that this task_work_func is finished. */ | |
stp_task_work_func_done(); | |
} | |
@@ -2270,14 +2298,16 @@ static void utrace_report_syscall_entry(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
- /* FIXME: Is this 100% correct? */ | |
- if (!utrace | |
- || !(utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_ENTRY)|ENGINE_STOP))) | |
+ if (!utrace) | |
return; | |
+ /* FIXME: Is this 100% correct? */ | |
+ if (!(utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_ENTRY)|ENGINE_STOP))) | |
+ goto put_utrace;; | |
+ | |
#if 0 | |
if (!in_atomic() && !irqs_disabled()) | |
printk(KERN_ERR | |
@@ -2289,17 +2319,21 @@ static void utrace_report_syscall_entry(void *cb_data __attribute__ ((unused)), | |
work = __stp_utrace_alloc_task_work(utrace, NULL); | |
if (work == NULL) { | |
_stp_error("Unable to allocate space for task_work"); | |
- return; | |
+ goto put_utrace; | |
} | |
__stp_utrace_save_regs(work, regs); | |
stp_init_task_work(work, &utrace_syscall_entry_work); | |
rc = stp_task_work_add(task, work); | |
+ /* Pass our utrace struct reference onto the worker */ | |
+ if (!rc) | |
+ return; | |
// stp_task_work_add() returns -ESRCH if the task has already | |
// passed exit_task_work(). Just ignore this error. | |
- if (rc != 0 && rc != -ESRCH) { | |
+ if (rc != -ESRCH) | |
printk(KERN_ERR "%s:%d - stp_task_work_add() returned %d\n", | |
__FUNCTION__, __LINE__, rc); | |
- } | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
#else | |
// This is the original version. | |
struct task_struct *task = current; | |
@@ -2309,12 +2343,13 @@ static void utrace_report_syscall_entry(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
/* FIXME: Is this 100% correct? */ | |
- if (utrace | |
- && utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_ENTRY)|ENGINE_STOP)) { | |
+ if (utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_ENTRY)|ENGINE_STOP)) { | |
INIT_REPORT(report); | |
@@ -2323,6 +2358,7 @@ static void utrace_report_syscall_entry(void *cb_data __attribute__ ((unused)), | |
REPORT(task, utrace, &report, UTRACE_EVENT(SYSCALL_ENTRY), | |
report_syscall_entry, regs); | |
} | |
+ put_utrace_struct(bucket, utrace); | |
#if 0 | |
INIT_REPORT(report); | |
@@ -2344,6 +2380,7 @@ static void utrace_syscall_entry_work(struct task_work *work) | |
container_of(work, struct __stp_utrace_task_work, work); | |
struct utrace *utrace = utrace_work->utrace; | |
struct task_struct *task = current; | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
struct pt_regs *regs = &utrace_work->regs; | |
INIT_REPORT(report); | |
@@ -2356,6 +2393,8 @@ static void utrace_syscall_entry_work(struct task_work *work) | |
report_syscall_entry, regs); | |
__stp_utrace_free_task_work(work); | |
+ put_utrace_struct(bucket, utrace); | |
+ | |
/* Remember that this task_work_func is finished. */ | |
stp_task_work_func_done(); | |
} | |
@@ -2377,13 +2416,14 @@ static void utrace_report_syscall_exit(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
/* FIXME: Is this 100% correct? */ | |
- if (!utrace | |
- || !(utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_EXIT)|ENGINE_STOP))) | |
- return; | |
+ if (!(utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_EXIT)|ENGINE_STOP))) | |
+ goto put_utrace; | |
#if 0 | |
if (!in_atomic() && !irqs_disabled()) | |
@@ -2396,17 +2436,21 @@ static void utrace_report_syscall_exit(void *cb_data __attribute__ ((unused)), | |
work = __stp_utrace_alloc_task_work(utrace, NULL); | |
if (work == NULL) { | |
_stp_error("Unable to allocate space for task_work"); | |
- return; | |
+ goto put_utrace; | |
} | |
__stp_utrace_save_regs(work, regs); | |
stp_init_task_work(work, &utrace_syscall_exit_work); | |
rc = stp_task_work_add(task, work); | |
+ /* Pass our utrace struct reference onto the worker */ | |
+ if (!rc) | |
+ return; | |
// stp_task_work_add() returns -ESRCH if the task has already | |
// passed exit_task_work(). Just ignore this error. | |
- if (rc != 0 && rc != -ESRCH) { | |
+ if (rc != -ESRCH) | |
printk(KERN_ERR "%s:%d - stp_task_work_add() returned %d\n", | |
__FUNCTION__, __LINE__, rc); | |
- } | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
#else | |
// This is the original version. | |
struct task_struct *task = current; | |
@@ -2416,12 +2460,13 @@ static void utrace_report_syscall_exit(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
/* FIXME: Is this 100% correct? */ | |
- if (utrace | |
- && utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_EXIT)|ENGINE_STOP)) { | |
+ if (utrace->utrace_flags & (UTRACE_EVENT(SYSCALL_EXIT)|ENGINE_STOP)) { | |
INIT_REPORT(report); | |
#ifdef STP_TF_DEBUG | |
@@ -2432,6 +2477,7 @@ static void utrace_report_syscall_exit(void *cb_data __attribute__ ((unused)), | |
REPORT(task, utrace, &report, UTRACE_EVENT(SYSCALL_EXIT), | |
report_syscall_exit, regs); | |
} | |
+ put_utrace_struct(bucket, utrace); | |
#endif | |
} | |
@@ -2441,6 +2487,7 @@ static void utrace_syscall_exit_work(struct task_work *work) | |
container_of(work, struct __stp_utrace_task_work, work); | |
struct utrace *utrace = utrace_work->utrace; | |
struct task_struct *task = current; | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
struct pt_regs *regs = &utrace_work->regs; | |
INIT_REPORT(report); | |
@@ -2462,6 +2509,8 @@ static void utrace_syscall_exit_work(struct task_work *work) | |
REPORT(task, utrace, &report, UTRACE_EVENT(SYSCALL_EXIT), | |
report_syscall_exit, regs); | |
+ put_utrace_struct(bucket, utrace); | |
+ | |
/* Remember that this task_work_func is finished. */ | |
stp_task_work_func_done(); | |
} | |
@@ -2489,17 +2538,18 @@ static void utrace_report_clone(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
#ifdef STP_TF_DEBUG | |
printk(KERN_ERR "%s:%d - parent %p, child %p, current %p\n", | |
__FUNCTION__, __LINE__, task, child, current); | |
#endif | |
- if (!utrace | |
- || !(utrace->utrace_flags & UTRACE_EVENT(CLONE))) | |
- return; | |
+ if (!(utrace->utrace_flags & UTRACE_EVENT(CLONE))) | |
+ goto put_utrace; | |
// TODO: Need to double-check the lifetime of struct child. | |
@@ -2507,16 +2557,20 @@ static void utrace_report_clone(void *cb_data __attribute__ ((unused)), | |
work = __stp_utrace_alloc_task_work(utrace, (void *)child); | |
if (work == NULL) { | |
_stp_error("Unable to allocate space for task_work"); | |
- return; | |
+ goto put_utrace; | |
} | |
stp_init_task_work(work, &utrace_clone_work); | |
rc = stp_task_work_add(task, work); | |
+ /* Pass our utrace struct reference onto the worker */ | |
+ if (!rc) | |
+ return; | |
// stp_task_work_add() returns -ESRCH if the task has already | |
// passed exit_task_work(). Just ignore this error. | |
- if (rc != 0 && rc != -ESRCH) { | |
+ if (rc != -ESRCH) | |
printk(KERN_ERR "%s:%d - stp_task_work_add() returned %d\n", | |
__FUNCTION__, __LINE__, rc); | |
- } | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
#else | |
// This is the original version. | |
struct utrace_bucket *bucket; | |
@@ -2525,15 +2579,17 @@ static void utrace_report_clone(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
#ifdef STP_TF_DEBUG | |
printk(KERN_ERR "%s:%d - parent %p, child %p, current %p\n", | |
__FUNCTION__, __LINE__, task, child, current); | |
#endif | |
- if (utrace && utrace->utrace_flags & UTRACE_EVENT(CLONE)) { | |
+ if (utrace->utrace_flags & UTRACE_EVENT(CLONE)) { | |
unsigned long clone_flags = 0; | |
INIT_REPORT(report); | |
@@ -2595,6 +2651,7 @@ static void utrace_report_clone(void *cb_data __attribute__ ((unused)), | |
} | |
#endif | |
} | |
+ put_utrace_struct(bucket, utrace); | |
#endif | |
} | |
@@ -2604,6 +2661,7 @@ static void utrace_clone_work(struct task_work *work) | |
container_of(work, struct __stp_utrace_task_work, work); | |
struct utrace *utrace = utrace_work->utrace; | |
struct task_struct *task = current; | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
struct task_struct *child = (struct task_struct *)utrace_work->data; | |
unsigned long clone_flags = 0; | |
@@ -2670,6 +2728,8 @@ static void utrace_clone_work(struct task_work *work) | |
} | |
#endif | |
+ put_utrace_struct(bucket, utrace); | |
+ | |
/* Remember that this task_work_func is finished. */ | |
stp_task_work_func_done(); | |
} | |
@@ -2686,8 +2746,8 @@ static void utrace_clone_work(struct task_work *work) | |
*/ | |
static void utrace_finish_vfork(struct task_struct *task) | |
{ | |
- struct utrace_bucket *bucket = get_utrace_bucket(task); | |
- struct utrace *utrace = task_utrace_struct(bucket, task); | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
+ struct utrace *utrace = get_utrace_struct(bucket, task); | |
if (utrace->vfork_stop) { | |
spin_lock(&utrace->lock); | |
@@ -2713,14 +2773,16 @@ static void utrace_report_death(void *cb_data __attribute__ ((unused)), | |
if (atomic_read(&utrace_state) != __UTRACE_REGISTERED) | |
return; | |
- bucket = get_utrace_bucket(task); | |
- utrace = task_utrace_struct(bucket, task); | |
+ bucket = find_utrace_bucket(task); | |
+ utrace = get_utrace_struct(bucket, task); | |
+ if (!utrace) | |
+ return; | |
#ifdef STP_TF_DEBUG | |
printk(KERN_ERR "%s:%d - task %p, utrace %p, flags %lx\n", __FUNCTION__, __LINE__, task, utrace, utrace ? utrace->utrace_flags : 0); | |
#endif | |
- if (!utrace || !(utrace->utrace_flags & UTRACE_EVENT(DEATH))) | |
- return; | |
+ if (!(utrace->utrace_flags & UTRACE_EVENT(DEATH))) | |
+ goto put_utrace; | |
/* This code is called from the 'sched_process_exit' | |
* tracepoint, which really corresponds more to UTRACE_EXIT | |
@@ -2752,19 +2814,22 @@ static void utrace_report_death(void *cb_data __attribute__ ((unused)), | |
__FUNCTION__, __LINE__); | |
#endif | |
rc = stp_task_work_add(task, &utrace->report_work); | |
- if (rc != 0) { | |
- atomic_set(&utrace->report_work_added, 0); | |
- /* stp_task_work_add() returns -ESRCH | |
- * if the task has already passed | |
- * exit_task_work(). Just ignore this | |
- * error. */ | |
- if (rc != -ESRCH) { | |
- printk(KERN_ERR | |
- "%s:%d - task_work_add() returned %d\n", | |
- __FUNCTION__, __LINE__, rc); | |
- } | |
+ /* Pass our utrace struct reference onto the worker */ | |
+ if (!rc) | |
+ return; | |
+ atomic_set(&utrace->report_work_added, 0); | |
+ /* stp_task_work_add() returns -ESRCH | |
+ * if the task has already passed | |
+ * exit_task_work(). Just ignore this | |
+ * error. */ | |
+ if (rc != -ESRCH) { | |
+ printk(KERN_ERR | |
+ "%s:%d - task_work_add() returned %d\n", | |
+ __FUNCTION__, __LINE__, rc); | |
} | |
} | |
+put_utrace: | |
+ put_utrace_struct(bucket, utrace); | |
} | |
/* | |
@@ -2803,13 +2868,14 @@ static void finish_resume_report(struct task_struct *task, | |
static void utrace_resume(struct task_work *work) | |
{ | |
/* | |
- * We could also do 'task_utrace_struct()' here to find the | |
+ * We could also do 'get_utrace_struct()' here to find the | |
* task's 'struct utrace', but 'container_of()' should be | |
- * instantaneous (where 'task_utrace_struct()' has to do a | |
+ * instantaneous (where 'get_utrace_struct()' has to do a | |
* hash lookup). | |
*/ | |
struct utrace *utrace = container_of(work, struct utrace, resume_work); | |
struct task_struct *task = current; | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
INIT_REPORT(report); | |
struct utrace_engine *engine; | |
@@ -2817,11 +2883,8 @@ static void utrace_resume(struct task_work *work) | |
atomic_set(&utrace->resume_work_added, 0); | |
/* Make sure the task isn't exiting. */ | |
- if (task->flags & PF_EXITING) { | |
- /* Remember that this task_work_func is finished. */ | |
- stp_task_work_func_done(); | |
- return; | |
- } | |
+ if (task->flags & PF_EXITING) | |
+ goto exit; | |
/* | |
* Some machines get here with interrupts disabled. The same arch | |
@@ -2844,9 +2907,7 @@ static void utrace_resume(struct task_work *work) | |
* purposes as well as calling us.) | |
*/ | |
- /* Remember that this task_work_func is finished. */ | |
- stp_task_work_func_done(); | |
- return; | |
+ goto exit; | |
case UTRACE_INTERRUPT: | |
/* | |
* Note that UTRACE_INTERRUPT reporting was handled by | |
@@ -2883,6 +2944,9 @@ static void utrace_resume(struct task_work *work) | |
*/ | |
finish_resume_report(task, utrace, &report); | |
+exit: | |
+ put_utrace_struct(bucket, utrace); | |
+ | |
/* Remember that this task_work_func is finished. */ | |
stp_task_work_func_done(); | |
} | |
@@ -2891,14 +2955,14 @@ static void utrace_resume(struct task_work *work) | |
static void utrace_report_work(struct task_work *work) | |
{ | |
/* | |
- * We could also do 'task_utrace_struct()' here to find the | |
+ * We could also do 'get_utrace_struct()' here to find the | |
* task's 'struct utrace', but 'container_of()' should be | |
- * instantaneous (where 'task_utrace_struct()' has to do a | |
+ * instantaneous (where 'get_utrace_struct()' has to do a | |
* hash lookup). | |
*/ | |
struct utrace *utrace = container_of(work, struct utrace, report_work); | |
struct task_struct *task = current; | |
- struct utrace_bucket *bucket = get_utrace_bucket(task); | |
+ struct utrace_bucket *bucket = find_utrace_bucket(task); | |
INIT_REPORT(report); | |
struct utrace_engine *engine; | |
unsigned long clone_flags; | |
@@ -2922,7 +2986,10 @@ static void utrace_report_work(struct task_work *work) | |
-1/*signal*/); | |
utrace_maybe_reap(task, utrace, false); | |
- utrace_free(bucket, utrace); | |
+ | |
+ /* Put two references on the utrace struct to free it */ | |
+ put_utrace_struct(bucket, utrace); | |
+ put_utrace_struct(bucket, utrace); | |
/* Remember that this task_work_func is finished. */ | |
stp_task_work_func_done(); | |
-- | |
2.30.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- systemtap-before.sum 2021-02-05 16:41:57.440992820 -0800 | |
+++ systemtap-after.sum 2021-02-05 18:15:41.238437212 -0800 | |
@@ -1,4 +1,4 @@ | |
-Test Run By root on Fri Feb 5 16:00:09 2021 | |
+Test Run By root on Fri Feb 5 17:35:04 2021 | |
Native configuration is x86_64-unknown-linux-gnu | |
=== systemtap tests === | |
@@ -45,7 +45,10 @@ | |
PASS: abort: TEST 5: abort() in the middle of a probe handler body (--compatible 3.3): stdout: string is "" | |
PASS: abort: TEST 5: abort() in the middle of a probe handler body (--compatible 3.3): exit code: string should NOT be "0" | |
PASS: abort: TEST 5: abort() in the middle of a probe handler body (--compatible 3.3): stderr: matches regex "^semantic error: unresolved function.*\(similar: [^\n]*?\): identifier 'abort' at [^\n]*?\.stp:3:5\n" | |
-PASS: abort: TEST 6: abort() in timer.profile (using globals): stdout: string is "fire 3!\nfire 2!\nfire 1!\n" | |
+FAIL: abort: TEST 6: abort() in timer.profile (using globals): stdout: string should be "fire 3!\nfire 2!\nfire 1!\n", but got "fire 1! | |
+fire 3! | |
+fire 2! | |
+" | |
PASS: abort: TEST 6: abort() in timer.profile (using globals): exit code: string is "0" | |
PASS: abort: TEST 7: abort() in timer.profile (more concurrency and no globals): stdout: string is "" | |
PASS: abort: TEST 7: abort() in timer.profile (more concurrency and no globals): stderr: string is "" | |
@@ -63,7 +66,7 @@ | |
FAIL: additional_scripts (-E BAD_SCRIPT listing probes) | |
PASS: additional_scripts (-e and -E ) | |
PASS: additional_scripts (file and -E ) | |
-FAIL: additional_scripts (multiple -E) | |
+PASS: additional_scripts (multiple -E ) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/addr_op.exp ... | |
PASS: addr_op: TEST 1: 2 excessive parens after unary '&' - with components (kernel): stdout: string is "1\n" | |
PASS: addr_op: TEST 1: 2 excessive parens after unary '&' - with components (kernel): exit code: string is "0" | |
@@ -206,7 +209,7 @@ | |
FAIL: at_var_cu | |
Running /home/sultan/systemtap/testsuite/systemtap.base/at_var.exp ... | |
PASS: at_var | |
-FAIL: at_var (non-optimized) | |
+PASS: at_var (non-optimized) | |
FAIL: at_var | |
PASS: at_var (non-optimized) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/at_var_func.exp ... | |
@@ -244,7 +247,7 @@ | |
PASS: auto_path2 | |
PASS: auto_path3 | |
Running /home/sultan/systemtap/testsuite/systemtap.base/backtrace.exp ... | |
-PASS: backtrace (3 37) | |
+PASS: backtrace (3 41) | |
PASS: backtrace-unwindsyms (3 35) | |
PASS: self-unwind-ensure-exact (0) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/bad-code.exp ... | |
@@ -301,7 +304,7 @@ | |
Running /home/sultan/systemtap/testsuite/systemtap.base/bz1074541.exp ... | |
PASS: ./bz1074541 | |
Running /home/sultan/systemtap/testsuite/systemtap.base/bz1126645.exp ... | |
-FAIL: bz1126645 -p5 (547) | |
+FAIL: bz1126645 -p5 (44) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/bz1214176.exp ... | |
PASS: stap -p4 -e { probe nfs.proc.read_done { println(server_ip) } } | |
PASS: stap -p4 -e { probe nfs.proc.read_setup { println(count) } } | |
@@ -399,7 +402,7 @@ | |
PASS: cast-user compile | |
FAIL: cast-user | |
Running /home/sultan/systemtap/testsuite/systemtap.base/cmdline.exp ... | |
-FAIL: cmdline | |
+PASS: cmdline | |
Running /home/sultan/systemtap/testsuite/systemtap.base/cmd_parse.exp ... | |
PASS: cmd_parse1 | |
PASS: cmd_parse2 | |
@@ -634,7 +637,7 @@ | |
FAIL: enum compiling enum.c | |
Running /home/sultan/systemtap/testsuite/systemtap.base/environment_sanity.exp ... | |
Host: Linux centos7-bb 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux | |
-Snapshot: version 4.5/0.177, commit release-4.4-89-g1ef2edcd3aa1 | |
+Snapshot: version 4.5/0.177, commit release-4.4-90-g8d16bd1cc2a8 | |
GCC: 4.8.5 [gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)] | |
Distro: CentOS Linux release 7.8.2003 (Core) | |
SElinux: Enforcing | |
@@ -2786,10 +2789,10 @@ | |
Running /home/sultan/systemtap/testsuite/systemtap.base/optim.exp ... | |
PASS: optim | |
Running /home/sultan/systemtap/testsuite/systemtap.base/optim_stats.exp ... | |
-PASS: TEST1 (5, 14) | |
-PASS: TEST2 (20, 86) | |
-PASS: TEST3 (5, 7) | |
-PASS: TEST4 (20, 66) | |
+PASS: TEST1 (5, 11) | |
+PASS: TEST2 (20, 85) | |
+PASS: TEST3 (5, 6) | |
+PASS: TEST4 (20, 67) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/optim_voidstmt.exp ... | |
PASS: optim_voidstmt startup | |
PASS: optim_voidstmt load generation | |
@@ -2823,7 +2826,7 @@ | |
FAIL: perf process (0 - 0) | |
PASS: perf counter | |
FAIL: perf global (0 - 0) | |
-UNRESOLVED: counter order 800000 7000000 | |
+UNRESOLVED: counter order 8000000 800000 | |
Running /home/sultan/systemtap/testsuite/systemtap.base/plt.exp ... | |
PASS: plt | |
PASS: plt library | |
@@ -2914,7 +2917,6 @@ | |
PASS: probefunc:kernel.function("scheduler_tick") startup | |
PASS: probefunc:kernel.function("scheduler_tick") load generation | |
PASS: probefunc:kernel.function("scheduler_tick") shutdown and output | |
-FAIL: probefunc:kernel.function("scheduler_tick") unexpected output (after passing output) | |
PASS: probefunc:kernel.function("context_switch").inline startup | |
PASS: probefunc:kernel.function("context_switch").inline load generation | |
PASS: probefunc:kernel.function("context_switch").inline shutdown and output | |
@@ -2952,18 +2954,14 @@ | |
PASS: process_resume-getpid: process resumed properly | |
PASS: process_resume-end startup | |
PASS: process_resume-end load generation | |
-FAIL: process_resume-end unexpected output | |
+PASS: process_resume-end shutdown and output | |
PASS: process_resume-end: process resumed properly | |
Running /home/sultan/systemtap/testsuite/systemtap.base/proc_exec.exp ... | |
-PASS: PROC_EXEC_01 startup | |
-PASS: PROC_EXEC_01 load generation | |
-PASS: PROC_EXEC_01 shutdown and output | |
+FAIL: PROC_EXEC_01 startup (timeout) | |
PASS: PROC_EXEC_02 startup | |
PASS: PROC_EXEC_02 load generation | |
-PASS: PROC_EXEC_02 shutdown and output | |
-PASS: PROC_EXEC_03 startup | |
-PASS: PROC_EXEC_03 load generation | |
-PASS: PROC_EXEC_03 shutdown and output | |
+FAIL: PROC_EXEC_02 unexpected output | |
+FAIL: PROC_EXEC_03 startup (timeout) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/procfs_bpf.exp ... | |
FAIL: PROCFS_BPF startup (eof) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/procfs.exp ... | |
@@ -3315,7 +3313,7 @@ | |
PASS: sdt_buildid compiling | |
PASS: sdt_buildid compiling -shared | |
UNTESTED: sdt_buildid debuginfod | |
-PASS: sdt_buildid non-buildid both | |
+FAIL: sdt_buildid non-buildid both | |
PASS: sdt_buildid non-buildid exe | |
PASS: sdt_buildid non-buildid solib | |
Running /home/sultan/systemtap/testsuite/systemtap.base/sdt_casm.exp ... | |
@@ -3795,7 +3793,7 @@ | |
PASS: tracepoints - kernel.trace("bla:") | |
PASS: tracepoints - kernel.trace("sched:") | |
PASS: systemtap.base/tracepoints.stp -w | |
-FAIL: systemtap.base/tracepoints2.stp | |
+PASS: systemtap.base/tracepoints2.stp | |
Running /home/sultan/systemtap/testsuite/systemtap.base/tracepoints_list.exp ... | |
UNTESTED: tracepoints_list (no perf) | |
Running /home/sultan/systemtap/testsuite/systemtap.base/tracescripts.exp ... | |
@@ -3880,7 +3878,7 @@ | |
Running /home/sultan/systemtap/testsuite/systemtap.base/utrace_p5.exp ... | |
PASS: UTRACE_P5_01 startup | |
PASS: UTRACE_P5_01 load generation | |
-FAIL: UTRACE_P5_01 unexpected output | |
+PASS: UTRACE_P5_01 shutdown and output | |
PASS: UTRACE_P5_01_cmd startup | |
PASS: UTRACE_P5_01_cmd load generation | |
PASS: UTRACE_P5_01_cmd shutdown and output | |
@@ -3890,21 +3888,19 @@ | |
PASS: UTRACE_P5_02_cmd startup | |
PASS: UTRACE_P5_02_cmd load generation | |
PASS: UTRACE_P5_02_cmd shutdown and output | |
-PASS: UTRACE_P5_03 startup | |
-PASS: UTRACE_P5_03 load generation | |
-FAIL: UTRACE_P5_03 unexpected output | |
+FAIL: UTRACE_P5_03 startup (timeout) | |
PASS: UTRACE_P5_04 startup | |
PASS: UTRACE_P5_04 load generation | |
-FAIL: UTRACE_P5_04 unexpected output | |
+PASS: UTRACE_P5_04 shutdown and output | |
PASS: UTRACE_P5_05 startup | |
PASS: UTRACE_P5_05 load generation | |
-PASS: UTRACE_P5_05 shutdown and output | |
+FAIL: UTRACE_P5_05 unexpected output | |
PASS: UTRACE_P5_05_cmd startup | |
PASS: UTRACE_P5_05_cmd load generation | |
PASS: UTRACE_P5_05_cmd shutdown and output | |
PASS: UTRACE_P5_06 startup | |
PASS: UTRACE_P5_06 load generation | |
-FAIL: UTRACE_P5_06 unexpected output | |
+PASS: UTRACE_P5_06 shutdown and output | |
PASS: UTRACE_P5_06_cmd startup | |
PASS: UTRACE_P5_06_cmd load generation | |
PASS: UTRACE_P5_06_cmd shutdown and output | |
@@ -4144,9 +4140,7 @@ | |
PASS: while.stp | |
Running /home/sultan/systemtap/testsuite/systemtap.clone/dtrace_clone.exp ... | |
PASS: dtrace_clone1 - build success | |
-PASS: dtrace_clone2 startup | |
-PASS: dtrace_clone2 load generation | |
-PASS: dtrace_clone2 shutdown and output | |
+FAIL: dtrace_clone2 startup (timeout) | |
PASS: dtrace_clone3 - build success | |
PASS: dtrace_clone4 startup | |
PASS: dtrace_clone4 load generation | |
@@ -4157,14 +4151,10 @@ | |
PASS: dtrace_fork_exec2 load generation | |
PASS: dtrace_fork_exec2 shutdown and output | |
PASS: dtrace_fork_exec3 - build success | |
-PASS: dtrace_fork_exec4 startup | |
-PASS: dtrace_fork_exec4 load generation | |
-PASS: dtrace_fork_exec4 shutdown and output | |
+FAIL: dtrace_fork_exec4 startup (timeout) | |
Running /home/sultan/systemtap/testsuite/systemtap.clone/dtrace_vfork_exec.exp ... | |
PASS: dtrace_vfork_exec1 - build success | |
-PASS: dtrace_vfork_exec2 startup | |
-PASS: dtrace_vfork_exec2 load generation | |
-PASS: dtrace_vfork_exec2 shutdown and output | |
+FAIL: dtrace_vfork_exec2 startup (timeout) | |
PASS: dtrace_vfork_exec3 - build success | |
PASS: dtrace_vfork_exec4 startup | |
PASS: dtrace_vfork_exec4 load generation | |
@@ -4176,10 +4166,10 @@ | |
PASS: main_quiesce shutdown and output | |
Running /home/sultan/systemtap/testsuite/systemtap.clone/probe_by_pid.exp ... | |
PASS: probe_by_pid(utrace) - build success | |
-PASS: probe_by_pid(utrace) startup | |
-PASS: probe_by_pid(utrace) load generation | |
-PASS: probe_by_pid(utrace) shutdown and output | |
-FAIL: probe_by_pid(function) startup (eof) | |
+FAIL: probe_by_pid(utrace) startup (eof) | |
+PASS: probe_by_pid(function) startup | |
+PASS: probe_by_pid(function) load generation | |
+FAIL: probe_by_pid(function) unexpected output | |
Running /home/sultan/systemtap/testsuite/systemtap.context/context.exp ... | |
PASS: backtrace of begin probe | |
FAIL: backtrace of yyy_func2 (0) | |
@@ -4217,9 +4207,7 @@ | |
PASS: symline () | |
PASS: symfileline in pp () | |
Running /home/sultan/systemtap/testsuite/systemtap.context/context_ns.exp ... | |
-PASS: pid_ns startup | |
-PASS: pid_ns load generation | |
-PASS: pid_ns shutdown and output | |
+FAIL: pid_ns startup (eof) | |
Running /home/sultan/systemtap/testsuite/systemtap.context/fib.exp ... | |
FAIL: fib (2 0) | |
FAIL: fib (10 0) | |
@@ -4353,7 +4341,7 @@ | |
PASS: systemtap.examples/general/tcl-trace build | |
FAIL: systemtap.examples/general/tcl-trace run | |
PASS: systemtap.examples/general/varwatch build | |
-FAIL: systemtap.examples/general/varwatch run | |
+PASS: systemtap.examples/general/varwatch run | |
PASS: systemtap.examples/general/watchdog support | |
PASS: systemtap.examples/general/watchdog build | |
PASS: systemtap.examples/general/watchdog run | |
@@ -4865,15 +4853,15 @@ | |
PASS: kprobes_onthefly - otf_start_disabled_iter_1 (valid output) | |
PASS: kprobes_onthefly - otf_start_enabled_iter_1 (valid output) | |
PASS: kprobes_onthefly - otf_start_disabled_iter_2 (valid output) | |
-FAIL: kprobes_onthefly - otf_start_enabled_iter_2 (invalid output) | |
-FAIL: kprobes_onthefly - otf_start_disabled_iter_3 (invalid output) | |
+PASS: kprobes_onthefly - otf_start_enabled_iter_2 (valid output) | |
+PASS: kprobes_onthefly - otf_start_disabled_iter_3 (valid output) | |
PASS: kprobes_onthefly - otf_start_enabled_iter_3 (valid output) | |
FAIL: kprobes_onthefly - otf_start_disabled_iter_4 (invalid output) | |
FAIL: kprobes_onthefly - otf_start_enabled_iter_4 (invalid output) | |
-FAIL: kprobes_onthefly - otf_start_disabled_iter_5 (invalid output) | |
+PASS: kprobes_onthefly - otf_start_disabled_iter_5 (valid output) | |
PASS: kprobes_onthefly - otf_start_enabled_iter_5 (valid output) | |
-FAIL: kprobes_onthefly - otf_timer_100ms (invalid output) | |
-PASS: kprobes_onthefly - otf_timer_50ms (valid output) | |
+PASS: kprobes_onthefly - otf_timer_100ms (valid output) | |
+FAIL: kprobes_onthefly - otf_timer_50ms (invalid output) | |
FAIL: kprobes_onthefly - otf_timer_10ms (invalid output) | |
PASS: kprobes_onthefly - otf_stress_5ms_iter_50 (survived) | |
PASS: kprobes_onthefly - otf_stress_1ms_iter_50 (survived) | |
@@ -4907,18 +4895,18 @@ | |
Running /home/sultan/systemtap/testsuite/systemtap.onthefly/uprobes_onthefly.exp ... | |
PASS: uprobes_onthefly (compilation) | |
FAIL: uprobes_onthefly - otf_finish_at_start_disabled (invalid output) | |
-FAIL: uprobes_onthefly - otf_finish_at_start_enabled (stap) | |
+PASS: uprobes_onthefly - otf_finish_at_start_enabled (valid output) | |
FAIL: uprobes_onthefly - otf_start_disabled_iter_1 (invalid output) | |
FAIL: uprobes_onthefly - otf_start_enabled_iter_1 (invalid output) | |
-FAIL: uprobes_onthefly - otf_start_disabled_iter_2 (invalid output) | |
-FAIL: uprobes_onthefly - otf_start_enabled_iter_2 (invalid output) | |
+FAIL: uprobes_onthefly - otf_start_disabled_iter_2 (stap) | |
+FAIL: uprobes_onthefly - otf_start_enabled_iter_2 (stap) | |
FAIL: uprobes_onthefly - otf_start_disabled_iter_3 (invalid output) | |
FAIL: uprobes_onthefly - otf_start_enabled_iter_3 (invalid output) | |
FAIL: uprobes_onthefly - otf_start_disabled_iter_4 (invalid output) | |
FAIL: uprobes_onthefly - otf_start_enabled_iter_4 (stap) | |
FAIL: uprobes_onthefly - otf_start_disabled_iter_5 (invalid output) | |
-FAIL: uprobes_onthefly - otf_start_enabled_iter_5 (stap) | |
-FAIL: uprobes_onthefly - otf_timer_100ms (invalid output) | |
+FAIL: uprobes_onthefly - otf_start_enabled_iter_5 (invalid output) | |
+FAIL: uprobes_onthefly - otf_timer_100ms (stap) | |
FAIL: uprobes_onthefly - otf_timer_50ms (invalid output) | |
PASS: uprobes_onthefly - otf_stress_10ms_iter_50 (survived) | |
PASS: uprobes_onthefly - otf_stress_5ms_iter_50 (survived) | |
@@ -6976,7 +6964,7 @@ | |
PASS: print_user_buffer compile | |
PASS: print_user_buffer startup | |
PASS: print_user_buffer load generation | |
-FAIL: print_user_buffer unexpected output | |
+PASS: print_user_buffer shutdown and output | |
Running /home/sultan/systemtap/testsuite/systemtap.printf/ptr-1.2.exp ... | |
PASS: systemtap.printf/ptr-1.2.stp --compatible=1.2 | |
PASS: systemtap.printf/ptr-1.2.stp --compatible=1.2 -DSTP_LEGACY_PRINT | |
@@ -7083,7 +7071,7 @@ | |
PASS: 32-bit access nd_syscall | |
PASS: 32-bit acct nd_syscall | |
PASS: 32-bit adjtimex nd_syscall | |
-FAIL: 32-bit aio nd_syscall | |
+PASS: 32-bit aio nd_syscall | |
FAIL: 32-bit alarm nd_syscall | |
PASS: 32-bit arch_prctl nd_syscall | |
PASS: 32-bit bind nd_syscall | |
@@ -7092,12 +7080,12 @@ | |
PASS: 32-bit capability nd_syscall | |
PASS: 32-bit chmod nd_syscall | |
PASS: 32-bit chroot nd_syscall | |
-FAIL: 32-bit clock nd_syscall | |
-PASS: 32-bit clone nd_syscall | |
+PASS: 32-bit clock nd_syscall | |
+FAIL: 32-bit clone nd_syscall | |
PASS: 32-bit connect nd_syscall | |
FAIL: 32-bit copy_file_range nd_syscall | |
PASS: 32-bit dcookie nd_syscall | |
-FAIL: 32-bit dir nd_syscall | |
+PASS: 32-bit dir nd_syscall | |
PASS: 32-bit domainname nd_syscall | |
PASS: 32-bit dup nd_syscall | |
PASS: 32-bit eventfd nd_syscall | |
@@ -7105,7 +7093,7 @@ | |
UNSUPPORTED: 32-bit execveat nd_syscall not supported on this arch | |
PASS: 32-bit exit nd_syscall | |
PASS: 32-bit exit_group nd_syscall | |
-FAIL: 32-bit fadvise64 nd_syscall | |
+PASS: 32-bit fadvise64 nd_syscall | |
PASS: 32-bit fallocate nd_syscall | |
PASS: 32-bit fanotify nd_syscall | |
PASS: 32-bit flock nd_syscall | |
@@ -7157,8 +7145,8 @@ | |
UNSUPPORTED: 32-bit nice nd_syscall not supported on this arch | |
PASS: 32-bit numa nd_syscall | |
PASS: 32-bit openclose nd_syscall | |
-PASS: 32-bit perf_event nd_syscall | |
-PASS: 32-bit personality nd_syscall | |
+FAIL: 32-bit perf_event nd_syscall | |
+FAIL: 32-bit personality nd_syscall | |
PASS: 32-bit pgid nd_syscall | |
PASS: 32-bit pipe nd_syscall | |
PASS: 32-bit pivot_root nd_syscall | |
@@ -7168,7 +7156,7 @@ | |
PASS: 32-bit pread nd_syscall | |
PASS: 32-bit preadv nd_syscall | |
PASS: 32-bit prlimit nd_syscall | |
-PASS: 32-bit process_vm nd_syscall | |
+FAIL: 32-bit process_vm nd_syscall | |
FAIL: 32-bit ptrace nd_syscall | |
PASS: 32-bit pwrite nd_syscall | |
PASS: 32-bit pwritev nd_syscall | |
@@ -7179,7 +7167,7 @@ | |
PASS: 32-bit readwrite nd_syscall | |
PASS: 32-bit reboot nd_syscall | |
PASS: 32-bit recv nd_syscall | |
-FAIL: 32-bit recvfrom nd_syscall | |
+PASS: 32-bit recvfrom nd_syscall | |
PASS: 32-bit recvmmsg nd_syscall | |
PASS: 32-bit recvmsg nd_syscall | |
PASS: 32-bit remap_file_pages nd_syscall | |
@@ -7214,7 +7202,7 @@ | |
PASS: 32-bit shmat nd_syscall | |
PASS: 32-bit shmget nd_syscall | |
PASS: 32-bit shutdown nd_syscall | |
-PASS: 32-bit sigaltstack nd_syscall | |
+FAIL: 32-bit sigaltstack nd_syscall | |
UNSUPPORTED: 32-bit sigmask nd_syscall not supported on this arch | |
PASS: 32-bit signal nd_syscall | |
PASS: 32-bit signalfd nd_syscall | |
@@ -7247,7 +7235,7 @@ | |
PASS: 32-bit vforkwait nd_syscall | |
PASS: 32-bit vhangup nd_syscall | |
PASS: 32-bit wait nd_syscall | |
-PASS: 32-bit wait4 nd_syscall | |
+FAIL: 32-bit wait4 nd_syscall | |
PASS: 32-bit writev nd_syscall | |
PASS: 32-bit xattr nd_syscall | |
Running /home/sultan/systemtap/testsuite/systemtap.syscall/syscall_consistency.exp ... | |
@@ -7337,7 +7325,7 @@ | |
PASS: 32-bit access syscall | |
PASS: 32-bit acct syscall | |
PASS: 32-bit adjtimex syscall | |
-FAIL: 32-bit aio syscall | |
+PASS: 32-bit aio syscall | |
FAIL: 32-bit alarm syscall | |
PASS: 32-bit arch_prctl syscall | |
PASS: 32-bit bind syscall | |
@@ -7346,9 +7334,9 @@ | |
PASS: 32-bit capability syscall | |
PASS: 32-bit chmod syscall | |
PASS: 32-bit chroot syscall | |
-PASS: 32-bit clock syscall | |
+FAIL: 32-bit clock syscall | |
PASS: 32-bit clone syscall | |
-FAIL: 32-bit connect syscall | |
+PASS: 32-bit connect syscall | |
FAIL: 32-bit copy_file_range syscall | |
PASS: 32-bit dcookie syscall | |
PASS: 32-bit dir syscall | |
@@ -7359,7 +7347,7 @@ | |
UNSUPPORTED: 32-bit execveat syscall not supported on this arch | |
PASS: 32-bit exit syscall | |
PASS: 32-bit exit_group syscall | |
-PASS: 32-bit fadvise64 syscall | |
+FAIL: 32-bit fadvise64 syscall | |
PASS: 32-bit fallocate syscall | |
PASS: 32-bit fanotify syscall | |
PASS: 32-bit flock syscall | |
@@ -7422,7 +7410,7 @@ | |
PASS: 32-bit pread syscall | |
PASS: 32-bit preadv syscall | |
PASS: 32-bit prlimit syscall | |
-FAIL: 32-bit process_vm syscall | |
+PASS: 32-bit process_vm syscall | |
PASS: 32-bit ptrace syscall | |
PASS: 32-bit pwrite syscall | |
PASS: 32-bit pwritev syscall | |
@@ -7432,8 +7420,8 @@ | |
PASS: 32-bit readv syscall | |
PASS: 32-bit readwrite syscall | |
PASS: 32-bit reboot syscall | |
-FAIL: 32-bit recv syscall | |
-FAIL: 32-bit recvfrom syscall | |
+PASS: 32-bit recv syscall | |
+PASS: 32-bit recvfrom syscall | |
PASS: 32-bit recvmmsg syscall | |
PASS: 32-bit recvmsg syscall | |
PASS: 32-bit remap_file_pages syscall | |
@@ -7479,7 +7467,7 @@ | |
PASS: 32-bit swap syscall | |
PASS: 32-bit sync syscall | |
PASS: 32-bit sync_file_range syscall | |
-FAIL: 32-bit syncfs syscall | |
+PASS: 32-bit syncfs syscall | |
PASS: 32-bit sysctl syscall | |
PASS: 32-bit sysfs syscall | |
PASS: 32-bit sysinfo syscall | |
@@ -7500,7 +7488,7 @@ | |
PASS: 32-bit userfaultfd syscall | |
PASS: 32-bit vforkwait syscall | |
PASS: 32-bit vhangup syscall | |
-FAIL: 32-bit wait syscall | |
+PASS: 32-bit wait syscall | |
FAIL: 32-bit wait4 syscall | |
PASS: 32-bit writev syscall | |
PASS: 32-bit xattr syscall | |
@@ -7538,7 +7526,7 @@ | |
PASS: 32-bit fanotify tp_syscall | |
PASS: 32-bit flock tp_syscall | |
PASS: 32-bit forkwait tp_syscall | |
-FAIL: 32-bit futex tp_syscall | |
+PASS: 32-bit futex tp_syscall | |
PASS: 32-bit futimes tp_syscall | |
PASS: 32-bit fxattr tp_syscall | |
PASS: 32-bit getcpu tp_syscall | |
@@ -7586,7 +7574,7 @@ | |
PASS: 32-bit numa tp_syscall | |
PASS: 32-bit openclose tp_syscall | |
FAIL: 32-bit perf_event tp_syscall | |
-PASS: 32-bit personality tp_syscall | |
+FAIL: 32-bit personality tp_syscall | |
PASS: 32-bit pgid tp_syscall | |
PASS: 32-bit pipe tp_syscall | |
PASS: 32-bit pivot_root tp_syscall | |
@@ -7597,7 +7585,7 @@ | |
PASS: 32-bit preadv tp_syscall | |
PASS: 32-bit prlimit tp_syscall | |
FAIL: 32-bit process_vm tp_syscall | |
-PASS: 32-bit ptrace tp_syscall | |
+FAIL: 32-bit ptrace tp_syscall | |
PASS: 32-bit pwrite tp_syscall | |
PASS: 32-bit pwritev tp_syscall | |
PASS: 32-bit quotactl tp_syscall | |
@@ -7608,8 +7596,8 @@ | |
PASS: 32-bit reboot tp_syscall | |
PASS: 32-bit recv tp_syscall | |
FAIL: 32-bit recvfrom tp_syscall | |
-PASS: 32-bit recvmmsg tp_syscall | |
-FAIL: 32-bit recvmsg tp_syscall | |
+FAIL: 32-bit recvmmsg tp_syscall | |
+PASS: 32-bit recvmsg tp_syscall | |
PASS: 32-bit remap_file_pages tp_syscall | |
PASS: 32-bit rename tp_syscall | |
PASS: 32-bit restart_syscall tp_syscall | |
@@ -7623,7 +7611,7 @@ | |
PASS: 32-bit sched_setaffinity tp_syscall | |
PASS: 32-bit sched_setscheduler tp_syscall | |
PASS: 32-bit seccomp tp_syscall | |
-PASS: 32-bit select tp_syscall | |
+FAIL: 32-bit select tp_syscall | |
PASS: 32-bit semctl tp_syscall | |
PASS: 32-bit semget tp_syscall | |
PASS: 32-bit semop tp_syscall | |
@@ -7674,7 +7662,7 @@ | |
PASS: 32-bit userfaultfd tp_syscall | |
PASS: 32-bit vforkwait tp_syscall | |
PASS: 32-bit vhangup tp_syscall | |
-FAIL: 32-bit wait tp_syscall | |
+PASS: 32-bit wait tp_syscall | |
PASS: 32-bit wait4 tp_syscall | |
PASS: 32-bit writev tp_syscall | |
PASS: 32-bit xattr tp_syscall | |
@@ -9082,7 +9070,7 @@ | |
PASS: unprivileged myproc: --unprivileged process.library(string).function(number).exported | |
PASS: unprivileged myproc: --privilege=stapusr process.library(string).function(string) | |
PASS: unprivileged myproc: --unprivileged process.library(string).function(string).call | |
-PASS: unprivileged myproc: --privilege=stapusr process.library(string).function(string).inline | |
+FAIL: unprivileged myproc: --privilege=stapusr process.library(string).function(string).inline | |
PASS: unprivileged myproc: --unprivileged process.library(string).function(string).return | |
PASS: unprivileged myproc: --privilege=stapusr process.library(string).function(string).exported | |
PASS: unprivileged myproc: --unprivileged process.library(string).function(string).label(string) | |
@@ -9117,7 +9105,7 @@ | |
UNTESTED: unprivileged myproc: --privilege=stapusr process(number).insn.block | |
KFAIL: unprivileged myproc: --privilege=stapusr process(number).statement(number).absolute (PRMS: INODE_UPROBES) | |
KFAIL: unprivileged myproc: --unprivileged process(number).statement(number).absolute.return (PRMS: INODE_UPROBES) | |
-PASS: unprivileged myproc: --privilege=stapusr process(number).syscall | |
+FAIL: unprivileged myproc: --privilege=stapusr process(number).syscall | |
PASS: unprivileged myproc: --unprivileged process(number).syscall.return | |
UNTESTED: unprivileged myproc: --privilege=stapusr process(number).thread.begin | |
UNTESTED: unprivileged myproc: --privilege=stapusr process(number).thread.end | |
@@ -9126,61 +9114,61 @@ | |
PASS: unprivileged myproc: --privilege=stapusr process(number).function(number).exported | |
PASS: unprivileged myproc: --unprivileged process(number).function(number).return | |
PASS: unprivileged myproc: --privilege=stapusr process(number).function(string) | |
-FAIL: unprivileged myproc: --unprivileged process(number).function(string).call | |
+PASS: unprivileged myproc: --unprivileged process(number).function(string).call | |
PASS: unprivileged myproc: --privilege=stapusr process(number).function(string).callee(string) | |
PASS: unprivileged myproc: --unprivileged process(number).function(string).callee(string).call | |
PASS: unprivileged myproc: --privilege=stapusr process(number).function(string).callee(string).return | |
PASS: unprivileged myproc: --unprivileged process(number).function(string).callees | |
PASS: unprivileged myproc: --privilege=stapusr process(number).function(string).callees(number) | |
PASS: unprivileged myproc: --unprivileged process(number).function(string).exported | |
-FAIL: unprivileged myproc: --privilege=stapusr process(number).function(string).inline | |
+PASS: unprivileged myproc: --privilege=stapusr process(number).function(string).inline | |
PASS: unprivileged myproc: --unprivileged process(number).function(string).label(string) | |
-PASS: unprivileged myproc: --privilege=stapusr process(number).function(string).return | |
+FAIL: unprivileged myproc: --privilege=stapusr process(number).function(string).return | |
PASS: unprivileged myproc: --unprivileged process(number).mark(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(number).plt | |
-PASS: unprivileged myproc: --unprivileged process(number).plt.return | |
-PASS: unprivileged myproc: --privilege=stapusr process(number).plt(string) | |
+FAIL: unprivileged myproc: --unprivileged process(number).plt.return | |
+FAIL: unprivileged myproc: --privilege=stapusr process(number).plt(string) | |
PASS: unprivileged myproc: --unprivileged process(number).plt(string).return | |
-PASS: unprivileged myproc: --privilege=stapusr process(number).provider(string).mark(string) | |
+FAIL: unprivileged myproc: --privilege=stapusr process(number).provider(string).mark(string) | |
PASS: unprivileged myproc: --unprivileged process(number).statement(number) | |
-FAIL: unprivileged myproc: --privilege=stapusr process(number).statement(number).nearest | |
+PASS: unprivileged myproc: --privilege=stapusr process(number).statement(number).nearest | |
PASS: unprivileged myproc: --unprivileged process(number).statement(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(number).statement(string).nearest | |
-FAIL: unprivileged myproc: --unprivileged process(string).begin | |
+PASS: unprivileged myproc: --unprivileged process(string).begin | |
FAIL: unprivileged myproc: --privilege=stapusr process(string).end | |
PASS: unprivileged myproc: --unprivileged process(string).function(number) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).function(number).call | |
KFAIL: unprivileged myproc: --unprivileged process(string).function(number).inline (PRMS: GCC) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).function(number).return | |
-PASS: unprivileged myproc: --unprivileged process(string).function(number).exported | |
+FAIL: unprivileged myproc: --unprivileged process(string).function(number).exported | |
PASS: unprivileged myproc: --privilege=stapusr process(string).function(string) | |
PASS: unprivileged myproc: --unprivileged process(string).function(string).call | |
-PASS: unprivileged myproc: --privilege=stapusr process(string).function(string).inline | |
-PASS: unprivileged myproc: --unprivileged process(string).function(string).return | |
+FAIL: unprivileged myproc: --privilege=stapusr process(string).function(string).inline | |
+FAIL: unprivileged myproc: --unprivileged process(string).function(string).return | |
PASS: unprivileged myproc: --privilege=stapusr process(string).function(string).exported | |
PASS: unprivileged myproc: --unprivileged process(string).function(string).callee(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).function(string).callee(string).call | |
PASS: unprivileged myproc: --unprivileged process(string).function(string).callee(string).return | |
-FAIL: unprivileged myproc: --privilege=stapusr process(string).function(string).callees | |
+PASS: unprivileged myproc: --privilege=stapusr process(string).function(string).callees | |
PASS: unprivileged myproc: --unprivileged process(string).function(string).callees(number) | |
UNTESTED: unprivileged myproc: --privilege=stapusr process(string).insn | |
UNTESTED: unprivileged myproc: --privilege=stapusr process(string).insn.block | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(number) | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).function(number).call | |
KFAIL: unprivileged myproc: --privilege=stapusr process(string).library(string).function(number).inline (PRMS: GCC) | |
-PASS: unprivileged myproc: --unprivileged process(string).library(string).function(number).return | |
+FAIL: unprivileged myproc: --unprivileged process(string).library(string).function(number).return | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(number).exported | |
-PASS: unprivileged myproc: --unprivileged process(string).library(string).function(string) | |
+FAIL: unprivileged myproc: --unprivileged process(string).library(string).function(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).call | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).function(string).inline | |
-PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).return | |
+FAIL: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).return | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).function(string).exported | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).label(string) | |
-PASS: unprivileged myproc: --unprivileged process(string).library(string).function(string).callee(string) | |
+FAIL: unprivileged myproc: --unprivileged process(string).library(string).function(string).callee(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).callee(string).call | |
UNTESTED: unprivileged myproc: --unprivileged process(string).library(string).function(string).callee(string).return | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).function(string).callees | |
-FAIL: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).callees(number) | |
+PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).function(string).callees(number) | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).mark(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).provider(string).mark(string) | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).statement(number) | |
@@ -9191,17 +9179,17 @@ | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).plt.return | |
PASS: unprivileged myproc: --unprivileged process(string).library(string).plt(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).library(string).plt(string).return | |
-PASS: unprivileged myproc: --unprivileged process(string).mark(string) | |
-FAIL: unprivileged myproc: --privilege=stapusr process(string).provider(string).mark(string) | |
+FAIL: unprivileged myproc: --unprivileged process(string).mark(string) | |
+PASS: unprivileged myproc: --privilege=stapusr process(string).provider(string).mark(string) | |
PASS: unprivileged myproc: --unprivileged process(string).statement(number) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).statement(number).nearest | |
PASS: unprivileged myproc: --unprivileged process(string).statement(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).statement(string).nearest | |
PASS: unprivileged myproc: --unprivileged process(string).plt | |
-FAIL: unprivileged myproc: --privilege=stapusr process(string).plt.return | |
-FAIL: unprivileged myproc: --unprivileged process(string).plt(string) | |
+PASS: unprivileged myproc: --privilege=stapusr process(string).plt.return | |
+PASS: unprivileged myproc: --unprivileged process(string).plt(string) | |
PASS: unprivileged myproc: --privilege=stapusr process(string).plt(string).return | |
-FAIL: unprivileged myproc: --unprivileged process(string).syscall | |
+PASS: unprivileged myproc: --unprivileged process(string).syscall | |
PASS: unprivileged myproc: --privilege=stapusr process(string).syscall.return | |
PASS: unprivileged myproc: --unprivileged process(string).thread.begin | |
PASS: unprivileged myproc: --privilege=stapusr process(string).thread.end | |
@@ -9252,7 +9240,7 @@ | |
PASS: unprivileged myproc: --privilege=stapsys process.library(string).provider(string).mark(string) | |
PASS: unprivileged myproc: --privilege=stapsys process.library(string).statement(number) | |
PASS: unprivileged myproc: --privilege=stapsys process.library(string).statement(number).nearest | |
-FAIL: unprivileged myproc: --privilege=stapsys process.library(string).statement(string) | |
+PASS: unprivileged myproc: --privilege=stapsys process.library(string).statement(string) | |
PASS: unprivileged myproc: --privilege=stapsys process.library(string).statement(string).nearest | |
PASS: unprivileged myproc: --privilege=stapsys process.provider(string).mark(string) | |
PASS: unprivileged myproc: --privilege=stapsys process.mark(string) | |
@@ -9279,7 +9267,7 @@ | |
PASS: unprivileged myproc: --privilege=stapsys process(number).function(number).exported | |
PASS: unprivileged myproc: --privilege=stapsys process(number).function(number).return | |
PASS: unprivileged myproc: --privilege=stapsys process(number).function(string) | |
-PASS: unprivileged myproc: --privilege=stapsys process(number).function(string).call | |
+FAIL: unprivileged myproc: --privilege=stapsys process(number).function(string).call | |
PASS: unprivileged myproc: --privilege=stapsys process(number).function(string).callee(string) | |
PASS: unprivileged myproc: --privilege=stapsys process(number).function(string).callee(string).call | |
PASS: unprivileged myproc: --privilege=stapsys process(number).function(string).callee(string).return | |
@@ -9308,10 +9296,10 @@ | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(number).exported | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string) | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).call | |
-PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).inline | |
+FAIL: unprivileged myproc: --privilege=stapsys process(string).function(string).inline | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).return | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).exported | |
-FAIL: unprivileged myproc: --privilege=stapsys process(string).function(string).callee(string) | |
+PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).callee(string) | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).callee(string).call | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).callee(string).return | |
PASS: unprivileged myproc: --privilege=stapsys process(string).function(string).callees | |
@@ -9324,7 +9312,7 @@ | |
PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(number).return | |
PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(number).exported | |
PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(string) | |
-FAIL: unprivileged myproc: --privilege=stapsys process(string).library(string).function(string).call | |
+PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(string).call | |
PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(string).inline | |
PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(string).return | |
PASS: unprivileged myproc: --privilege=stapsys process(string).library(string).function(string).exported | |
@@ -10330,8 +10318,8 @@ | |
=== systemtap Summary === | |
-# of expected passes 8071 | |
-# of unexpected failures 400 | |
+# of expected passes 8060 | |
+# of unexpected failures 396 | |
# of unexpected successes 9 | |
# of expected failures 346 | |
# of known failures 82 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment