2 * Copyright (C) 2013 Paul Woegerer <paul_woegerer@mentor.com>
3 * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <sys/types.h>
31 #include <lttng/ust-elf.h>
32 #include "lttng-tracer-core.h"
33 #include "lttng-ust-statedump.h"
36 #define TRACEPOINT_DEFINE
37 #define TRACEPOINT_CREATE_PROBES
38 #define TP_SESSION_CHECK
39 #include "lttng-ust-statedump-provider.h"
41 struct dl_iterate_data
{
46 struct bin_info_data
{
49 const char *resolved_path
;
58 uint8_t has_debug_link
;
61 typedef void (*tracepoint_cb
)(struct lttng_session
*session
, void *priv
);
64 * Trace statedump event into all sessions owned by the caller thread
65 * for which statedump is pending.
68 int trace_statedump_event(tracepoint_cb tp_cb
, void *owner
, void *priv
)
70 struct cds_list_head
*sessionsp
;
71 struct lttng_session
*session
;
73 sessionsp
= _lttng_get_sessions();
74 cds_list_for_each_entry(session
, sessionsp
, node
) {
75 if (session
->owner
!= owner
)
77 if (!session
->statedump_pending
)
85 void trace_bin_info_cb(struct lttng_session
*session
, void *priv
)
87 struct bin_info_data
*bin_data
= (struct bin_info_data
*) priv
;
89 tracepoint(lttng_ust_statedump
, bin_info
,
90 session
, bin_data
->base_addr_ptr
,
91 bin_data
->resolved_path
, bin_data
->memsz
,
92 bin_data
->is_pic
, bin_data
->has_build_id
,
93 bin_data
->has_debug_link
);
97 void trace_build_id_cb(struct lttng_session
*session
, void *priv
)
99 struct bin_info_data
*bin_data
= (struct bin_info_data
*) priv
;
101 tracepoint(lttng_ust_statedump
, build_id
,
102 session
, bin_data
->base_addr_ptr
,
103 bin_data
->build_id
, bin_data
->build_id_len
);
107 void trace_debug_link_cb(struct lttng_session
*session
, void *priv
)
109 struct bin_info_data
*bin_data
= (struct bin_info_data
*) priv
;
111 tracepoint(lttng_ust_statedump
, debug_link
,
112 session
, bin_data
->base_addr_ptr
,
113 bin_data
->dbg_file
, bin_data
->crc
);
117 void trace_start_cb(struct lttng_session
*session
, void *priv
)
119 tracepoint(lttng_ust_statedump
, start
, session
);
123 void trace_end_cb(struct lttng_session
*session
, void *priv
)
125 tracepoint(lttng_ust_statedump
, end
, session
);
129 int get_elf_info(struct bin_info_data
*bin_data
)
131 struct lttng_ust_elf
*elf
;
134 elf
= lttng_ust_elf_create(bin_data
->resolved_path
);
140 ret
= lttng_ust_elf_get_memsz(elf
, &bin_data
->memsz
);
146 ret
= lttng_ust_elf_get_build_id(elf
, &bin_data
->build_id
,
147 &bin_data
->build_id_len
,
152 bin_data
->has_build_id
= !!found
;
154 ret
= lttng_ust_elf_get_debug_link(elf
, &bin_data
->dbg_file
,
160 bin_data
->has_debug_link
= !!found
;
162 bin_data
->is_pic
= lttng_ust_elf_is_pic(elf
);
165 lttng_ust_elf_destroy(elf
);
170 int trace_baddr(struct bin_info_data
*bin_data
)
174 if (!bin_data
->vdso
) {
175 ret
= get_elf_info(bin_data
);
181 bin_data
->has_build_id
= 0;
182 bin_data
->has_debug_link
= 0;
185 ret
= trace_statedump_event(trace_bin_info_cb
, bin_data
->owner
,
191 if (bin_data
->has_build_id
) {
192 ret
= trace_statedump_event(
193 trace_build_id_cb
, bin_data
->owner
, bin_data
);
194 free(bin_data
->build_id
);
200 if (bin_data
->has_debug_link
) {
201 ret
= trace_statedump_event(
202 trace_debug_link_cb
, bin_data
->owner
, bin_data
);
203 free(bin_data
->dbg_file
);
214 int trace_statedump_start(void *owner
)
216 return trace_statedump_event(trace_start_cb
, owner
, NULL
);
220 int trace_statedump_end(void *owner
)
222 return trace_statedump_event(trace_end_cb
, owner
, NULL
);
226 int extract_bin_info_events(struct dl_phdr_info
*info
, size_t size
, void *_data
)
229 struct dl_iterate_data
*data
= _data
;
232 * UST lock nests within dynamic loader lock.
234 * Hold this lock across handling of the entire module to
235 * protect memory allocation at early process start, due to
236 * interactions with libc-wrapper lttng malloc instrumentation.
242 for (j
= 0; j
< info
->dlpi_phnum
; j
++) {
243 struct bin_info_data bin_data
;
244 char resolved_path
[PATH_MAX
];
247 if (info
->dlpi_phdr
[j
].p_type
!= PT_LOAD
)
250 /* Calculate virtual memory address of the loadable segment */
251 base_addr_ptr
= (void *) info
->dlpi_addr
+
252 info
->dlpi_phdr
[j
].p_vaddr
;
254 if ((info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == 0)) {
256 * Only the first phdr without a dlpi_name
257 * encountered is considered as the program
258 * executable. The rest are vdsos.
260 if (!data
->exec_found
) {
262 data
->exec_found
= 1;
265 * Use /proc/self/exe to resolve the
266 * executable's full path.
268 path_len
= readlink("/proc/self/exe",
274 resolved_path
[path_len
] = '\0';
277 snprintf(resolved_path
, PATH_MAX
- 1, "[vdso]");
282 * For regular dl_phdr_info entries check if
283 * the path to the binary really exists. If not,
284 * treat as vdso and use dlpi_name as 'path'.
286 if (!realpath(info
->dlpi_name
, resolved_path
)) {
287 snprintf(resolved_path
, PATH_MAX
- 1, "[%s]",
295 bin_data
.owner
= data
->owner
;
296 bin_data
.base_addr_ptr
= base_addr_ptr
;
297 bin_data
.resolved_path
= resolved_path
;
298 ret
= trace_baddr(&bin_data
);
307 * Generate a statedump of base addresses of all shared objects loaded
308 * by the traced application, as well as for the application's
312 int do_baddr_statedump(void *owner
)
314 struct dl_iterate_data data
;
316 if (lttng_getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
320 * Fixup lttng-ust TLS when called from dlopen/dlclose
323 lttng_ust_fixup_tls();
328 * Iterate through the list of currently loaded shared objects and
329 * generate events for loadable segments using
330 * extract_bin_info_events.
332 dl_iterate_phdr(extract_bin_info_events
, &data
);
338 * Generate a statedump of a given traced application. A statedump is
339 * delimited by start and end events. For a given (process, session)
340 * pair, begin/end events are serialized and will match. However, in a
341 * session, statedumps from different processes may be
342 * interleaved. The vpid context should be used to identify which
343 * events belong to which process.
345 * Grab the ust_lock outside of the RCU read-side lock because we
346 * perform synchronize_rcu with the ust_lock held, which can trigger
347 * deadlocks otherwise.
349 int do_lttng_ust_statedump(void *owner
)
352 trace_statedump_start(owner
);
355 do_baddr_statedump(owner
);
358 trace_statedump_end(owner
);
364 void lttng_ust_statedump_init(void)
366 __tracepoints__init();
367 __tracepoints__ptrs_init();
368 __lttng_events_init__lttng_ust_statedump();
371 void lttng_ust_statedump_destroy(void)
373 __lttng_events_exit__lttng_ust_statedump();
374 __tracepoints__ptrs_destroy();
375 __tracepoints__destroy();
This page took 0.036585 seconds and 4 git commands to generate.