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
24 #include <sys/types.h>
34 #include <usterr-signal-safe.h>
35 #include "lttng-tracer-core.h"
36 #include "lttng-ust-statedump.h"
38 #define TRACEPOINT_DEFINE
39 #define TRACEPOINT_CREATE_PROBES
40 #define TP_SESSION_CHECK
41 #include "lttng-ust-statedump-provider.h"
43 struct dl_iterate_data
{
51 const char *resolved_path
;
57 typedef void (*tracepoint_cb
)(struct lttng_session
*session
, void *priv
);
60 * Trace statedump event into all sessions owned by the caller thread
61 * for which statedump is pending.
64 int trace_statedump_event(tracepoint_cb tp_cb
, void *owner
, void *priv
)
66 struct cds_list_head
*sessionsp
;
67 struct lttng_session
*session
;
70 * UST lock nests within dynamic loader lock.
77 sessionsp
= _lttng_get_sessions();
78 cds_list_for_each_entry(session
, sessionsp
, node
) {
79 if (session
->owner
!= owner
)
81 if (!session
->statedump_pending
)
90 void trace_soinfo_cb(struct lttng_session
*session
, void *priv
)
92 struct soinfo_data
*so_data
= (struct soinfo_data
*) priv
;
94 tracepoint(lttng_ust_statedump
, soinfo
,
95 session
, so_data
->base_addr_ptr
,
96 so_data
->resolved_path
, so_data
->size
,
101 void trace_start_cb(struct lttng_session
*session
, void *priv
)
103 tracepoint(lttng_ust_statedump
, start
, session
);
107 void trace_end_cb(struct lttng_session
*session
, void *priv
)
109 tracepoint(lttng_ust_statedump
, end
, session
);
113 int trace_baddr(struct soinfo_data
*so_data
)
117 if (so_data
->vdso
|| stat(so_data
->resolved_path
, &sostat
)) {
119 sostat
.st_mtime
= -1;
122 so_data
->size
= sostat
.st_size
;
123 so_data
->mtime
= sostat
.st_mtime
;
125 return trace_statedump_event(trace_soinfo_cb
, so_data
->owner
, so_data
);
129 int trace_statedump_start(void *owner
)
131 return trace_statedump_event(trace_start_cb
, owner
, NULL
);
135 int trace_statedump_end(void *owner
)
137 return trace_statedump_event(trace_end_cb
, owner
, NULL
);
141 int extract_soinfo_events(struct dl_phdr_info
*info
, size_t size
, void *_data
)
144 struct dl_iterate_data
*data
= _data
;
146 for (j
= 0; j
< info
->dlpi_phnum
; j
++) {
147 struct soinfo_data so_data
;
148 char resolved_path
[PATH_MAX
];
151 if (info
->dlpi_phdr
[j
].p_type
!= PT_LOAD
)
154 /* Calculate virtual memory address of the loadable segment */
155 base_addr_ptr
= (void *) info
->dlpi_addr
+
156 info
->dlpi_phdr
[j
].p_vaddr
;
158 if ((info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == 0)) {
160 * Only the first phdr without a dlpi_name
161 * encountered is considered as the program
162 * executable. The rest are vdsos.
164 if (!data
->exec_found
) {
166 data
->exec_found
= 1;
169 * Use /proc/self/exe to resolve the
170 * executable's full path.
172 path_len
= readlink("/proc/self/exe",
178 resolved_path
[path_len
] = '\0';
181 snprintf(resolved_path
, PATH_MAX
- 1, "[vdso]");
186 * For regular dl_phdr_info entries check if
187 * the path to the SO really exists. If not,
188 * treat as vdso and use dlpi_name as 'path'.
190 if (!realpath(info
->dlpi_name
, resolved_path
)) {
191 snprintf(resolved_path
, PATH_MAX
- 1, "[%s]",
197 so_data
.owner
= data
->owner
;
198 so_data
.base_addr_ptr
= base_addr_ptr
;
199 so_data
.resolved_path
= resolved_path
;
200 return trace_baddr(&so_data
);
207 * Generate a statedump of base addresses of all shared objects loaded
208 * by the traced application, as well as for the application's
212 int do_baddr_statedump(void *owner
)
214 struct dl_iterate_data data
;
216 if (getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
222 * Iterate through the list of currently loaded shared objects and
223 * generate events for loadable segments using
224 * extract_soinfo_events.
226 dl_iterate_phdr(extract_soinfo_events
, &data
);
232 * Generate a statedump of a given traced application. A statedump is
233 * delimited by start and end events. For a given (process, session)
234 * pair, begin/end events are serialized and will match. However, in a
235 * session, statedumps from different processes may be
236 * interleaved. The vpid context should be used to identify which
237 * events belong to which process.
239 int do_lttng_ust_statedump(void *owner
)
241 trace_statedump_start(owner
);
242 do_baddr_statedump(owner
);
243 trace_statedump_end(owner
);
248 void lttng_ust_statedump_init(void)
250 __tracepoints__init();
251 __tracepoints__ptrs_init();
252 __lttng_events_init__lttng_ust_statedump();
255 void lttng_ust_statedump_destroy(void)
257 __lttng_events_exit__lttng_ust_statedump();
258 __tracepoints__ptrs_destroy();
259 __tracepoints__destroy();
This page took 0.037789 seconds and 5 git commands to generate.