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 #include "ust_baddr_statedump.h"
43 void *exec_baddr
; /* executable base address */
47 * Trace baddr into all sessions for which statedump is pending owned by
51 int trace_baddr(void *base_addr_ptr
,
52 const char *resolved_path
,
56 struct cds_list_head
*sessionsp
;
57 struct lttng_session
*session
;
60 if (vdso
|| stat(resolved_path
, &sostat
)) {
65 * UST lock nests within dynamic loader lock.
69 * Stop iteration on headers if need to exit.
75 sessionsp
= _lttng_get_sessions();
76 cds_list_for_each_entry(session
, sessionsp
, node
) {
77 if (session
->owner
!= owner
)
79 if (!session
->statedump_pending
)
81 tracepoint(ust_baddr_statedump
, soinfo
,
82 session
, base_addr_ptr
,
83 resolved_path
, sostat
.st_size
,
91 int extract_soinfo_events(struct dl_phdr_info
*info
, size_t size
, void *_data
)
94 struct extract_data
*data
= _data
;
95 void *owner
= data
->owner
;
97 for (j
= 0; j
< info
->dlpi_phnum
; j
++) {
98 char resolved_path
[PATH_MAX
];
102 if (info
->dlpi_phdr
[j
].p_type
!= PT_LOAD
)
105 /* Calculate virtual memory address of the loadable segment */
106 base_addr_ptr
= (void *) info
->dlpi_addr
107 + info
->dlpi_phdr
[j
].p_vaddr
;
109 if ((info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == 0)
110 && !data
->exec_baddr
) {
112 * Only the first phdr encountered is considered
113 * as the program executable. The following
114 * could be e.g. vdso. Don't mistakenly dump
115 * them as being the program executable.
117 data
->exec_baddr
= base_addr_ptr
;
119 * Deal with program executable outside of phdr
124 if (info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == 0) {
126 snprintf(resolved_path
, PATH_MAX
- 1, "[vdso]");
130 * For regular dl_phdr_info entries we have to check if
131 * the path to the shared object really exists.
133 if (!realpath(info
->dlpi_name
, resolved_path
)) {
134 /* Path unknown, put the 'path' into brackets */
135 snprintf(resolved_path
, PATH_MAX
- 1, "[%s]",
140 if (trace_baddr(base_addr_ptr
, resolved_path
, vdso
, owner
)) {
144 * We are only interested in the base address (lowest virtual
145 * address associated with the memory image), skip the rest
153 void dump_exec_baddr(struct extract_data
*data
)
155 void *owner
= data
->owner
;
156 Dl_info dl_info
= { 0 };
158 char resolved_path
[PATH_MAX
];
160 base_addr_ptr
= data
->exec_baddr
;
164 * We have to use Dl_info to determine the executable full path.
166 if (!dladdr(base_addr_ptr
, &dl_info
))
168 if (!realpath(dl_info
.dli_fname
, resolved_path
))
170 trace_baddr(base_addr_ptr
, resolved_path
, 0, owner
);
173 int lttng_ust_baddr_statedump(void *owner
)
175 struct extract_data data
;
177 if (getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
181 data
.exec_baddr
= NULL
;
183 * Iterate through the list of currently loaded shared objects and
184 * generate events for loadable segments using
185 * extract_soinfo_events.
187 dl_iterate_phdr(extract_soinfo_events
, &data
);
189 * We cannot call dladdr() from within phdr iteration, without
190 * causing constructor vs dynamic loader vs multithread internal
191 * deadlocks, so dump the executable outside of the phdr
194 dump_exec_baddr(&data
);
198 void lttng_ust_baddr_statedump_init(void)
200 __tracepoints__init();
201 __tracepoints__ptrs_init();
204 void lttng_ust_baddr_statedump_destroy(void)
206 __tracepoints__ptrs_destroy();
207 __tracepoints__destroy();
This page took 0.036388 seconds and 5 git commands to generate.