2 * Copyright (C) 2013 Paul Woegerer <paul_woegerer@mentor.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * 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-baddr.h"
38 #define TRACEPOINT_DEFINE
39 #define TRACEPOINT_CREATE_PROBES
40 #define TP_SESSION_CHECK
41 #include "ust_baddr_statedump.h"
45 void *exec_baddr
; /* executable base address */
49 * Trace baddr into all sessions for which statedump is pending owned by
53 int trace_baddr(void *base_addr_ptr
,
54 const char *resolved_path
,
58 struct cds_list_head
*sessionsp
;
59 struct lttng_session
*session
;
62 if (vdso
|| stat(resolved_path
, &sostat
)) {
67 * UST lock nests within dynamic loader lock.
71 * Stop iteration on headers if need to exit.
77 sessionsp
= _lttng_get_sessions();
78 cds_list_for_each_entry(session
, sessionsp
, node
) {
79 if (session
->owner
!= owner
)
81 if (!session
->statedump_pending
)
83 tracepoint(ust_baddr_statedump
, soinfo
,
84 session
, base_addr_ptr
,
85 resolved_path
, sostat
.st_size
,
93 int extract_soinfo_events(struct dl_phdr_info
*info
, size_t size
, void *_data
)
96 struct extract_data
*data
= _data
;
97 void *owner
= data
->owner
;
99 for (j
= 0; j
< info
->dlpi_phnum
; j
++) {
100 char resolved_path
[PATH_MAX
];
104 if (info
->dlpi_phdr
[j
].p_type
!= PT_LOAD
)
107 /* Calculate virtual memory address of the loadable segment */
108 base_addr_ptr
= (void *) info
->dlpi_addr
109 + info
->dlpi_phdr
[j
].p_vaddr
;
111 if ((info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == 0)
112 && !data
->exec_baddr
) {
114 * Only the first phdr encountered is considered
115 * as the program executable. The following
116 * could be e.g. vdso. Don't mistakenly dump
117 * them as being the program executable.
119 data
->exec_baddr
= base_addr_ptr
;
121 * Deal with program executable outside of phdr
126 if (info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == 0) {
128 snprintf(resolved_path
, PATH_MAX
- 1, "[vdso]");
132 * For regular dl_phdr_info entries we have to check if
133 * the path to the shared object really exists.
135 if (!realpath(info
->dlpi_name
, resolved_path
)) {
136 /* Path unknown, put the 'path' into brackets */
137 snprintf(resolved_path
, PATH_MAX
- 1, "[%s]",
142 if (trace_baddr(base_addr_ptr
, resolved_path
, vdso
, owner
)) {
146 * We are only interested in the base address (lowest virtual
147 * address associated with the memory image), skip the rest
155 void dump_exec_baddr(struct extract_data
*data
)
157 void *owner
= data
->owner
;
158 Dl_info dl_info
= { 0 };
160 char resolved_path
[PATH_MAX
];
162 base_addr_ptr
= data
->exec_baddr
;
166 * We have to use Dl_info to determine the executable full path.
168 if (!dladdr(base_addr_ptr
, &dl_info
))
170 if (!realpath(dl_info
.dli_fname
, resolved_path
))
172 trace_baddr(base_addr_ptr
, resolved_path
, 0, owner
);
175 int lttng_ust_baddr_statedump(void *owner
)
177 struct extract_data data
;
179 if (getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
183 data
.exec_baddr
= NULL
;
185 * Iterate through the list of currently loaded shared objects and
186 * generate events for loadable segments using
187 * extract_soinfo_events.
189 dl_iterate_phdr(extract_soinfo_events
, &data
);
191 * We cannot call dladdr() from within phdr iteration, without
192 * causing constructor vs dynamic loader vs multithread internal
193 * deadlocks, so dump the executable outside of the phdr
196 dump_exec_baddr(&data
);
200 void lttng_ust_baddr_statedump_init(void)
202 __tracepoints__init();
203 __tracepoints__ptrs_init();
204 __lttng_events_init__ust_baddr_statedump();
207 void lttng_ust_baddr_statedump_destroy(void)
209 __lttng_events_exit__ust_baddr_statedump();
210 __tracepoints__ptrs_destroy();
211 __tracepoints__destroy();
This page took 0.043915 seconds and 4 git commands to generate.