Skip to content

Commit 2c369d9

Browse files
captain5050namhyung
authored andcommitted
perf symbol: Add blocking argument to filename__read_build_id
When synthesizing build-ids, for build ID mmap2 events, they will be added for data mmaps if -d/--data is specified. The files opened for their build IDs may block on the open causing perf to hang during synthesis. There is some robustness in existing calls to filename__read_build_id by checking the file path is to a regular file, which unfortunately fails for symlinks. Rather than adding more is_regular_file calls, switch filename__read_build_id to take a "block" argument and specify O_NONBLOCK when this is false. The existing is_regular_file checking callers and the event synthesis callers are made to pass false and thereby avoiding the hang. Fixes: 53b00ff ("perf record: Make --buildid-mmap the default") Signed-off-by: Ian Rogers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Namhyung Kim <[email protected]>
1 parent ba0b708 commit 2c369d9

File tree

12 files changed

+32
-27
lines changed

12 files changed

+32
-27
lines changed

tools/perf/bench/inject-buildid.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static int add_dso(const char *fpath, const struct stat *sb __maybe_unused,
8585
if (typeflag == FTW_D || typeflag == FTW_SL)
8686
return 0;
8787

88-
if (filename__read_build_id(fpath, &bid) < 0)
88+
if (filename__read_build_id(fpath, &bid, /*block=*/true) < 0)
8989
return 0;
9090

9191
dso->name = realpath(fpath, NULL);

tools/perf/builtin-buildid-cache.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi)
180180
struct nscookie nsc;
181181

182182
nsinfo__mountns_enter(nsi, &nsc);
183-
err = filename__read_build_id(filename, &bid);
183+
err = filename__read_build_id(filename, &bid, /*block=*/true);
184184
nsinfo__mountns_exit(&nsc);
185185
if (err < 0) {
186186
pr_debug("Couldn't read a build-id in %s\n", filename);
@@ -204,7 +204,7 @@ static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi)
204204
int err;
205205

206206
nsinfo__mountns_enter(nsi, &nsc);
207-
err = filename__read_build_id(filename, &bid);
207+
err = filename__read_build_id(filename, &bid, /*block=*/true);
208208
nsinfo__mountns_exit(&nsc);
209209
if (err < 0) {
210210
pr_debug("Couldn't read a build-id in %s\n", filename);
@@ -280,7 +280,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
280280
if (!dso__build_id_filename(dso, filename, sizeof(filename), false))
281281
return true;
282282

283-
if (filename__read_build_id(filename, &bid) == -1) {
283+
if (filename__read_build_id(filename, &bid, /*block=*/true) == -1) {
284284
if (errno == ENOENT)
285285
return false;
286286

@@ -309,7 +309,7 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi)
309309
int err;
310310

311311
nsinfo__mountns_enter(nsi, &nsc);
312-
err = filename__read_build_id(filename, &bid);
312+
err = filename__read_build_id(filename, &bid, /*block=*/true);
313313
nsinfo__mountns_exit(&nsc);
314314
if (err < 0) {
315315
pr_debug("Couldn't read a build-id in %s\n", filename);

tools/perf/builtin-inject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,12 +680,12 @@ static int dso__read_build_id(struct dso *dso)
680680

681681
mutex_lock(dso__lock(dso));
682682
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
683-
if (filename__read_build_id(dso__long_name(dso), &bid) > 0)
683+
if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0)
684684
dso__set_build_id(dso, &bid);
685685
else if (dso__nsinfo(dso)) {
686686
char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso));
687687

688-
if (new_name && filename__read_build_id(new_name, &bid) > 0)
688+
if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0)
689689
dso__set_build_id(dso, &bid);
690690
free(new_name);
691691
}

tools/perf/tests/sdt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static int build_id_cache__add_file(const char *filename)
3131
struct build_id bid = { .size = 0, };
3232
int err;
3333

34-
err = filename__read_build_id(filename, &bid);
34+
err = filename__read_build_id(filename, &bid, /*block=*/true);
3535
if (err < 0) {
3636
pr_debug("Failed to read build id of %s\n", filename);
3737
return err;

tools/perf/util/build-id.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ int filename__snprintf_build_id(const char *pathname, char *sbuild_id, size_t sb
115115
struct build_id bid = { .size = 0, };
116116
int ret;
117117

118-
ret = filename__read_build_id(pathname, &bid);
118+
ret = filename__read_build_id(pathname, &bid, /*block=*/true);
119119
if (ret < 0)
120120
return ret;
121121

@@ -841,7 +841,7 @@ static int filename__read_build_id_ns(const char *filename,
841841
int ret;
842842

843843
nsinfo__mountns_enter(nsi, &nsc);
844-
ret = filename__read_build_id(filename, bid);
844+
ret = filename__read_build_id(filename, bid, /*block=*/true);
845845
nsinfo__mountns_exit(&nsc);
846846

847847
return ret;

tools/perf/util/debuginfo.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,12 @@ struct debuginfo *debuginfo__new(const char *path)
110110
if (!dso)
111111
goto out;
112112

113-
/* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO */
114-
if (is_regular_file(path) && filename__read_build_id(path, &bid) > 0)
113+
/*
114+
* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO. Don't block
115+
* incase the path isn't for a regular file.
116+
*/
117+
assert(!dso__has_build_id(dso));
118+
if (filename__read_build_id(path, &bid, /*block=*/false) > 0)
115119
dso__set_build_id(dso, &bid);
116120

117121
for (type = distro_dwarf_types;

tools/perf/util/dsos.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data)
8181
return 0;
8282
}
8383
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
84-
if (filename__read_build_id(dso__long_name(dso), &bid) > 0) {
84+
if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0) {
8585
dso__set_build_id(dso, &bid);
8686
args->have_build_id = true;
8787
} else if (errno == ENOENT && dso__nsinfo(dso)) {
8888
char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso));
8989

90-
if (new_name && filename__read_build_id(new_name, &bid) > 0) {
90+
if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0) {
9191
dso__set_build_id(dso, &bid);
9292
args->have_build_id = true;
9393
}

tools/perf/util/symbol-elf.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ static int read_build_id(const char *filename, struct build_id *bid)
902902

903903
#else // HAVE_LIBBFD_BUILDID_SUPPORT
904904

905-
static int read_build_id(const char *filename, struct build_id *bid)
905+
static int read_build_id(const char *filename, struct build_id *bid, bool block)
906906
{
907907
size_t size = sizeof(bid->data);
908908
int fd, err = -1;
@@ -911,7 +911,7 @@ static int read_build_id(const char *filename, struct build_id *bid)
911911
if (size < BUILD_ID_SIZE)
912912
goto out;
913913

914-
fd = open(filename, O_RDONLY);
914+
fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK));
915915
if (fd < 0)
916916
goto out;
917917

@@ -934,7 +934,7 @@ static int read_build_id(const char *filename, struct build_id *bid)
934934

935935
#endif // HAVE_LIBBFD_BUILDID_SUPPORT
936936

937-
int filename__read_build_id(const char *filename, struct build_id *bid)
937+
int filename__read_build_id(const char *filename, struct build_id *bid, bool block)
938938
{
939939
struct kmod_path m = { .name = NULL, };
940940
char path[PATH_MAX];
@@ -958,9 +958,10 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
958958
}
959959
close(fd);
960960
filename = path;
961+
block = true;
961962
}
962963

963-
err = read_build_id(filename, bid);
964+
err = read_build_id(filename, bid, block);
964965

965966
if (m.comp)
966967
unlink(filename);

tools/perf/util/symbol-minimal.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ int filename__read_debuglink(const char *filename __maybe_unused,
8585
/*
8686
* Just try PT_NOTE header otherwise fails
8787
*/
88-
int filename__read_build_id(const char *filename, struct build_id *bid)
88+
int filename__read_build_id(const char *filename, struct build_id *bid, bool block)
8989
{
9090
int fd, ret = -1;
9191
bool need_swap = false, elf32;
@@ -102,7 +102,7 @@ int filename__read_build_id(const char *filename, struct build_id *bid)
102102
void *phdr, *buf = NULL;
103103
ssize_t phdr_size, ehdr_size, buf_size = 0;
104104

105-
fd = open(filename, O_RDONLY);
105+
fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK));
106106
if (fd < 0)
107107
return -1;
108108

@@ -323,7 +323,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
323323
if (ret >= 0)
324324
RC_CHK_ACCESS(dso)->is_64_bit = ret;
325325

326-
if (filename__read_build_id(ss->name, &bid) > 0)
326+
if (filename__read_build_id(ss->name, &bid, /*block=*/true) > 0)
327327
dso__set_build_id(dso, &bid);
328328
return 0;
329329
}

tools/perf/util/symbol.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,14 +1869,14 @@ int dso__load(struct dso *dso, struct map *map)
18691869

18701870
/*
18711871
* Read the build id if possible. This is required for
1872-
* DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work
1872+
* DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work. Don't block in case path
1873+
* isn't for a regular file.
18731874
*/
1874-
if (!dso__has_build_id(dso) &&
1875-
is_regular_file(dso__long_name(dso))) {
1875+
if (!dso__has_build_id(dso)) {
18761876
struct build_id bid = { .size = 0, };
18771877

18781878
__symbol__join_symfs(name, PATH_MAX, dso__long_name(dso));
1879-
if (filename__read_build_id(name, &bid) > 0)
1879+
if (filename__read_build_id(name, &bid, /*block=*/false) > 0)
18801880
dso__set_build_id(dso, &bid);
18811881
}
18821882

0 commit comments

Comments
 (0)