summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
88a5db7)
The sockets hash table was allocated two times hence losing the first
reference at the second allocation.
Furthermore, when a kernel/ust session is created, a default consumer is
allocated but was lost short after that when the tracing session current
consumer was copied and the pointer was overwritten.
Note that this fixes the memory leak but there is a code logic that
seems wrong when it comes to handle the consumer object trace path and
subdir during the session creation. A comment has been added and it
should be fixed.
Signed-off-by: David Goulet <dgoulet@efficios.com>
*/
struct consumer_output *consumer_copy_output(struct consumer_output *obj)
{
*/
struct consumer_output *consumer_copy_output(struct consumer_output *obj)
{
+ struct lttng_ht *tmp_ht_ptr;
struct lttng_ht_iter iter;
struct consumer_socket *socket, *copy_sock;
struct consumer_output *output;
struct lttng_ht_iter iter;
struct consumer_socket *socket, *copy_sock;
struct consumer_output *output;
if (output == NULL) {
goto error;
}
if (output == NULL) {
goto error;
}
+ /* Avoid losing the HT reference after the memcpy() */
+ tmp_ht_ptr = output->socks;
memcpy(output, obj, sizeof(struct consumer_output));
memcpy(output, obj, sizeof(struct consumer_output));
- /* Copy sockets */
- output->socks = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+ /* Putting back the HT pointer and start copying socket(s). */
+ output->socks = tmp_ht_ptr;
cds_lfht_for_each_entry(obj->socks->ht, &iter.iter, socket, node.node) {
/* Create new socket object. */
cds_lfht_for_each_entry(obj->socks->ht, &iter.iter, socket, node.node) {
/* Create new socket object. */
+ copy_sock->registered = socket->registered;
copy_sock->lock = socket->lock;
consumer_add_socket(copy_sock, output);
}
copy_sock->lock = socket->lock;
consumer_add_socket(copy_sock, output);
}
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
DBG3("Copying tracing session consumer output in kernel session");
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
DBG3("Copying tracing session consumer output in kernel session");
+ /*
+ * XXX: We should audit the session creation and what this function
+ * does "extra" in order to avoid a destroy since this function is used
+ * in the domain session creation (kernel and ust) only. Same for UST
+ * domain.
+ */
+ if (session->kernel_session->consumer) {
+ consumer_destroy_output(session->kernel_session->consumer);
+ }
session->kernel_session->consumer =
consumer_copy_output(session->consumer);
/* Ease our life a bit for the next part */
session->kernel_session->consumer =
consumer_copy_output(session->consumer);
/* Ease our life a bit for the next part */
break;
case LTTNG_DOMAIN_UST:
DBG3("Copying tracing session consumer output in UST session");
break;
case LTTNG_DOMAIN_UST:
DBG3("Copying tracing session consumer output in UST session");
+ if (session->ust_session->consumer) {
+ consumer_destroy_output(session->ust_session->consumer);
+ }
session->ust_session->consumer =
consumer_copy_output(session->consumer);
/* Ease our life a bit for the next part */
session->ust_session->consumer =
consumer_copy_output(session->consumer);
/* Ease our life a bit for the next part */
lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
if (lus->consumer == NULL) {
lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
if (lus->consumer == NULL) {
- goto error_free_session;
"%s" DEFAULT_UST_TRACE_DIR, path);
if (ret < 0) {
PERROR("snprintf UST consumer trace path");
"%s" DEFAULT_UST_TRACE_DIR, path);
if (ret < 0) {
PERROR("snprintf UST consumer trace path");
path);
if (ret < 0) {
PERROR("snprintf kernel traces path");
path);
if (ret < 0) {
PERROR("snprintf kernel traces path");
- goto error_free_session;
+error_path:
+ consumer_destroy_output(lus->consumer);
+error_consumer:
lttng_ht_destroy(lus->domain_global.channels);
lttng_ht_destroy(lus->domain_exec);
lttng_ht_destroy(lus->domain_pid);
lttng_ht_destroy(lus->domain_global.channels);
lttng_ht_destroy(lus->domain_exec);
lttng_ht_destroy(lus->domain_pid);