This is an archive of the discontinued LLVM Phabricator instance.

[llvm-cov] Use -path-equivalence to support relative path.
AbandonedPublic

Authored by zequanwu on Mar 31 2021, 5:20 PM.

Details

Reviewers
vsk
tunz
phosek
rnk
Summary

Right now, llvm-cov doesn't support relative path and -path-equivalence is
only used for search source files. If the file path embedded in the binary is a
relative path and we use llvm-cov show -path-equivalence=from,to, the location
of generated coverage report files will be relative to current working direcotry.
If ../../test.cpp is embedded, coverage report files will be generated outside
the directory specified by -o.

This patch let llvm-cov construct output directory with the to part of
-path-equivalence=from,to as prefix. For example, if we have /tmp/src/a.cpp
embedded in the binary, llvm-cov show -path-equivalence=/tmp/src/,/cov ...
will generate output direcotry like this: coverage/cov/a.cpp.

But if -path-equivalence is not given and ../../a.cpp is embedded in the
binary, llvm-cov may still generate report files outside report directory when
source files are found. Maybe we should give a warning/error to let user use
-path-equivalence when relative path is present?

Diff Detail

Event Timeline

zequanwu requested review of this revision.Mar 31 2021, 5:20 PM
zequanwu created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptMar 31 2021, 5:20 PM
vsk added a comment.Apr 1 2021, 10:18 AM

This patch let llvm-cov construct output directory with the to part of -path-equivalence=from,to as prefix

I think this makes sense.

For example, if we have /tmp/src/a.cpp embedded in the binary, llvm-cov show -path-equivalence=/tmp/src/,/cov ... will generate output direcotry like this: coverage/cov/a.cpp.

What happens if the binary has a relative path '../../a.cpp' embedded and the user passes -path-equivalence=/tmp/src/,/cov to llvm-cov? Is a.cpp written to <coverage-dir>/cov/../../a.cpp?

But if -path-equivalence is not given and ../../a.cpp is embedded in the binary, llvm-cov may still generate report files outside report directory when source files are found. Maybe we should give a warning/error to let user use -path-equivalence when relative path is present?

Until recently, relative paths weren't allowed in the coverage mapping. I don't believe it was ever the intention to allow llvm-cov to write files outside of the coverage dir. That sounds dangerous to me, fwiw I think that should be a hard error and the tool should refuse to do it.

We ran into this issue as well where the compilation directory is set to . and path starts with ../.. (we use similar setup to Chromium) so llvm-cov tries to write files outside of the coverage directory. The way to address it I was considering would be to provide a way to override compilation directory, for example llvm-cov show --compilation-dir=/path/to/source/out/default ... so if the path stored in profile is ../../a/b.c, then it'd become /path/to/source/a/b.c. This would address the issue for us but I'm not sure if it's the best possible solution. What do you think?

vsk added a comment.Apr 1 2021, 11:11 AM

I think then you would somehow need multiple -compilation-dir options if e.g. you have paths with different levels of ../ nesting, e.g. ../../foo.c and ../../../../bar.c. That sounds like it could become hard to manage.

In RawCoverageFilenamesReader::readUncompressed, we do:

SmallString<256> P(CWD);
llvm::sys::path::append(P, Filename);

Can this just be turned into an absolute path?

In D99695#2664701, @vsk wrote:

I think then you would somehow need multiple -compilation-dir options if e.g. you have paths with different levels of ../ nesting, e.g. ../../foo.c and ../../../../bar.c. That sounds like it could become hard to manage.

In RawCoverageFilenamesReader::readUncompressed, we do:

SmallString<256> P(CWD);
llvm::sys::path::append(P, Filename);

Can this just be turned into an absolute path?

The flag would override the compilation dir that's stored inside the profile (the 0th path entry) so there should be just one. In that code snippet, it means overriding CWD.

In D99695#2664545, @vsk wrote:

For example, if we have /tmp/src/a.cpp embedded in the binary, llvm-cov show -path-equivalence=/tmp/src/,/cov ... will generate output direcotry like this: coverage/cov/a.cpp.

What happens if the binary has a relative path '../../a.cpp' embedded and the user passes -path-equivalence=/tmp/src/,/cov to llvm-cov? Is a.cpp written to <coverage-dir>/cov/../../a.cpp?

In this case, ../../ is not matching /tmp/src. So, it's like -path-equivalence is not given. llvm-cov will lookup a.cpp in ../../ relative to current working directory.

But if -path-equivalence is not given and ../../a.cpp is embedded in the binary, llvm-cov may still generate report files outside report directory when source files are found. Maybe we should give a warning/error to let user use -path-equivalence when relative path is present?

Until recently, relative paths weren't allowed in the coverage mapping. I don't believe it was ever the intention to allow llvm-cov to write files outside of the coverage dir. That sounds dangerous to me, fwiw I think that should be a hard error and the tool should refuse to do it.

I agree.

In D99695#2664701, @vsk wrote:

I think then you would somehow need multiple -compilation-dir options if e.g. you have paths with different levels of ../ nesting, e.g. ../../foo.c and ../../../../bar.c. That sounds like it could become hard to manage.

This case is hard to manage. This patch would only handle case that all paths have same level of ../.

In D99695#2664701, @vsk wrote:

I think then you would somehow need multiple -compilation-dir options if e.g. you have paths with different levels of ../ nesting, e.g. ../../foo.c and ../../../../bar.c. That sounds like it could become hard to manage.

In RawCoverageFilenamesReader::readUncompressed, we do:

SmallString<256> P(CWD);
llvm::sys::path::append(P, Filename);

Can this just be turned into an absolute path?

The flag would override the compilation dir that's stored inside the profile (the 0th path entry) so there should be just one. In that code snippet, it means overriding CWD.

That makes sense.
Do we need a new flag or just use -path-equivalence like this patch?

phosek added a comment.Apr 2 2021, 5:39 PM
In D99695#2664701, @vsk wrote:

I think then you would somehow need multiple -compilation-dir options if e.g. you have paths with different levels of ../ nesting, e.g. ../../foo.c and ../../../../bar.c. That sounds like it could become hard to manage.

In RawCoverageFilenamesReader::readUncompressed, we do:

SmallString<256> P(CWD);
llvm::sys::path::append(P, Filename);

Can this just be turned into an absolute path?

The flag would override the compilation dir that's stored inside the profile (the 0th path entry) so there should be just one. In that code snippet, it means overriding CWD.

That makes sense.
Do we need a new flag or just use -path-equivalence like this patch?

I'm working on a patch that introduces the new flag.

zequanwu abandoned this revision.Jun 11 2021, 1:45 PM