Fix: statedump: invalid read during iter_end
[lttng-ust.git] / src / lib / lttng-ust / lttng-ust-statedump.c
CommitLineData
cf73e0fe 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-or-later
cf73e0fe 3 *
c0c0989a
MJ
4 * Copyright (C) 2013 Paul Woegerer <paul_woegerer@mentor.com>
5 * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
6 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
cf73e0fe
AB
7 */
8
1ddceb36 9#define _LGPL_SOURCE
8e2aed3f 10#include <link.h>
cf73e0fe 11#include <limits.h>
cf73e0fe 12#include <stdio.h>
8e2aed3f
AB
13#include <stdint.h>
14#include <stdlib.h>
97c7c238 15#include <stdbool.h>
8e2aed3f
AB
16#include <sys/types.h>
17#include <unistd.h>
cf73e0fe 18
9d315d6d
MJ
19#include "common/elf.h"
20#include "common/macros.h"
cf73e0fe
AB
21#include "lttng-tracer-core.h"
22#include "lttng-ust-statedump.h"
e58e5ad5 23#include "common/jhash.h"
910dcd72 24#include "common/getenv.h"
36c52fff 25#include "lib/lttng-ust/events.h"
cf73e0fe 26
6ba0c2b2
MD
27#define LTTNG_UST_TRACEPOINT_HIDDEN_DEFINITION
28#define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
29
88c7c4ea 30#define LTTNG_UST_TRACEPOINT_DEFINE
97c7c238
MD
31#include "ust_lib.h" /* Only define. */
32
660323e6 33#define LTTNG_UST_TRACEPOINT_CREATE_PROBES
91fe3e13 34#define LTTNG_UST_TP_SESSION_CHECK
97c7c238 35#include "lttng-ust-statedump-provider.h" /* Define and create probes. */
cf73e0fe
AB
36
37struct dl_iterate_data {
cf73e0fe 38 int exec_found;
97c7c238
MD
39 bool first;
40 bool cancel;
cf73e0fe
AB
41};
42
f60e49df 43struct bin_info_data {
cf73e0fe 44 void *base_addr_ptr;
97c7c238 45 char resolved_path[PATH_MAX];
8e2aed3f
AB
46 char *dbg_file;
47 uint8_t *build_id;
48 uint64_t memsz;
49 size_t build_id_len;
cf73e0fe 50 int vdso;
8e2aed3f 51 uint32_t crc;
f5eb039d 52 uint8_t is_pic;
c5c4fd82
MD
53 uint8_t has_build_id;
54 uint8_t has_debug_link;
cf73e0fe
AB
55};
56
97c7c238
MD
57struct lttng_ust_dl_node {
58 struct bin_info_data bin_data;
59 struct cds_hlist_node node;
60 bool traced;
61 bool marked;
62};
63
64#define UST_DL_STATE_HASH_BITS 8
65#define UST_DL_STATE_TABLE_SIZE (1 << UST_DL_STATE_HASH_BITS)
95fa2ba4 66static struct cds_hlist_head dl_state_table[UST_DL_STATE_TABLE_SIZE];
97c7c238 67
f69fe5fb 68typedef void (*tracepoint_cb)(struct lttng_ust_session *session, void *priv);
cf73e0fe 69
97c7c238
MD
70static
71struct lttng_ust_dl_node *alloc_dl_node(const struct bin_info_data *bin_data)
72{
73 struct lttng_ust_dl_node *e;
74
75 e = zmalloc(sizeof(struct lttng_ust_dl_node));
76 if (!e)
77 return NULL;
78 if (bin_data->dbg_file) {
79 e->bin_data.dbg_file = strdup(bin_data->dbg_file);
80 if (!e->bin_data.dbg_file)
81 goto error;
82 }
83 if (bin_data->build_id) {
84 e->bin_data.build_id = zmalloc(bin_data->build_id_len);
85 if (!e->bin_data.build_id)
86 goto error;
87 memcpy(e->bin_data.build_id, bin_data->build_id,
88 bin_data->build_id_len);
89 }
90 e->bin_data.base_addr_ptr = bin_data->base_addr_ptr;
91 memcpy(e->bin_data.resolved_path, bin_data->resolved_path, PATH_MAX);
92 e->bin_data.memsz = bin_data->memsz;
93 e->bin_data.build_id_len = bin_data->build_id_len;
94 e->bin_data.vdso = bin_data->vdso;
95 e->bin_data.crc = bin_data->crc;
96 e->bin_data.is_pic = bin_data->is_pic;
97 e->bin_data.has_build_id = bin_data->has_build_id;
98 e->bin_data.has_debug_link = bin_data->has_debug_link;
99 return e;
100
101error:
102 free(e->bin_data.build_id);
103 free(e->bin_data.dbg_file);
104 free(e);
105 return NULL;
106}
107
108static
109void free_dl_node(struct lttng_ust_dl_node *e)
110{
111 free(e->bin_data.build_id);
112 free(e->bin_data.dbg_file);
113 free(e);
114}
115
116/* Return 0 if same, nonzero if not. */
117static
118int compare_bin_data(const struct bin_info_data *a,
119 const struct bin_info_data *b)
120{
121 if (a->base_addr_ptr != b->base_addr_ptr)
122 return -1;
123 if (strcmp(a->resolved_path, b->resolved_path) != 0)
124 return -1;
125 if (a->dbg_file && !b->dbg_file)
126 return -1;
127 if (!a->dbg_file && b->dbg_file)
128 return -1;
129 if (a->dbg_file && strcmp(a->dbg_file, b->dbg_file) != 0)
130 return -1;
131 if (a->build_id && !b->build_id)
132 return -1;
133 if (!a->build_id && b->build_id)
134 return -1;
135 if (a->build_id_len != b->build_id_len)
136 return -1;
137 if (a->build_id &&
138 memcmp(a->build_id, b->build_id, a->build_id_len) != 0)
139 return -1;
140 if (a->memsz != b->memsz)
141 return -1;
142 if (a->vdso != b->vdso)
143 return -1;
144 if (a->crc != b->crc)
145 return -1;
146 if (a->is_pic != b->is_pic)
147 return -1;
148 if (a->has_build_id != b->has_build_id)
149 return -1;
150 if (a->has_debug_link != b->has_debug_link)
151 return -1;
152 return 0;
153}
154
155static
156struct lttng_ust_dl_node *find_or_create_dl_node(struct bin_info_data *bin_data)
157{
158 struct cds_hlist_head *head;
159 struct lttng_ust_dl_node *e;
160 unsigned int hash;
161 bool found = false;
162
163 hash = jhash(&bin_data->base_addr_ptr,
164 sizeof(bin_data->base_addr_ptr), 0);
165 head = &dl_state_table[hash & (UST_DL_STATE_TABLE_SIZE - 1)];
166 cds_hlist_for_each_entry_2(e, head, node) {
167 if (compare_bin_data(&e->bin_data, bin_data) != 0)
168 continue;
169 found = true;
170 break;
171 }
172 if (!found) {
173 /* Create */
174 e = alloc_dl_node(bin_data);
175 if (!e)
176 return NULL;
177 cds_hlist_add_head(&e->node, head);
178 }
179 return e;
180}
181
182static
183void remove_dl_node(struct lttng_ust_dl_node *e)
184{
185 cds_hlist_del(&e->node);
186}
187
cf73e0fe
AB
188/*
189 * Trace statedump event into all sessions owned by the caller thread
190 * for which statedump is pending.
191 */
192static
97c7c238 193void trace_statedump_event(tracepoint_cb tp_cb, void *owner, void *priv)
cf73e0fe
AB
194{
195 struct cds_list_head *sessionsp;
bdb12629 196 struct lttng_ust_session_private *session_priv;
cf73e0fe 197
7753d283 198 sessionsp = lttng_get_sessions();
bdb12629
MD
199 cds_list_for_each_entry(session_priv, sessionsp, node) {
200 if (session_priv->owner != owner)
cf73e0fe 201 continue;
bdb12629 202 if (!session_priv->statedump_pending)
cf73e0fe 203 continue;
bdb12629 204 tp_cb(session_priv->pub, priv);
cf73e0fe 205 }
cf73e0fe
AB
206}
207
208static
f69fe5fb 209void trace_bin_info_cb(struct lttng_ust_session *session, void *priv)
cf73e0fe 210{
f60e49df 211 struct bin_info_data *bin_data = (struct bin_info_data *) priv;
cf73e0fe 212
cbc06a3b 213 lttng_ust_tracepoint(lttng_ust_statedump, bin_info,
f60e49df 214 session, bin_data->base_addr_ptr,
c5c4fd82
MD
215 bin_data->resolved_path, bin_data->memsz,
216 bin_data->is_pic, bin_data->has_build_id,
217 bin_data->has_debug_link);
8e2aed3f
AB
218}
219
220static
f69fe5fb 221void trace_build_id_cb(struct lttng_ust_session *session, void *priv)
8e2aed3f 222{
f60e49df 223 struct bin_info_data *bin_data = (struct bin_info_data *) priv;
8e2aed3f 224
cbc06a3b 225 lttng_ust_tracepoint(lttng_ust_statedump, build_id,
f60e49df
AB
226 session, bin_data->base_addr_ptr,
227 bin_data->build_id, bin_data->build_id_len);
8e2aed3f
AB
228}
229
230static
f69fe5fb 231void trace_debug_link_cb(struct lttng_ust_session *session, void *priv)
8e2aed3f 232{
f60e49df 233 struct bin_info_data *bin_data = (struct bin_info_data *) priv;
8e2aed3f 234
cbc06a3b 235 lttng_ust_tracepoint(lttng_ust_statedump, debug_link,
f60e49df
AB
236 session, bin_data->base_addr_ptr,
237 bin_data->dbg_file, bin_data->crc);
cf73e0fe
AB
238}
239
94be38e8 240static
f69fe5fb 241void procname_cb(struct lttng_ust_session *session, void *priv)
94be38e8
JR
242{
243 char *procname = (char *) priv;
cbc06a3b 244 lttng_ust_tracepoint(lttng_ust_statedump, procname, session, procname);
94be38e8
JR
245}
246
cf73e0fe 247static
2208d8b5 248void trace_start_cb(struct lttng_ust_session *session, void *priv __attribute__((unused)))
cf73e0fe 249{
cbc06a3b 250 lttng_ust_tracepoint(lttng_ust_statedump, start, session);
cf73e0fe
AB
251}
252
253static
2208d8b5 254void trace_end_cb(struct lttng_ust_session *session, void *priv __attribute__((unused)))
cf73e0fe 255{
cbc06a3b 256 lttng_ust_tracepoint(lttng_ust_statedump, end, session);
cf73e0fe
AB
257}
258
8e2aed3f 259static
c5c4fd82
MD
260int get_elf_info(struct bin_info_data *bin_data)
261{
8e2aed3f 262 struct lttng_ust_elf *elf;
c5c4fd82 263 int ret = 0, found;
8e2aed3f 264
f60e49df 265 elf = lttng_ust_elf_create(bin_data->resolved_path);
8e2aed3f
AB
266 if (!elf) {
267 ret = -1;
268 goto end;
269 }
270
f60e49df 271 ret = lttng_ust_elf_get_memsz(elf, &bin_data->memsz);
8e2aed3f
AB
272 if (ret) {
273 goto end;
274 }
275
c5c4fd82 276 found = 0;
f60e49df 277 ret = lttng_ust_elf_get_build_id(elf, &bin_data->build_id,
c5c4fd82
MD
278 &bin_data->build_id_len,
279 &found);
8e2aed3f
AB
280 if (ret) {
281 goto end;
282 }
c5c4fd82
MD
283 bin_data->has_build_id = !!found;
284 found = 0;
f60e49df 285 ret = lttng_ust_elf_get_debug_link(elf, &bin_data->dbg_file,
c5c4fd82
MD
286 &bin_data->crc,
287 &found);
8e2aed3f
AB
288 if (ret) {
289 goto end;
290 }
c5c4fd82 291 bin_data->has_debug_link = !!found;
8e2aed3f 292
f60e49df 293 bin_data->is_pic = lttng_ust_elf_is_pic(elf);
f5eb039d 294
8e2aed3f
AB
295end:
296 lttng_ust_elf_destroy(elf);
297 return ret;
298}
299
cf73e0fe 300static
97c7c238
MD
301void trace_baddr(struct bin_info_data *bin_data, void *owner)
302{
303 trace_statedump_event(trace_bin_info_cb, owner, bin_data);
304
305 if (bin_data->has_build_id)
306 trace_statedump_event(trace_build_id_cb, owner, bin_data);
307
308 if (bin_data->has_debug_link)
309 trace_statedump_event(trace_debug_link_cb, owner, bin_data);
310}
311
312static
313int extract_baddr(struct bin_info_data *bin_data)
cf73e0fe 314{
c5c4fd82 315 int ret = 0;
97c7c238 316 struct lttng_ust_dl_node *e;
8e2aed3f 317
f60e49df 318 if (!bin_data->vdso) {
c5c4fd82 319 ret = get_elf_info(bin_data);
8e2aed3f
AB
320 if (ret) {
321 goto end;
322 }
323 } else {
f60e49df 324 bin_data->memsz = 0;
fd783031
MD
325 bin_data->has_build_id = 0;
326 bin_data->has_debug_link = 0;
8e2aed3f
AB
327 }
328
97c7c238
MD
329 e = find_or_create_dl_node(bin_data);
330 if (!e) {
331 ret = -1;
8e2aed3f
AB
332 goto end;
333 }
97c7c238 334 e->marked = true;
8e2aed3f 335end:
97c7c238
MD
336 free(bin_data->build_id);
337 bin_data->build_id = NULL;
338 free(bin_data->dbg_file);
339 bin_data->dbg_file = NULL;
8e2aed3f 340 return ret;
cf73e0fe
AB
341}
342
343static
97c7c238 344void trace_statedump_start(void *owner)
cf73e0fe 345{
97c7c238 346 trace_statedump_event(trace_start_cb, owner, NULL);
cf73e0fe
AB
347}
348
349static
97c7c238 350void trace_statedump_end(void *owner)
cf73e0fe 351{
97c7c238 352 trace_statedump_event(trace_end_cb, owner, NULL);
cf73e0fe
AB
353}
354
355static
97c7c238 356void iter_begin(struct dl_iterate_data *data)
cf73e0fe 357{
97c7c238 358 unsigned int i;
cf73e0fe 359
d34e6761
MD
360 /*
361 * UST lock nests within dynamic loader lock.
362 *
97c7c238 363 * Hold this lock across handling of the module listing to
d34e6761
MD
364 * protect memory allocation at early process start, due to
365 * interactions with libc-wrapper lttng malloc instrumentation.
366 */
367 if (ust_lock()) {
97c7c238
MD
368 data->cancel = true;
369 return;
d34e6761
MD
370 }
371
97c7c238
MD
372 /* Ensure all entries are unmarked. */
373 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
374 struct cds_hlist_head *head;
375 struct lttng_ust_dl_node *e;
376
377 head = &dl_state_table[i];
378 cds_hlist_for_each_entry_2(e, head, node)
379 assert(!e->marked);
380 }
381}
382
383static
384void trace_lib_load(const struct bin_info_data *bin_data, void *ip)
385{
cbc06a3b 386 lttng_ust_tracepoint(lttng_ust_lib, load,
97c7c238
MD
387 ip, bin_data->base_addr_ptr, bin_data->resolved_path,
388 bin_data->memsz, bin_data->has_build_id,
389 bin_data->has_debug_link);
390
391 if (bin_data->has_build_id) {
cbc06a3b 392 lttng_ust_tracepoint(lttng_ust_lib, build_id,
97c7c238
MD
393 ip, bin_data->base_addr_ptr, bin_data->build_id,
394 bin_data->build_id_len);
395 }
396
397 if (bin_data->has_debug_link) {
cbc06a3b 398 lttng_ust_tracepoint(lttng_ust_lib, debug_link,
97c7c238
MD
399 ip, bin_data->base_addr_ptr, bin_data->dbg_file,
400 bin_data->crc);
401 }
402}
403
404static
405void trace_lib_unload(const struct bin_info_data *bin_data, void *ip)
406{
cbc06a3b 407 lttng_ust_tracepoint(lttng_ust_lib, unload, ip, bin_data->base_addr_ptr);
97c7c238
MD
408}
409
410static
411void iter_end(struct dl_iterate_data *data, void *ip)
412{
413 unsigned int i;
414
2eb235ec
MD
415 if (data->cancel)
416 goto end;
97c7c238
MD
417 /*
418 * Iterate on hash table.
419 * For each marked, traced, do nothing.
420 * For each marked, not traced, trace lib open event. traced = true.
421 * For each unmarked, traced, trace lib close event. remove node.
422 * For each unmarked, not traced, remove node.
423 */
424 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
425 struct cds_hlist_head *head;
2ebb2790 426 struct lttng_ust_dl_node *e, *tmp;
97c7c238
MD
427
428 head = &dl_state_table[i];
2ebb2790 429 cds_hlist_for_each_entry_safe_2(e, tmp, head, node) {
97c7c238
MD
430 if (e->marked) {
431 if (!e->traced) {
432 trace_lib_load(&e->bin_data, ip);
433 e->traced = true;
434 }
b891574e 435 e->marked = false;
97c7c238
MD
436 } else {
437 if (e->traced)
438 trace_lib_unload(&e->bin_data, ip);
439 remove_dl_node(e);
440 free_dl_node(e);
441 }
97c7c238
MD
442 }
443 }
2eb235ec 444end:
97c7c238
MD
445 ust_unlock();
446}
447
448static
2208d8b5 449int extract_bin_info_events(struct dl_phdr_info *info, size_t size __attribute__((unused)), void *_data)
97c7c238
MD
450{
451 int j, ret = 0;
452 struct dl_iterate_data *data = _data;
453
454 if (data->first) {
455 iter_begin(data);
456 data->first = false;
457 }
458
459 if (data->cancel)
460 goto end;
461
cf73e0fe 462 for (j = 0; j < info->dlpi_phnum; j++) {
f60e49df 463 struct bin_info_data bin_data;
cf73e0fe
AB
464
465 if (info->dlpi_phdr[j].p_type != PT_LOAD)
466 continue;
467
97c7c238
MD
468 memset(&bin_data, 0, sizeof(bin_data));
469
cf73e0fe 470 /* Calculate virtual memory address of the loadable segment */
97c7c238 471 bin_data.base_addr_ptr = (void *) info->dlpi_addr +
cf73e0fe
AB
472 info->dlpi_phdr[j].p_vaddr;
473
474 if ((info->dlpi_name == NULL || info->dlpi_name[0] == 0)) {
475 /*
476 * Only the first phdr without a dlpi_name
477 * encountered is considered as the program
478 * executable. The rest are vdsos.
479 */
480 if (!data->exec_found) {
481 ssize_t path_len;
482 data->exec_found = 1;
483
484 /*
485 * Use /proc/self/exe to resolve the
486 * executable's full path.
487 */
488 path_len = readlink("/proc/self/exe",
97c7c238 489 bin_data.resolved_path,
cf73e0fe
AB
490 PATH_MAX - 1);
491 if (path_len <= 0)
492 break;
493
97c7c238 494 bin_data.resolved_path[path_len] = '\0';
f60e49df 495 bin_data.vdso = 0;
cf73e0fe 496 } else {
97c7c238
MD
497 snprintf(bin_data.resolved_path,
498 PATH_MAX - 1, "[vdso]");
f60e49df 499 bin_data.vdso = 1;
cf73e0fe
AB
500 }
501 } else {
502 /*
503 * For regular dl_phdr_info entries check if
f60e49df 504 * the path to the binary really exists. If not,
cf73e0fe
AB
505 * treat as vdso and use dlpi_name as 'path'.
506 */
97c7c238
MD
507 if (!realpath(info->dlpi_name,
508 bin_data.resolved_path)) {
509 snprintf(bin_data.resolved_path,
510 PATH_MAX - 1, "[%s]",
cf73e0fe 511 info->dlpi_name);
f60e49df 512 bin_data.vdso = 1;
89be5359 513 } else {
f60e49df 514 bin_data.vdso = 0;
cf73e0fe
AB
515 }
516 }
517
97c7c238 518 ret = extract_baddr(&bin_data);
d34e6761 519 break;
cf73e0fe 520 }
d34e6761 521end:
d34e6761 522 return ret;
cf73e0fe
AB
523}
524
cf73e0fe 525static
97c7c238
MD
526void ust_dl_table_statedump(void *owner)
527{
528 unsigned int i;
529
530 if (ust_lock())
531 goto end;
532
533 /* Statedump each traced table entry into session for owner. */
534 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
535 struct cds_hlist_head *head;
536 struct lttng_ust_dl_node *e;
537
538 head = &dl_state_table[i];
539 cds_hlist_for_each_entry_2(e, head, node) {
540 if (e->traced)
541 trace_baddr(&e->bin_data, owner);
542 }
543 }
544
545end:
546 ust_unlock();
547}
548
549void lttng_ust_dl_update(void *ip)
cf73e0fe
AB
550{
551 struct dl_iterate_data data;
552
4c41b460 553 if (lttng_ust_getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
97c7c238 554 return;
cf73e0fe 555
c362addf 556 /*
a9fd951a
MJ
557 * Force the allocation of lttng-ust TLS variables when called from
558 * dlopen/dlclose instrumentation.
c362addf 559 */
a9fd951a 560 lttng_ust_alloc_tls();
c362addf 561
cf73e0fe 562 data.exec_found = 0;
97c7c238
MD
563 data.first = true;
564 data.cancel = false;
cf73e0fe
AB
565 /*
566 * Iterate through the list of currently loaded shared objects and
97c7c238 567 * generate tables entries for loadable segments using
f60e49df 568 * extract_bin_info_events.
97c7c238
MD
569 * Removed libraries are detected by mark-and-sweep: marking is
570 * done in the iteration over libraries, and sweeping is
571 * performed by iter_end().
cf73e0fe 572 */
f60e49df 573 dl_iterate_phdr(extract_bin_info_events, &data);
97c7c238
MD
574 if (data.first)
575 iter_begin(&data);
576 iter_end(&data, ip);
577}
cf73e0fe 578
97c7c238
MD
579/*
580 * Generate a statedump of base addresses of all shared objects loaded
581 * by the traced application, as well as for the application's
582 * executable itself.
583 */
584static
585int do_baddr_statedump(void *owner)
586{
4c41b460 587 if (lttng_ust_getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
97c7c238
MD
588 return 0;
589 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
590 ust_dl_table_statedump(owner);
cf73e0fe
AB
591 return 0;
592}
593
94be38e8
JR
594static
595int do_procname_statedump(void *owner)
596{
4c41b460 597 if (lttng_ust_getenv("LTTNG_UST_WITHOUT_PROCNAME_STATEDUMP"))
94be38e8
JR
598 return 0;
599
600 trace_statedump_event(procname_cb, owner, lttng_ust_sockinfo_get_procname(owner));
601 return 0;
602}
603
cf73e0fe
AB
604/*
605 * Generate a statedump of a given traced application. A statedump is
606 * delimited by start and end events. For a given (process, session)
607 * pair, begin/end events are serialized and will match. However, in a
608 * session, statedumps from different processes may be
609 * interleaved. The vpid context should be used to identify which
610 * events belong to which process.
8002ea62
MD
611 *
612 * Grab the ust_lock outside of the RCU read-side lock because we
613 * perform synchronize_rcu with the ust_lock held, which can trigger
614 * deadlocks otherwise.
cf73e0fe
AB
615 */
616int do_lttng_ust_statedump(void *owner)
617{
8002ea62 618 ust_lock_nocheck();
cf73e0fe 619 trace_statedump_start(owner);
8002ea62
MD
620 ust_unlock();
621
94be38e8 622 do_procname_statedump(owner);
cf73e0fe 623 do_baddr_statedump(owner);
8002ea62
MD
624
625 ust_lock_nocheck();
cf73e0fe 626 trace_statedump_end(owner);
8002ea62 627 ust_unlock();
cf73e0fe
AB
628
629 return 0;
630}
631
632void lttng_ust_statedump_init(void)
633{
ac9f44c2
MJ
634 lttng_ust__tracepoints__init();
635 lttng_ust__tracepoints__ptrs_init();
11bce056 636 lttng_ust__events_init__lttng_ust_statedump();
97c7c238
MD
637 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
638}
639
640static
641void ust_dl_state_destroy(void)
642{
643 unsigned int i;
644
645 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
646 struct cds_hlist_head *head;
647 struct lttng_ust_dl_node *e, *tmp;
648
649 head = &dl_state_table[i];
650 cds_hlist_for_each_entry_safe_2(e, tmp, head, node)
651 free_dl_node(e);
652 CDS_INIT_HLIST_HEAD(head);
653 }
cf73e0fe
AB
654}
655
656void lttng_ust_statedump_destroy(void)
657{
638ce920 658 lttng_ust__events_exit__lttng_ust_statedump();
ac9f44c2
MJ
659 lttng_ust__tracepoints__ptrs_destroy();
660 lttng_ust__tracepoints__destroy();
97c7c238 661 ust_dl_state_destroy();
cf73e0fe 662}
This page took 0.064923 seconds and 4 git commands to generate.