Observed issue
==============
The following scenario leads to a hang on `lttng destroy`.
# Start lttng-sessiond under gdb
$ gdb lttng-sessiond
set pagination off
set non-stop
start
break action_executor_snapshot_session_handler
$ lttng add-trigger --name my_trigger --condition=event-rule-matches --type=user:tracepoint --name=sample_component:message --action=snapshot-session my_snapshot
$ lttng create --snapshot my_snapshot
$ lttng enable-event -u -a
$ lttng start
$ start an app producing a single sample_component:message
# gdb should break on thread 6
# inside gdb
thread 6
$ lttng destroy my_snapshot
$ lttng create --snapshot my_snapshot
$ lttng enable-event -u -a
$ lttng start
# inside gdb use `continue`
$ lttng destroy my_snapshot
The destroy command hang:
Destroying session my_snapshot.... ....
Cause
=====
The scenario forces the usage of the following code path:
if (session->id != LTTNG_OPTIONAL_GET(item->context.session_id)) {
624├───────────────> DBG("Session id for session `%s` (id: %" PRIu64
625│ " is not the same that was sampled (id: %" PRIu64
626│ " at the moment the work item was enqueued for %s` action of trigger `%s`",
627│ session_name, session->id,
628│ LTTNG_OPTIONAL_GET(item->context.session_id),
629│ get_action_name(action),
630│ get_trigger_name(work_item->trigger));
631│ ret = 0;
632│ goto error_unlock_list;
633│ }
At that point a reference on the session object was taken on line:
610│ session = session_find_by_name(session_name);
But the reference is never put on `error_unlock_list` resulting in a ref
count problem.
Solution
========
Use `session_put` for the code path.
Note that most of the handler also have the same problem that was
introduced by commit
72365501d3148ca977a09bad8de0ec51b427bdd8 [1]
Known drawbacks
=========
None.
Refs
=========
[1] https://github.com/lttng/lttng-tools/commit/
72365501d3148ca977a09bad8de0ec51b427bdd8
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I23c3c089866df74854bbfe64320310c4b28ee41d
get_action_name(action),
get_trigger_name(work_item->trigger));
ret = 0;
- goto error_unlock_list;
+ goto error_put_session;
}
session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
- goto error_dispose_session;
+ goto error_unlock_session;
}
cmd_ret = (lttng_error_code) cmd_start_trace(session);
break;
}
-error_dispose_session:
+error_unlock_session:
session_unlock(session);
+error_put_session:
session_put(session);
error_unlock_list:
session_unlock_list();
get_action_name(action),
get_trigger_name(work_item->trigger));
ret = 0;
- goto error_unlock_list;
+ goto error_put_session;
}
session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
- goto error_dispose_session;
+ goto error_unlock_session;
}
cmd_ret = (lttng_error_code) cmd_stop_trace(session);
break;
}
-error_dispose_session:
+error_unlock_session:
session_unlock(session);
+error_put_session:
session_put(session);
error_unlock_list:
session_unlock_list();
get_action_name(action),
get_trigger_name(work_item->trigger));
ret = 0;
- goto error_unlock_list;
+ goto error_put_session;
}
session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
- goto error_dispose_session;
+ goto error_unlock_session;
}
cmd_ret = (lttng_error_code) cmd_rotate_session(session, NULL, false,
break;
}
-error_dispose_session:
+error_unlock_session:
session_unlock(session);
+error_put_session:
session_put(session);
error_unlock_list:
session_unlock_list();
get_action_name(action),
get_trigger_name(work_item->trigger));
ret = 0;
- goto error_unlock_list;
+ goto error_put_session;
}
session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
- goto error_dispose_session;
+ goto error_unlock_session;
}
cmd_ret = (lttng_error_code) cmd_snapshot_record(session, snapshot_output, 0);
break;
}
-error_dispose_session:
+error_unlock_session:
session_unlock(session);
+error_put_session:
session_put(session);
error_unlock_list:
session_unlock_list();