This is an archive of the discontinued LLVM Phabricator instance.

[clang] Implement setting crash_diagnostics_dir through env variable
ClosedPublic

Authored by mizvekov on Aug 31 2022, 7:30 PM.

Details

Summary

This implements setting the equivalent of -fcrash-diagnostics-dir
through the environment variable CLANG_CRASH_DIAGNOSTICS_DIR.
If present, the flag still takes precedence.

This helps integration with test frameworks and pipelines.

With this feature, we change the libcxx bootstrapping build
pipeline to produce clang crash reproducers as artifacts.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Diff Detail

Event Timeline

mizvekov created this revision.Aug 31 2022, 7:30 PM
Herald added projects: Restricted Project, Restricted Project, Restricted Project. · View Herald TranscriptAug 31 2022, 7:30 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
mizvekov requested review of this revision.Aug 31 2022, 7:30 PM
mizvekov planned changes to this revision.Aug 31 2022, 7:45 PM
mizvekov updated this revision to Diff 457159.
mizvekov requested review of this revision.Sep 1 2022, 1:27 AM
mizvekov added reviewers: aaron.ballman, Restricted Project, ldionne, Mordante.
mizvekov retitled this revision from WIP: [clang] Implement setting crash_diagnostics_dir through env variable to [clang] Implement setting crash_diagnostics_dir through env variable.

I don't mind the idea, but wonder if some level of RFC/project-wide decision should be made here? WDYT @aaron.ballman ?

clang/lib/Driver/Driver.cpp
5415–5416

StringRef would be better here instead, which should mean you don't have to create the SmallString below, and could just work in Twines for everything.

mizvekov added inline comments.Sep 1 2022, 7:59 AM
clang/lib/Driver/Driver.cpp
5415–5416

It seems that llvm::sys::path::append takes twine as inputs, but it only outputs to a SmallVectorImpl.
Unless there is something else I could use?

erichkeane added inline comments.Sep 1 2022, 8:05 AM
clang/lib/Driver/Driver.cpp
5415–5416

Ah, yikes, I missed that was what was happening :/ THAT is still necessary. A Twine can be created from a stringref (and I'd still prefer one anyway), but you DO still have to make that SmallString unfortunately.

mizvekov added inline comments.Sep 1 2022, 8:20 AM
clang/lib/Driver/Driver.cpp
5415–5416

The Twine also can't take a nullptr (such as the case no flag passed and no env variable), so we would have to use something like std::optional<Twine>, and make the needed conversions here.

And the Twine to SmallString copy looks unergonomic as well.

So it seems we would need to make some little changes out of scope of this MR to get that to look nicely.

erichkeane added inline comments.Sep 1 2022, 8:23 AM
clang/lib/Driver/Driver.cpp
5415–5416

I guess i don't get the concern here? I'm suggesting just changing this from const char* to StringRef (which should work). Everything else below should 'just work' AFAIK.

mizvekov added inline comments.Sep 1 2022, 8:30 AM
clang/lib/Driver/Driver.cpp
5415–5416

Oh okay I misunderstood you! Thought you meant to make CrashDirectory a Twine.

Yeah with StringRef we only need to change the test:

if (CrashDirectory) {

--->

if (CrashDirectory.data() != nullptr) {

Everything else stays the same. It doesn't look cleaner, but would address your concerns about avoiding storing a char pointer variable?

mizvekov added inline comments.Sep 1 2022, 8:35 AM
clang/lib/Driver/Driver.cpp
5415–5416

We could add a bool conversion to StringRef, but perhaps folks could find the meaning confusing between empty and null pointer?

erichkeane accepted this revision.Sep 1 2022, 8:50 AM
erichkeane added inline comments.
clang/lib/Driver/Driver.cpp
5415–5416

Hrm... do we actually have meaning here to 'empty' for these files? I guess we allow it already.... hrm... Ok, disregard the suggestion, and thanks for thinking this through with me.

mizvekov added inline comments.Sep 1 2022, 8:54 AM
clang/lib/Driver/Driver.cpp
5415–5416

Thanks for the review and suggestions!

Yeah right, I didn't want to change the behavior vs empty here, but I think if we did some change, it would make more sense to create some specific error for it, instead of treating empty the same as no argument passed.

I don't mind the idea, but wonder if some level of RFC/project-wide decision should be made here? WDYT @aaron.ballman ?

We use environment variables in several other places within the driver, but I am a bit skittish about adding new ones to correspond to feature flags as that seems to be somewhat novel. I think it'd be a good idea to get more buy-in with an RFC on Discourse for more broad awareness.

If we go this route, we definitely need user-facing documentation that explains what's going on. I don't think we have anything corresponding to https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html, but having such a page for Clang would be a good idea (even if the page is incomplete).

clang/docs/ReleaseNotes.rst
136–144
clang/lib/Driver/Driver.cpp
5417

This should use llvm::sys::Process::GetEnv() so it properly handles text encodings. CC @tahonermann @cor3ntin for text encoding awareness.

aaron.ballman requested changes to this revision.Sep 1 2022, 8:55 AM
This revision now requires changes to proceed.Sep 1 2022, 8:55 AM

We use environment variables in several other places within the driver, but I am a bit skittish about adding new ones to correspond to feature flags as that seems to be somewhat novel. I think it'd be a good idea to get more buy-in with an RFC on Discourse for more broad awareness.

If we go this route, we definitely need user-facing documentation that explains what's going on. I don't think we have anything corresponding to https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html, but having such a page for Clang would be a good idea (even if the page is incomplete).

Okay, fair!

We will have an RFC about this.

clang/lib/Driver/Driver.cpp
5417

Okay, makes sense. But be aware that we have multiple places in the llvm project where we are using std::getenv to retrieve a filesystem path variable. There is another one within clang itself as well (CLANG_MODULE_CACHE_PATH, which is where I took inspiration from).

aaron.ballman added inline comments.Sep 1 2022, 9:14 AM
clang/lib/Driver/Driver.cpp
5417

Yeah, I noticed the same thing when I was looking around. Every one of those is a bug! It likely works fine for Linux where UTF-8 is common, but they will all fail on Windows where UTF-16 is used for the OS but ::getenv() uses the C locale. Any sort of non-ASCII characters in the file path are likely not going to do the right thing in that case.

Thanks for working on this! It's really great to get the crash report as an artifact.

libcxx/test/libcxx/crash.sh.cpp
15 ↗(On Diff #457159)

The libc++ build seems to be green. I assume it was intended to be red so we can validate the artifact is available in the CI.

libcxx/utils/ci/buildkite-pipeline.yml
377

Are relative directories allowed?

mizvekov added inline comments.Sep 1 2022, 10:03 AM
libcxx/test/libcxx/crash.sh.cpp
15 ↗(On Diff #457159)

If I made it red, this test would fail in one the jobs from the early group, and we would never run the bootstraping job :(

But making it green does not stop it from exporting the artifact, you can go in there in the build results and have a look!

libcxx/utils/ci/buildkite-pipeline.yml
377

Yes, it already worked with the flag.

You can check that it's working, even though the bootstrapping pipeline is green, it still exports the artifacts.

Mordante accepted this revision.Sep 1 2022, 10:12 AM

Ideally it would be documented these artifacts are now available. However there's no good place in libc++ to document that. I'm working on such a document so I will take care of documenting these artifacts.

LGTM from libc++'s PoV.

libcxx/utils/ci/buildkite-pipeline.yml
377

Thanks I see.

Just a hint you can move this job earlier in this file for testing purposes and/or remove jobs you don't want to test. I use this every now and then when I have issues with a specific CI.

mizvekov requested review of this revision.Sep 1 2022, 10:54 AM
mizvekov updated this revision to Diff 457327.
mizvekov marked 10 inline comments as done.
mizvekov updated this revision to Diff 457462.Sep 1 2022, 5:42 PM

If we go this route, we definitely need user-facing documentation that explains what's going on. I don't think we have anything corresponding to https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html, but having such a page for Clang would be a good idea (even if the page is incomplete).

I took an attempt at this on the latest diff.
I am suggesting we put the variables close to command line flags, in the same document, as I think it makes sense to have these options that interact with each other close together.

mizvekov updated this revision to Diff 457468.Sep 1 2022, 5:49 PM
mizvekov updated this revision to Diff 457685.Sep 2 2022, 1:12 PM
mizvekov updated this revision to Diff 457818.Sep 3 2022, 2:23 PM

@aaron.ballman I think all of your concerns are addressed now.

aaron.ballman accepted this revision.Sep 6 2022, 10:02 AM

LGTM, thank you!

This revision is now accepted and ready to land.Sep 6 2022, 10:02 AM