Fix: baddr_statedump tracepoint registration
[lttng-ust.git] / liblttng-ust / lttng-ust-baddr.c
CommitLineData
b13d93c2
PW
1/*
2 * Copyright (C) 2013 Paul Woegerer <paul_woegerer@mentor.com>
3 *
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.
8 *
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.
13 *
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
17 */
18
5aed31fc 19#define _LGPL_SOURCE
b13d93c2
PW
20#define _GNU_SOURCE
21#include <dlfcn.h>
22#include <link.h>
23
24#include <sys/types.h>
25#include <sys/stat.h>
b13d93c2
PW
26#include <unistd.h>
27#include <limits.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <stdint.h>
31#include <stddef.h>
32#include <stdio.h>
b13d93c2 33
9e166115
MD
34#include <usterr-signal-safe.h>
35#include "lttng-tracer-core.h"
13436238
PW
36#include "lttng-ust-baddr.h"
37
b13d93c2 38#define TRACEPOINT_DEFINE
f0cc794d
MD
39#define TRACEPOINT_CREATE_PROBES
40#define TP_SESSION_CHECK
95c25348 41#include "ust_baddr_statedump.h"
b13d93c2 42
5aed31fc
MD
43struct extract_data {
44 void *owner;
45 void *exec_baddr; /* executable base address */
46};
47
48/*
49 * Trace baddr into all sessions for which statedump is pending owned by
50 * the caller thread.
51 */
37dddb65 52static
5aed31fc
MD
53int trace_baddr(void *base_addr_ptr,
54 const char *resolved_path,
55 int vdso,
56 void *owner)
95c25348 57{
37dddb65 58 struct cds_list_head *sessionsp;
5aed31fc
MD
59 struct lttng_session *session;
60 struct stat sostat;
61
62 if (vdso || stat(resolved_path, &sostat)) {
63 sostat.st_size = 0;
64 sostat.st_mtime = -1;
65 }
66 /*
67 * UST lock nests within dynamic loader lock.
68 */
69 if (ust_lock()) {
70 /*
71 * Stop iteration on headers if need to exit.
72 */
73 ust_unlock();
74 return 1;
75 }
76
77 sessionsp = _lttng_get_sessions();
78 cds_list_for_each_entry(session, sessionsp, node) {
79 if (session->owner != owner)
80 continue;
81 if (!session->statedump_pending)
82 continue;
83 tracepoint(ust_baddr_statedump, soinfo,
84 session, base_addr_ptr,
85 resolved_path, sostat.st_size,
86 sostat.st_mtime);
87 }
88 ust_unlock();
89 return 0;
90}
91
92static
93int extract_soinfo_events(struct dl_phdr_info *info, size_t size, void *_data)
94{
95 int j;
96 struct extract_data *data = _data;
97 void *owner = data->owner;
37dddb65 98
95c25348
PW
99 for (j = 0; j < info->dlpi_phnum; j++) {
100 char resolved_path[PATH_MAX];
95c25348 101 void *base_addr_ptr;
5aed31fc 102 int vdso = 0;
95c25348
PW
103
104 if (info->dlpi_phdr[j].p_type != PT_LOAD)
105 continue;
106
107 /* Calculate virtual memory address of the loadable segment */
108 base_addr_ptr = (void *) info->dlpi_addr
109 + info->dlpi_phdr[j].p_vaddr;
110
95c25348 111 if ((info->dlpi_name == NULL || info->dlpi_name[0] == 0)
5aed31fc
MD
112 && !data->exec_baddr) {
113 /*
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.
118 */
119 data->exec_baddr = base_addr_ptr;
95c25348 120 /*
5aed31fc
MD
121 * Deal with program executable outside of phdr
122 * iteration.
95c25348 123 */
5aed31fc
MD
124 break;
125 }
126 if (info->dlpi_name == NULL || info->dlpi_name[0] == 0) {
127 /* Found vDSO. */
128 snprintf(resolved_path, PATH_MAX - 1, "[vdso]");
129 vdso = 1;
95c25348
PW
130 } else {
131 /*
132 * For regular dl_phdr_info entries we have to check if
5aed31fc 133 * the path to the shared object really exists.
95c25348
PW
134 */
135 if (!realpath(info->dlpi_name, resolved_path)) {
5aed31fc 136 /* Path unknown, put the 'path' into brackets */
95c25348 137 snprintf(resolved_path, PATH_MAX - 1, "[%s]",
5aed31fc
MD
138 info->dlpi_name);
139 vdso = 1;
95c25348
PW
140 }
141 }
5aed31fc 142 if (trace_baddr(base_addr_ptr, resolved_path, vdso, owner)) {
3327ac33
MD
143 return 1;
144 }
95c25348
PW
145 /*
146 * We are only interested in the base address (lowest virtual
147 * address associated with the memory image), skip the rest
148 */
149 break;
150 }
151 return 0;
152}
153
5aed31fc
MD
154static
155void dump_exec_baddr(struct extract_data *data)
156{
157 void *owner = data->owner;
158 Dl_info dl_info = { 0 };
159 void *base_addr_ptr;
160 char resolved_path[PATH_MAX];
161
162 base_addr_ptr = data->exec_baddr;
163 if (!base_addr_ptr)
164 return;
165 /*
166 * We have to use Dl_info to determine the executable full path.
167 */
168 if (!dladdr(base_addr_ptr, &dl_info))
169 return;
170 if (!realpath(dl_info.dli_fname, resolved_path))
171 return;
172 trace_baddr(base_addr_ptr, resolved_path, 0, owner);
173}
174
37dddb65 175int lttng_ust_baddr_statedump(void *owner)
95c25348 176{
5aed31fc
MD
177 struct extract_data data;
178
ca7643d6
PW
179 if (getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
180 return 0;
5aed31fc
MD
181
182 data.owner = owner;
183 data.exec_baddr = NULL;
95c25348
PW
184 /*
185 * Iterate through the list of currently loaded shared objects and
37dddb65
MD
186 * generate events for loadable segments using
187 * extract_soinfo_events.
95c25348 188 */
5aed31fc
MD
189 dl_iterate_phdr(extract_soinfo_events, &data);
190 /*
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
194 * iteration.
195 */
196 dump_exec_baddr(&data);
95c25348
PW
197 return 0;
198}
bd703713
PW
199
200void lttng_ust_baddr_statedump_init(void)
201{
202 __tracepoints__init();
203 __tracepoints__ptrs_init();
f0cc794d 204 __lttng_events_init__ust_baddr_statedump();
bd703713
PW
205}
206
207void lttng_ust_baddr_statedump_destroy(void)
208{
f0cc794d 209 __lttng_events_exit__ust_baddr_statedump();
bd703713
PW
210 __tracepoints__ptrs_destroy();
211 __tracepoints__destroy();
212}
This page took 0.035373 seconds and 4 git commands to generate.